@@ -30,6 +30,12 @@ type seriesStats struct {
30
30
numNonMatching int32
31
31
//tracks the last seen non-NaN time stamp (useful for lag
32
32
lastSeen uint32
33
+ //the expected number of points were received
34
+ correctNumPoints bool
35
+ //the last ts matches `now`
36
+ correctAlignment bool
37
+ //all points are sorted and 1 period apart
38
+ correctSpacing bool
33
39
}
34
40
35
41
type partitionMetrics struct {
@@ -58,25 +64,31 @@ func monitor() {
58
64
}
59
65
60
66
for _ , s := range query .Decoded {
61
- processPartitionSeries (s )
67
+ processPartitionSeries (s , tick )
62
68
}
63
69
}
64
70
}
65
71
66
-
67
- func processPartitionSeries (s graphite.Series ) {
68
- log .Infof ("%d - %d" , s .Datapoints [0 ].Ts , s .Datapoints [len (s .Datapoints )- 1 ].Ts )
72
+ func processPartitionSeries (s graphite.Series , now time.Time ) {
69
73
partition , err := strconv .Atoi (s .Target )
70
74
if err != nil {
71
75
log .Debug ("unable to parse partition" , err )
72
76
invalidError .Inc ()
73
77
return
74
78
}
79
+ if len (s .Datapoints ) < 2 {
80
+ log .Debugf ("partition has invalid number of datapoints: %d" , len (s .Datapoints ))
81
+ invalidError .Inc ()
82
+ return
83
+ }
84
+
75
85
serStats := seriesStats {}
76
86
serStats .lastTs = s .Datapoints [len (s .Datapoints )- 1 ].Ts
87
+ serStats .correctAlignment = int64 (serStats .lastTs ) == now .Unix ()
88
+ serStats .correctNumPoints = len (s .Datapoints ) == int (lookbackPeriod / testMetricsInterval )+ 1
89
+ serStats .correctSpacing = checkSpacing (s .Datapoints )
77
90
78
91
for _ , dp := range s .Datapoints {
79
-
80
92
if math .IsNaN (dp .Val ) {
81
93
serStats .nans += 1
82
94
continue
@@ -96,6 +108,18 @@ func processPartitionSeries(s graphite.Series) {
96
108
metrics .nonMatching .Set (int (serStats .numNonMatching ))
97
109
}
98
110
111
+ func checkSpacing (points []graphite.Point ) bool {
112
+ previous := points [0 ].Ts
113
+ for i := 1 ; i < len (points ); i ++ {
114
+ current := points [i ].Ts
115
+ if current - previous != uint32 (testMetricsInterval .Seconds ()) {
116
+ return false
117
+ }
118
+ previous = current
119
+ }
120
+ return true
121
+ }
122
+
99
123
func initMetricsBySeries () {
100
124
for p := 0 ; p < int (partitionCount ); p ++ {
101
125
metrics := partitionMetrics {
0 commit comments