From ae04378424c9171af06ecd3e7af91bebebe771cf Mon Sep 17 00:00:00 2001 From: Aliaksandr Valialkin Date: Tue, 24 Nov 2020 19:00:55 +0200 Subject: [PATCH] lib/protoparser/prometheus: properly parse "infinity" values in OpenMetrics format Updates https://github.com/VictoriaMetrics/VictoriaMetrics/issues/924 --- docs/CHANGELOG.md | 2 + go.mod | 2 +- go.sum | 4 +- lib/protoparser/prometheus/parser.go | 2 +- lib/protoparser/prometheus/parser_test.go | 41 +++++++++++++++++++ .../valyala/fastjson/fastfloat/parse.go | 8 +++- vendor/modules.txt | 2 +- 7 files changed, 54 insertions(+), 7 deletions(-) diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md index a9a318bbb..550672a27 100644 --- a/docs/CHANGELOG.md +++ b/docs/CHANGELOG.md @@ -21,6 +21,8 @@ See https://github.com/VictoriaMetrics/VictoriaMetrics/issues/851 * FEATURE: add `/tags/delSeries` handler from Graphite Tags API. See https://victoriametrics.github.io/#graphite-tags-api-usage * BUGFIX: properly parse Prometheus metrics with [exemplars](https://github.com/OpenObservability/OpenMetrics/blob/master/OpenMetrics.md#exemplars-1) such as `foo 123 # {bar="baz"} 1`. +* BUGFIX: properly parse "infinity" values in [OpenMetrics format](https://github.com/OpenObservability/OpenMetrics/blob/master/OpenMetrics.md#abnf). + See https://github.com/VictoriaMetrics/VictoriaMetrics/issues/924 # [v1.47.0](https://github.com/VictoriaMetrics/VictoriaMetrics/releases/tag/v1.47.0) diff --git a/go.mod b/go.mod index 8b886db80..c6fe4117e 100644 --- a/go.mod +++ b/go.mod @@ -15,7 +15,7 @@ require ( github.com/golang/snappy v0.0.2 github.com/klauspost/compress v1.11.3 github.com/stretchr/testify v1.5.1 // indirect - github.com/valyala/fastjson v1.6.1 + github.com/valyala/fastjson v1.6.3 github.com/valyala/fastrand v1.0.0 github.com/valyala/fasttemplate v1.2.1 github.com/valyala/gozstd v1.8.3 diff --git a/go.sum b/go.sum index b14e0bfb2..68e885846 100644 --- a/go.sum +++ b/go.sum @@ -164,8 +164,8 @@ github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5 github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw= github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= github.com/valyala/fasthttp v1.16.0/go.mod h1:YOKImeEosDdBPnxc0gy7INqi3m1zK6A+xl6TwOBhHCA= -github.com/valyala/fastjson v1.6.1 h1:qJs/Kz/HebWzk8LmhOrSm7kdOyJBr1XB+zSkYtEEfQE= -github.com/valyala/fastjson v1.6.1/go.mod h1:CLCAqky6SMuOcxStkYQvblddUtoRxhYMGLrsQns1aXY= +github.com/valyala/fastjson v1.6.3 h1:tAKFnnwmeMGPbwJ7IwxcTPCNr3uIzoIj3/Fh90ra4xc= +github.com/valyala/fastjson v1.6.3/go.mod h1:CLCAqky6SMuOcxStkYQvblddUtoRxhYMGLrsQns1aXY= github.com/valyala/fastrand v1.0.0 h1:LUKT9aKer2dVQNUi3waewTbKV+7H17kvWFNKs2ObdkI= github.com/valyala/fastrand v1.0.0/go.mod h1:HWqCzkrkg6QXT8V2EXWvXCoow7vLwOFN002oeRzjapQ= github.com/valyala/fasttemplate v1.2.1 h1:TVEnxayobAdVkhQfrfes2IzOB6o+z4roRkPF52WA1u4= diff --git a/lib/protoparser/prometheus/parser.go b/lib/protoparser/prometheus/parser.go index c7381f2bc..9d2753826 100644 --- a/lib/protoparser/prometheus/parser.go +++ b/lib/protoparser/prometheus/parser.go @@ -155,7 +155,7 @@ func (r *Row) unmarshal(s string, tagsPool []Tag, noEscapes bool) ([]Tag, error) r.Value = v return tagsPool, nil } - // There is timestamp. + // There is a timestamp. v, err := fastfloat.Parse(s[:n]) if err != nil { return tagsPool, fmt.Errorf("cannot parse value %q: %w", s[:n], err) diff --git a/lib/protoparser/prometheus/parser_test.go b/lib/protoparser/prometheus/parser_test.go index f864dd9a1..745139733 100644 --- a/lib/protoparser/prometheus/parser_test.go +++ b/lib/protoparser/prometheus/parser_test.go @@ -1,6 +1,7 @@ package prometheus import ( + "math" "reflect" "testing" ) @@ -233,6 +234,46 @@ cassandra_token_ownership_ratio 78.9`, &Rows{ }, }) + // "Infinity" word - this has been added in OpenMetrics. + // See https://github.com/OpenObservability/OpenMetrics/blob/master/OpenMetrics.md + // Checks for https://github.com/VictoriaMetrics/VictoriaMetrics/issues/924 + inf := math.Inf(1) + f(` + foo Infinity + bar +Infinity + baz -infinity + aaa +inf + bbb -INF + ccc INF + `, &Rows{ + Rows: []Row{ + { + Metric: "foo", + Value: inf, + }, + { + Metric: "bar", + Value: inf, + }, + { + Metric: "baz", + Value: -inf, + }, + { + Metric: "aaa", + Value: inf, + }, + { + Metric: "bbb", + Value: -inf, + }, + { + Metric: "ccc", + Value: inf, + }, + }, + }) + // Timestamp bigger than 1<<31 f("aaa 1123 429496729600", &Rows{ Rows: []Row{{ diff --git a/vendor/github.com/valyala/fastjson/fastfloat/parse.go b/vendor/github.com/valyala/fastjson/fastfloat/parse.go index d17d7f2e6..5d4a7c7a7 100644 --- a/vendor/github.com/valyala/fastjson/fastfloat/parse.go +++ b/vendor/github.com/valyala/fastjson/fastfloat/parse.go @@ -237,7 +237,9 @@ func ParseBestEffort(s string) float64 { if strings.HasPrefix(s, "+") { s = s[1:] } - if strings.EqualFold(s, "inf") { + // "infinity" is needed for OpenMetrics support. + // See https://github.com/OpenObservability/OpenMetrics/blob/master/OpenMetrics.md + if strings.EqualFold(s, "inf") || strings.EqualFold(s, "infinity") { if minus { return -inf } @@ -385,7 +387,9 @@ func Parse(s string) (float64, error) { if strings.HasPrefix(ss, "+") { ss = ss[1:] } - if strings.EqualFold(ss, "inf") { + // "infinity" is needed for OpenMetrics support. + // See https://github.com/OpenObservability/OpenMetrics/blob/master/OpenMetrics.md + if strings.EqualFold(ss, "inf") || strings.EqualFold(ss, "infinity") { if minus { return -inf, nil } diff --git a/vendor/modules.txt b/vendor/modules.txt index 2affcefa9..84457e3cd 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -99,7 +99,7 @@ github.com/klauspost/compress/zstd github.com/klauspost/compress/zstd/internal/xxhash # github.com/valyala/bytebufferpool v1.0.0 github.com/valyala/bytebufferpool -# github.com/valyala/fastjson v1.6.1 +# github.com/valyala/fastjson v1.6.3 github.com/valyala/fastjson github.com/valyala/fastjson/fastfloat # github.com/valyala/fastrand v1.0.0