@@ -389,6 +389,10 @@ def do_checks():
389389 raise ValueError ("+Inf bucket missing: " + name )
390390 if count is not None and value != count :
391391 raise ValueError ("Count does not match +Inf value: " + name )
392+ if has_negative_buckets and has_sum :
393+ raise ValueError ("Cannot have _sum with negative buckets: " + name )
394+ if not has_negative_buckets and has_negative_gsum :
395+ raise ValueError ("Cannot have negative _gsum with non-negative buckets: " + name )
392396
393397 for s in samples :
394398 suffix = s .name [len (name ):]
@@ -397,21 +401,31 @@ def do_checks():
397401 if group is not None :
398402 do_checks ()
399403 count = None
400- bucket = - 1
404+ bucket = None
405+ has_negative_buckets = False
406+ has_sum = False
407+ has_negative_gsum = False
401408 value = 0
402409 group = g
403410 timestamp = s .timestamp
404411
405412 if suffix == '_bucket' :
406413 b = float (s .labels ['le' ])
407- if b <= bucket :
414+ if b < 0 :
415+ has_negative_buckets = True
416+ if bucket is not None and b <= bucket :
408417 raise ValueError ("Buckets out of order: " + name )
409418 if s .value < value :
410419 raise ValueError ("Bucket values out of order: " + name )
411420 bucket = b
412421 value = s .value
413422 elif suffix in ['_count' , '_gcount' ]:
414423 count = s .value
424+ elif suffix in ['_sum' ]:
425+ has_sum = True
426+ elif suffix in ['_gsum' ] and s .value < 0 :
427+ has_negative_gsum = True
428+
415429 if group is not None :
416430 do_checks ()
417431
@@ -529,7 +543,7 @@ def build_metric(name, documentation, typ, unit, samples):
529543 if typ == 'stateset' and name not in sample .labels :
530544 raise ValueError ("Stateset missing label: " + line )
531545 if (typ in ['histogram' , 'gaugehistogram' ] and name + '_bucket' == sample .name
532- and (float ( sample .labels .get ('le' , - 1 )) < 0
546+ and (sample .labels .get ('le' , "NaN" ) == "NaN"
533547 or sample .labels ['le' ] != floatToGoString (sample .labels ['le' ]))):
534548 raise ValueError ("Invalid le label: " + line )
535549 if (typ == 'summary' and name == sample .name
@@ -567,8 +581,7 @@ def build_metric(name, documentation, typ, unit, samples):
567581 if sample .name [len (name ):] in ['_total' , '_sum' , '_count' , '_bucket' , '_gcount' , '_gsum' ] and math .isnan (
568582 sample .value ):
569583 raise ValueError ("Counter-like samples cannot be NaN: " + line )
570- if sample .name [len (name ):] in ['_total' , '_sum' , '_count' , '_bucket' , '_gcount' ,
571- '_gsum' ] and sample .value < 0 :
584+ if sample .name [len (name ):] in ['_total' , '_sum' , '_count' , '_bucket' , '_gcount' ] and sample .value < 0 :
572585 raise ValueError ("Counter-like samples cannot be negative: " + line )
573586 if sample .exemplar and not (
574587 (typ in ['histogram' , 'gaugehistogram' ] and sample .name .endswith ('_bucket' ))
0 commit comments