Files
Aliaksandr Valialkin 9fa9fc18a7 lib/protoparser/opentelemetry: eliminate memory allocations during parsing of samples send via OpenTelemetry protocol
This increases the parser performance by 4x-6x.

This commit uses the technique similar to https://github.com/VictoriaMetrics/VictoriaLogs/pull/720

goos: linux
goarch: amd64
pkg: github.com/VictoriaMetrics/VictoriaMetrics/lib/protoparser/opentelemetry/stream
cpu: AMD Ryzen 7 PRO 5850U with Radeon Graphics
                                                    │   old.txt    │               new.txt               │
                                                    │    sec/op    │   sec/op     vs base                │
ParseStream/default-metrics-labels-formatting-16      15.565µ ± 1%   2.150µ ± 3%  -86.19% (p=0.000 n=10)
ParseStream/prometheus-metrics-labels-formatting-16   24.228µ ± 2%   4.355µ ± 1%  -82.02% (p=0.000 n=10)
ParseStream/prometheus-metrics-formatting-16          23.028µ ± 2%   3.395µ ± 1%  -85.26% (p=0.000 n=10)
geomean                                                20.55µ        3.168µ       -84.59%

                                                    │   old.txt    │                new.txt                 │
                                                    │     B/s      │      B/s       vs base                 │
ParseStream/default-metrics-labels-formatting-16      127.9Mi ± 1%    918.3Mi ± 3%  +617.82% (p=0.000 n=10)
ParseStream/prometheus-metrics-labels-formatting-16   82.19Mi ± 2%   453.32Mi ± 1%  +451.57% (p=0.000 n=10)
ParseStream/prometheus-metrics-formatting-16          86.47Mi ± 2%   581.56Mi ± 1%  +572.52% (p=0.000 n=10)
geomean                                               96.88Mi         623.3Mi       +543.34%

                                                    │   old.txt    │                 new.txt                  │
                                                    │     B/op     │    B/op      vs base                     │
ParseStream/default-metrics-labels-formatting-16      12.53Ki ± 0%   0.00Ki ± 0%  -100.00% (p=0.000 n=10)
ParseStream/prometheus-metrics-labels-formatting-16   21.15Ki ± 1%   0.00Ki ±  ?  -100.00% (p=0.000 n=10)
ParseStream/prometheus-metrics-formatting-16          20.74Ki ± 1%   0.00Ki ±  ?  -100.00% (p=0.000 n=10)
geomean                                               17.65Ki                     ?                       ¹ ²
¹ summaries must be >0 to compute geomean
² ratios must be >0 to compute geomean

                                                    │  old.txt   │                new.txt                 │
                                                    │ allocs/op  │ allocs/op  vs base                     │
ParseStream/default-metrics-labels-formatting-16      426.0 ± 0%    0.0 ± 0%  -100.00% (p=0.000 n=10)
ParseStream/prometheus-metrics-labels-formatting-16   514.0 ± 0%    0.0 ± 0%  -100.00% (p=0.000 n=10)
ParseStream/prometheus-metrics-formatting-16          514.0 ± 0%    0.0 ± 0%  -100.00% (p=0.000 n=10)
geomean                                               482.8                   ?                       ¹ ²
2025-12-10 16:11:59 +01:00

61 lines
2.0 KiB
Go

package stream
import (
"testing"
"github.com/VictoriaMetrics/VictoriaMetrics/lib/prompb"
"github.com/VictoriaMetrics/VictoriaMetrics/lib/protoparser/opentelemetry/pb"
)
func TestSanitizePrometheusLabelName(t *testing.T) {
f := func(labelName, expectedResult string) {
t.Helper()
var sctx sanitizerContext
result := sctx.sanitizePrometheusLabelName(labelName)
if result != expectedResult {
t.Fatalf("unexpected result; got %q; want %q", result, expectedResult)
}
}
f("", "")
f("foo", "foo")
f("foo_bar/baz:abc", "foo_bar_baz_abc")
f("1foo", "key_1foo")
f("_foo", "key_foo")
f("__bar", "__bar")
}
func TestSanitizePrometheusMetricName(t *testing.T) {
f := func(metricName, unit string, metricType prompb.MetricType, expectedResult string) {
t.Helper()
var sctx sanitizerContext
mm := pb.MetricMetadata{
Name: metricName,
Unit: unit,
Type: metricType,
}
result := sctx.sanitizePrometheusMetricName(&mm)
if result != expectedResult {
t.Fatalf("unexpected result; got %q; want %q", result, expectedResult)
}
}
f("", "", prompb.MetricTypeUnknown, "")
f("foo", "", prompb.MetricTypeUnknown, "foo")
f("foo", "s", prompb.MetricTypeUnknown, "foo_seconds")
f("foo_seconds", "s", prompb.MetricTypeUnknown, "foo_seconds")
f("foo", "", prompb.MetricTypeCounter, "foo_total")
f("foo_total", "", prompb.MetricTypeCounter, "foo_total")
f("foo", "s", prompb.MetricTypeCounter, "foo_seconds_total")
f("foo_seconds", "s", prompb.MetricTypeCounter, "foo_seconds_total")
f("foo_total", "s", prompb.MetricTypeCounter, "foo_seconds_total")
f("foo_seconds_total", "s", prompb.MetricTypeCounter, "foo_seconds_total")
f("foo_total_seconds", "s", prompb.MetricTypeCounter, "foo_seconds_total")
f("foo", "1", prompb.MetricTypeGauge, "foo_ratio")
f("foo", "m/s", prompb.MetricTypeUnknown, "foo_meters_per_second")
f("foo_second", "m/s", prompb.MetricTypeUnknown, "foo_second_meters")
f("foo_meters", "m/s", prompb.MetricTypeUnknown, "foo_meters_per_second")
}