2023-01-04 07:19:18 +01:00
|
|
|
package streamaggr
|
|
|
|
|
|
|
|
import (
|
|
|
|
"fmt"
|
|
|
|
"sort"
|
2023-07-25 01:44:09 +02:00
|
|
|
"strconv"
|
2023-01-04 07:19:18 +01:00
|
|
|
"strings"
|
|
|
|
"sync"
|
|
|
|
"testing"
|
2023-01-25 18:14:49 +01:00
|
|
|
"time"
|
2023-01-04 07:19:18 +01:00
|
|
|
|
|
|
|
"github.com/VictoriaMetrics/VictoriaMetrics/lib/prompbmarshal"
|
|
|
|
"github.com/VictoriaMetrics/VictoriaMetrics/lib/promrelabel"
|
|
|
|
"github.com/VictoriaMetrics/VictoriaMetrics/lib/protoparser/prometheus"
|
|
|
|
)
|
|
|
|
|
|
|
|
func TestAggregatorsFailure(t *testing.T) {
|
|
|
|
f := func(config string) {
|
|
|
|
t.Helper()
|
2024-04-02 22:16:24 +02:00
|
|
|
pushFunc := func(_ []prompbmarshal.TimeSeries) {
|
2023-01-04 07:19:18 +01:00
|
|
|
panic(fmt.Errorf("pushFunc shouldn't be called"))
|
|
|
|
}
|
2024-03-04 04:42:55 +01:00
|
|
|
a, err := newAggregatorsFromData([]byte(config), pushFunc, nil)
|
2023-01-04 07:19:18 +01:00
|
|
|
if err == nil {
|
|
|
|
t.Fatalf("expecting non-nil error")
|
|
|
|
}
|
|
|
|
if a != nil {
|
|
|
|
t.Fatalf("expecting nil a")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Invalid config
|
|
|
|
f(`foobar`)
|
|
|
|
|
|
|
|
// Unknown option
|
|
|
|
f(`
|
|
|
|
- interval: 1m
|
|
|
|
outputs: [total]
|
|
|
|
foobar: baz
|
|
|
|
`)
|
|
|
|
|
|
|
|
// missing interval
|
|
|
|
f(`
|
|
|
|
- outputs: [total]
|
|
|
|
`)
|
|
|
|
|
|
|
|
// missing outputs
|
|
|
|
f(`
|
|
|
|
- interval: 1m
|
|
|
|
`)
|
|
|
|
|
|
|
|
// Invalid output
|
|
|
|
f(`
|
|
|
|
- interval: 1m
|
|
|
|
outputs: [foobar]
|
|
|
|
`)
|
|
|
|
|
|
|
|
// Negative interval
|
lib/streamaggr: huge pile of changes
- Reduce memory usage by up to 5x when de-duplicating samples across big number of time series.
- Reduce memory usage by up to 5x when aggregating across big number of output time series.
- Add lib/promutils.LabelsCompressor, which is going to be used by other VictoriaMetrics components
for reducing memory usage for marshaled []prompbmarshal.Label.
- Add `dedup_interval` option at aggregation config, which allows setting individual
deduplication intervals per each aggregation.
- Add `keep_metric_names` option at aggregation config, which allows keeping the original
metric names in the output samples.
- Add `unique_samples` output, which counts the number of unique sample values.
- Add `increase_prometheus` and `total_prometheus` outputs, which ignore the first sample
per each newly encountered time series.
- Use 64-bit hashes instead of marshaled labels as map keys when calculating `count_series` output.
This makes obsolete https://github.com/VictoriaMetrics/VictoriaMetrics/pull/5579
- Expose various metrics, which may help debugging stream aggregation:
- vm_streamaggr_dedup_state_size_bytes - the size of data structures responsible for deduplication
- vm_streamaggr_dedup_state_items_count - the number of items in the deduplication data structures
- vm_streamaggr_labels_compressor_size_bytes - the size of labels compressor data structures
- vm_streamaggr_labels_compressor_items_count - the number of entries in the labels compressor
- vm_streamaggr_flush_duration_seconds - a histogram, which shows the duration of stream aggregation flushes
- vm_streamaggr_dedup_flush_duration_seconds - a histogram, which shows the duration of deduplication flushes
- vm_streamaggr_flush_timeouts_total - counter for timed out stream aggregation flushes,
which took longer than the configured interval
- vm_streamaggr_dedup_flush_timeouts_total - counter for timed out deduplication flushes,
which took longer than the configured dedup_interval
- Actualize docs/stream-aggregation.md
The memory usage reduction increases CPU usage during stream aggregation by up to 30%.
This commit is based on https://github.com/VictoriaMetrics/VictoriaMetrics/pull/5850
Updates https://github.com/VictoriaMetrics/VictoriaMetrics/issues/5898
2024-03-02 01:42:26 +01:00
|
|
|
f(`
|
|
|
|
- outputs: [total]
|
|
|
|
interval: -5m
|
|
|
|
`)
|
2023-01-04 07:19:18 +01:00
|
|
|
// Too small interval
|
lib/streamaggr: huge pile of changes
- Reduce memory usage by up to 5x when de-duplicating samples across big number of time series.
- Reduce memory usage by up to 5x when aggregating across big number of output time series.
- Add lib/promutils.LabelsCompressor, which is going to be used by other VictoriaMetrics components
for reducing memory usage for marshaled []prompbmarshal.Label.
- Add `dedup_interval` option at aggregation config, which allows setting individual
deduplication intervals per each aggregation.
- Add `keep_metric_names` option at aggregation config, which allows keeping the original
metric names in the output samples.
- Add `unique_samples` output, which counts the number of unique sample values.
- Add `increase_prometheus` and `total_prometheus` outputs, which ignore the first sample
per each newly encountered time series.
- Use 64-bit hashes instead of marshaled labels as map keys when calculating `count_series` output.
This makes obsolete https://github.com/VictoriaMetrics/VictoriaMetrics/pull/5579
- Expose various metrics, which may help debugging stream aggregation:
- vm_streamaggr_dedup_state_size_bytes - the size of data structures responsible for deduplication
- vm_streamaggr_dedup_state_items_count - the number of items in the deduplication data structures
- vm_streamaggr_labels_compressor_size_bytes - the size of labels compressor data structures
- vm_streamaggr_labels_compressor_items_count - the number of entries in the labels compressor
- vm_streamaggr_flush_duration_seconds - a histogram, which shows the duration of stream aggregation flushes
- vm_streamaggr_dedup_flush_duration_seconds - a histogram, which shows the duration of deduplication flushes
- vm_streamaggr_flush_timeouts_total - counter for timed out stream aggregation flushes,
which took longer than the configured interval
- vm_streamaggr_dedup_flush_timeouts_total - counter for timed out deduplication flushes,
which took longer than the configured dedup_interval
- Actualize docs/stream-aggregation.md
The memory usage reduction increases CPU usage during stream aggregation by up to 30%.
This commit is based on https://github.com/VictoriaMetrics/VictoriaMetrics/pull/5850
Updates https://github.com/VictoriaMetrics/VictoriaMetrics/issues/5898
2024-03-02 01:42:26 +01:00
|
|
|
f(`
|
|
|
|
- outputs: [total]
|
|
|
|
interval: 10ms
|
|
|
|
`)
|
|
|
|
|
|
|
|
// interval isn't multiple of dedup_interval
|
|
|
|
f(`
|
|
|
|
- interval: 1m
|
|
|
|
dedup_interval: 35s
|
|
|
|
outputs: ["quantiles"]
|
|
|
|
`)
|
|
|
|
|
|
|
|
// dedup_interval is bigger than dedup_interval
|
|
|
|
f(`
|
|
|
|
- interval: 1m
|
|
|
|
dedup_interval: 1h
|
|
|
|
outputs: ["quantiles"]
|
|
|
|
`)
|
|
|
|
|
|
|
|
// keep_metric_names is set for multiple inputs
|
|
|
|
f(`
|
|
|
|
- interval: 1m
|
|
|
|
keep_metric_names: true
|
|
|
|
outputs: ["total", "increase"]
|
|
|
|
`)
|
|
|
|
|
|
|
|
// keep_metric_names is set for unsupported input
|
|
|
|
f(`
|
|
|
|
- interval: 1m
|
|
|
|
keep_metric_names: true
|
|
|
|
outputs: ["histogram_bucket"]
|
|
|
|
`)
|
2023-01-04 07:19:18 +01:00
|
|
|
|
|
|
|
// Invalid input_relabel_configs
|
|
|
|
f(`
|
|
|
|
- interval: 1m
|
|
|
|
outputs: [total]
|
|
|
|
input_relabel_configs:
|
|
|
|
- foo: bar
|
|
|
|
`)
|
|
|
|
f(`
|
|
|
|
- interval: 1m
|
|
|
|
outputs: [total]
|
|
|
|
input_relabel_configs:
|
|
|
|
- action: replace
|
|
|
|
`)
|
|
|
|
|
|
|
|
// Invalid output_relabel_configs
|
|
|
|
f(`
|
|
|
|
- interval: 1m
|
|
|
|
outputs: [total]
|
|
|
|
output_relabel_configs:
|
|
|
|
- foo: bar
|
|
|
|
`)
|
|
|
|
f(`
|
|
|
|
- interval: 1m
|
|
|
|
outputs: [total]
|
|
|
|
output_relabel_configs:
|
|
|
|
- action: replace
|
|
|
|
`)
|
|
|
|
|
|
|
|
// Both by and without are non-empty
|
|
|
|
f(`
|
|
|
|
- interval: 1m
|
|
|
|
outputs: [total]
|
|
|
|
by: [foo]
|
|
|
|
without: [bar]
|
|
|
|
`)
|
|
|
|
|
|
|
|
// Invalid quantiles()
|
|
|
|
f(`
|
|
|
|
- interval: 1m
|
|
|
|
outputs: ["quantiles("]
|
|
|
|
`)
|
|
|
|
f(`
|
|
|
|
- interval: 1m
|
|
|
|
outputs: ["quantiles()"]
|
|
|
|
`)
|
|
|
|
f(`
|
|
|
|
- interval: 1m
|
|
|
|
outputs: ["quantiles(foo)"]
|
|
|
|
`)
|
|
|
|
f(`
|
|
|
|
- interval: 1m
|
|
|
|
outputs: ["quantiles(-0.5)"]
|
|
|
|
`)
|
|
|
|
f(`
|
|
|
|
- interval: 1m
|
|
|
|
outputs: ["quantiles(1.5)"]
|
|
|
|
`)
|
|
|
|
}
|
|
|
|
|
2023-04-01 06:27:45 +02:00
|
|
|
func TestAggregatorsEqual(t *testing.T) {
|
|
|
|
f := func(a, b string, expectedResult bool) {
|
|
|
|
t.Helper()
|
|
|
|
|
2024-04-02 22:16:24 +02:00
|
|
|
pushFunc := func(_ []prompbmarshal.TimeSeries) {}
|
2024-03-04 04:42:55 +01:00
|
|
|
aa, err := newAggregatorsFromData([]byte(a), pushFunc, nil)
|
2023-04-01 06:27:45 +02:00
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("cannot initialize aggregators: %s", err)
|
|
|
|
}
|
2024-03-04 04:42:55 +01:00
|
|
|
ab, err := newAggregatorsFromData([]byte(b), pushFunc, nil)
|
2023-04-01 06:27:45 +02:00
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("cannot initialize aggregators: %s", err)
|
|
|
|
}
|
|
|
|
result := aa.Equal(ab)
|
|
|
|
if result != expectedResult {
|
|
|
|
t.Fatalf("unexpected result; got %v; want %v", result, expectedResult)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
f("", "", true)
|
|
|
|
f(`
|
|
|
|
- outputs: [total]
|
|
|
|
interval: 5m
|
|
|
|
`, ``, false)
|
|
|
|
f(`
|
|
|
|
- outputs: [total]
|
|
|
|
interval: 5m
|
|
|
|
`, `
|
|
|
|
- outputs: [total]
|
|
|
|
interval: 5m
|
|
|
|
`, true)
|
|
|
|
f(`
|
|
|
|
- outputs: [total]
|
|
|
|
interval: 3m
|
|
|
|
`, `
|
|
|
|
- outputs: [total]
|
|
|
|
interval: 5m
|
2024-01-26 22:45:23 +01:00
|
|
|
`, false)
|
|
|
|
f(`
|
|
|
|
- outputs: [total]
|
|
|
|
interval: 5m
|
|
|
|
flush_on_shutdown: true
|
|
|
|
`, `
|
|
|
|
- outputs: [total]
|
|
|
|
interval: 5m
|
|
|
|
flush_on_shutdown: false
|
2023-04-01 06:27:45 +02:00
|
|
|
`, false)
|
2024-04-22 14:22:59 +02:00
|
|
|
f(`
|
|
|
|
- outputs: [total]
|
|
|
|
interval: 5m
|
|
|
|
ignore_first_intervals: 2
|
|
|
|
`, `
|
|
|
|
- outputs: [total]
|
|
|
|
interval: 5m
|
|
|
|
ignore_first_intervals: 4`, false)
|
2023-04-01 06:27:45 +02:00
|
|
|
}
|
|
|
|
|
2023-01-04 07:19:18 +01:00
|
|
|
func TestAggregatorsSuccess(t *testing.T) {
|
2023-07-25 01:44:09 +02:00
|
|
|
f := func(config, inputMetrics, outputMetricsExpected, matchIdxsStrExpected string) {
|
2023-01-04 07:19:18 +01:00
|
|
|
t.Helper()
|
|
|
|
|
|
|
|
// Initialize Aggregators
|
|
|
|
var tssOutput []prompbmarshal.TimeSeries
|
|
|
|
var tssOutputLock sync.Mutex
|
|
|
|
pushFunc := func(tss []prompbmarshal.TimeSeries) {
|
|
|
|
tssOutputLock.Lock()
|
2024-03-04 23:45:22 +01:00
|
|
|
tssOutput = appendClonedTimeseries(tssOutput, tss)
|
2023-01-04 07:19:18 +01:00
|
|
|
tssOutputLock.Unlock()
|
|
|
|
}
|
2024-03-04 04:42:55 +01:00
|
|
|
opts := &Options{
|
|
|
|
FlushOnShutdown: true,
|
|
|
|
NoAlignFlushToInterval: true,
|
|
|
|
}
|
|
|
|
a, err := newAggregatorsFromData([]byte(config), pushFunc, opts)
|
2023-01-04 07:19:18 +01:00
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("cannot initialize aggregators: %s", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
// Push the inputMetrics to Aggregators
|
|
|
|
tssInput := mustParsePromMetrics(inputMetrics)
|
2023-07-25 01:44:09 +02:00
|
|
|
matchIdxs := a.Push(tssInput, nil)
|
2023-01-04 07:19:18 +01:00
|
|
|
a.MustStop()
|
|
|
|
|
2023-07-25 01:44:09 +02:00
|
|
|
// Verify matchIdxs equals to matchIdxsExpected
|
|
|
|
matchIdxsStr := ""
|
|
|
|
for _, v := range matchIdxs {
|
|
|
|
matchIdxsStr += strconv.Itoa(int(v))
|
|
|
|
}
|
|
|
|
if matchIdxsStr != matchIdxsStrExpected {
|
|
|
|
t.Fatalf("unexpected matchIdxs;\ngot\n%s\nwant\n%s", matchIdxsStr, matchIdxsStrExpected)
|
|
|
|
}
|
|
|
|
|
2023-01-04 07:19:18 +01:00
|
|
|
// Verify the tssOutput contains the expected metrics
|
2024-03-04 23:45:22 +01:00
|
|
|
outputMetrics := timeSeriessToString(tssOutput)
|
2023-01-04 07:19:18 +01:00
|
|
|
if outputMetrics != outputMetricsExpected {
|
|
|
|
t.Fatalf("unexpected output metrics;\ngot\n%s\nwant\n%s", outputMetrics, outputMetricsExpected)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-06-17 14:21:16 +02:00
|
|
|
// rate with duplicated events
|
|
|
|
f(`
|
|
|
|
- interval: 1m
|
|
|
|
by: [cde]
|
|
|
|
outputs: [rate_sum, rate_avg]
|
|
|
|
`, `
|
|
|
|
foo{abc="123", cde="1"} 0 10
|
|
|
|
foo{abc="123", cde="1"} 0 10
|
|
|
|
`, `foo:1m_by_cde_rate_avg{cde="1"} 0
|
|
|
|
foo:1m_by_cde_rate_sum{cde="1"} 0
|
|
|
|
`, "11")
|
|
|
|
|
|
|
|
// rate with duplicated events
|
|
|
|
f(`
|
|
|
|
- interval: 1m
|
|
|
|
by: [cde]
|
|
|
|
outputs: [rate_sum, rate_avg]
|
|
|
|
`, `
|
|
|
|
foo{abc="123", cde="1"} -4 10
|
|
|
|
foo{abc="123", cde="1"} -2 20
|
|
|
|
`, `foo:1m_by_cde_rate_avg{cde="1"} 0
|
|
|
|
foo:1m_by_cde_rate_sum{cde="1"} 0
|
|
|
|
`, "11")
|
|
|
|
|
|
|
|
return
|
|
|
|
|
2023-01-04 07:19:18 +01:00
|
|
|
// Empty config
|
2023-07-25 01:44:09 +02:00
|
|
|
f(``, ``, ``, "")
|
|
|
|
f(``, `foo{bar="baz"} 1`, ``, "0")
|
|
|
|
f(``, "foo 1\nbaz 2", ``, "00")
|
2023-01-04 07:19:18 +01:00
|
|
|
|
|
|
|
// Empty by list - aggregate only by time
|
|
|
|
f(`
|
|
|
|
- interval: 1m
|
|
|
|
outputs: [count_samples, sum_samples, count_series, last]
|
|
|
|
`, `
|
|
|
|
foo{abc="123"} 4
|
2024-03-18 00:02:28 +01:00
|
|
|
bar 5 100
|
|
|
|
bar 34 10
|
2023-01-04 07:19:18 +01:00
|
|
|
foo{abc="123"} 8.5
|
|
|
|
foo{abc="456",de="fg"} 8
|
2024-03-18 00:02:28 +01:00
|
|
|
`, `bar:1m_count_samples 2
|
2023-01-04 07:19:18 +01:00
|
|
|
bar:1m_count_series 1
|
|
|
|
bar:1m_last 5
|
2024-03-18 00:02:28 +01:00
|
|
|
bar:1m_sum_samples 39
|
2023-01-04 07:19:18 +01:00
|
|
|
foo:1m_count_samples{abc="123"} 2
|
|
|
|
foo:1m_count_samples{abc="456",de="fg"} 1
|
|
|
|
foo:1m_count_series{abc="123"} 1
|
|
|
|
foo:1m_count_series{abc="456",de="fg"} 1
|
|
|
|
foo:1m_last{abc="123"} 8.5
|
|
|
|
foo:1m_last{abc="456",de="fg"} 8
|
|
|
|
foo:1m_sum_samples{abc="123"} 12.5
|
|
|
|
foo:1m_sum_samples{abc="456",de="fg"} 8
|
2024-03-18 00:02:28 +01:00
|
|
|
`, "11111")
|
2023-01-04 07:19:18 +01:00
|
|
|
|
2023-01-05 11:08:24 +01:00
|
|
|
// Special case: __name__ in `by` list - this is the same as empty `by` list
|
2023-01-04 07:19:18 +01:00
|
|
|
f(`
|
|
|
|
- interval: 1m
|
|
|
|
by: [__name__]
|
|
|
|
outputs: [count_samples, sum_samples, count_series]
|
|
|
|
`, `
|
|
|
|
foo{abc="123"} 4
|
|
|
|
bar 5
|
|
|
|
foo{abc="123"} 8.5
|
|
|
|
foo{abc="456",de="fg"} 8
|
|
|
|
`, `bar:1m_count_samples 1
|
|
|
|
bar:1m_count_series 1
|
|
|
|
bar:1m_sum_samples 5
|
|
|
|
foo:1m_count_samples 3
|
|
|
|
foo:1m_count_series 2
|
|
|
|
foo:1m_sum_samples 20.5
|
2023-07-25 01:44:09 +02:00
|
|
|
`, "1111")
|
2023-01-04 07:19:18 +01:00
|
|
|
|
2023-01-05 11:08:24 +01:00
|
|
|
// Non-empty `by` list with non-existing labels
|
2023-01-04 07:19:18 +01:00
|
|
|
f(`
|
|
|
|
- interval: 1m
|
|
|
|
by: [foo, bar]
|
|
|
|
outputs: [count_samples, sum_samples, count_series]
|
|
|
|
`, `
|
|
|
|
foo{abc="123"} 4
|
|
|
|
bar 5
|
|
|
|
foo{abc="123"} 8.5
|
|
|
|
foo{abc="456",de="fg"} 8
|
2023-01-05 11:08:24 +01:00
|
|
|
`, `bar:1m_by_bar_foo_count_samples 1
|
|
|
|
bar:1m_by_bar_foo_count_series 1
|
|
|
|
bar:1m_by_bar_foo_sum_samples 5
|
|
|
|
foo:1m_by_bar_foo_count_samples 3
|
|
|
|
foo:1m_by_bar_foo_count_series 2
|
|
|
|
foo:1m_by_bar_foo_sum_samples 20.5
|
2023-07-25 01:44:09 +02:00
|
|
|
`, "1111")
|
2023-01-04 07:19:18 +01:00
|
|
|
|
2023-01-05 11:08:24 +01:00
|
|
|
// Non-empty `by` list with existing label
|
2023-01-04 07:19:18 +01:00
|
|
|
f(`
|
|
|
|
- interval: 1m
|
|
|
|
by: [abc]
|
|
|
|
outputs: [count_samples, sum_samples, count_series]
|
|
|
|
`, `
|
|
|
|
foo{abc="123"} 4
|
|
|
|
bar 5
|
|
|
|
foo{abc="123"} 8.5
|
|
|
|
foo{abc="456",de="fg"} 8
|
|
|
|
`, `bar:1m_by_abc_count_samples 1
|
|
|
|
bar:1m_by_abc_count_series 1
|
|
|
|
bar:1m_by_abc_sum_samples 5
|
|
|
|
foo:1m_by_abc_count_samples{abc="123"} 2
|
|
|
|
foo:1m_by_abc_count_samples{abc="456"} 1
|
|
|
|
foo:1m_by_abc_count_series{abc="123"} 1
|
|
|
|
foo:1m_by_abc_count_series{abc="456"} 1
|
|
|
|
foo:1m_by_abc_sum_samples{abc="123"} 12.5
|
|
|
|
foo:1m_by_abc_sum_samples{abc="456"} 8
|
2023-07-25 01:44:09 +02:00
|
|
|
`, "1111")
|
2023-01-04 07:19:18 +01:00
|
|
|
|
2023-01-05 11:08:24 +01:00
|
|
|
// Non-empty `by` list with duplicate existing label
|
|
|
|
f(`
|
|
|
|
- interval: 1m
|
|
|
|
by: [abc, abc]
|
|
|
|
outputs: [count_samples, sum_samples, count_series]
|
|
|
|
`, `
|
|
|
|
foo{abc="123"} 4
|
|
|
|
bar 5
|
|
|
|
foo{abc="123"} 8.5
|
|
|
|
foo{abc="456",de="fg"} 8
|
|
|
|
`, `bar:1m_by_abc_count_samples 1
|
|
|
|
bar:1m_by_abc_count_series 1
|
|
|
|
bar:1m_by_abc_sum_samples 5
|
|
|
|
foo:1m_by_abc_count_samples{abc="123"} 2
|
|
|
|
foo:1m_by_abc_count_samples{abc="456"} 1
|
|
|
|
foo:1m_by_abc_count_series{abc="123"} 1
|
|
|
|
foo:1m_by_abc_count_series{abc="456"} 1
|
|
|
|
foo:1m_by_abc_sum_samples{abc="123"} 12.5
|
|
|
|
foo:1m_by_abc_sum_samples{abc="456"} 8
|
2023-07-25 01:44:09 +02:00
|
|
|
`, "1111")
|
2023-01-05 11:08:24 +01:00
|
|
|
|
|
|
|
// Non-empty `without` list with non-existing labels
|
2023-01-04 07:19:18 +01:00
|
|
|
f(`
|
|
|
|
- interval: 1m
|
|
|
|
without: [foo]
|
|
|
|
outputs: [count_samples, sum_samples, count_series]
|
|
|
|
`, `
|
|
|
|
foo{abc="123"} 4
|
|
|
|
bar 5
|
|
|
|
foo{abc="123"} 8.5
|
|
|
|
foo{abc="456",de="fg"} 8
|
|
|
|
`, `bar:1m_without_foo_count_samples 1
|
|
|
|
bar:1m_without_foo_count_series 1
|
|
|
|
bar:1m_without_foo_sum_samples 5
|
|
|
|
foo:1m_without_foo_count_samples{abc="123"} 2
|
|
|
|
foo:1m_without_foo_count_samples{abc="456",de="fg"} 1
|
|
|
|
foo:1m_without_foo_count_series{abc="123"} 1
|
|
|
|
foo:1m_without_foo_count_series{abc="456",de="fg"} 1
|
|
|
|
foo:1m_without_foo_sum_samples{abc="123"} 12.5
|
|
|
|
foo:1m_without_foo_sum_samples{abc="456",de="fg"} 8
|
2023-07-25 01:44:09 +02:00
|
|
|
`, "1111")
|
2023-01-04 07:19:18 +01:00
|
|
|
|
2023-01-05 11:08:24 +01:00
|
|
|
// Non-empty `without` list with existing labels
|
2023-01-04 07:19:18 +01:00
|
|
|
f(`
|
|
|
|
- interval: 1m
|
|
|
|
without: [abc]
|
|
|
|
outputs: [count_samples, sum_samples, count_series]
|
|
|
|
`, `
|
|
|
|
foo{abc="123"} 4
|
|
|
|
bar 5
|
|
|
|
foo{abc="123"} 8.5
|
|
|
|
foo{abc="456",de="fg"} 8
|
|
|
|
`, `bar:1m_without_abc_count_samples 1
|
|
|
|
bar:1m_without_abc_count_series 1
|
|
|
|
bar:1m_without_abc_sum_samples 5
|
|
|
|
foo:1m_without_abc_count_samples 2
|
|
|
|
foo:1m_without_abc_count_samples{de="fg"} 1
|
|
|
|
foo:1m_without_abc_count_series 1
|
|
|
|
foo:1m_without_abc_count_series{de="fg"} 1
|
|
|
|
foo:1m_without_abc_sum_samples 12.5
|
|
|
|
foo:1m_without_abc_sum_samples{de="fg"} 8
|
2023-07-25 01:44:09 +02:00
|
|
|
`, "1111")
|
2023-01-04 07:19:18 +01:00
|
|
|
|
2023-01-05 11:08:24 +01:00
|
|
|
// Special case: __name__ in `without` list
|
2023-01-04 07:19:18 +01:00
|
|
|
f(`
|
|
|
|
- interval: 1m
|
|
|
|
without: [__name__]
|
|
|
|
outputs: [count_samples, sum_samples, count_series]
|
|
|
|
`, `
|
|
|
|
foo{abc="123"} 4
|
|
|
|
bar 5
|
|
|
|
foo{abc="123"} 8.5
|
|
|
|
foo{abc="456",de="fg"} 8
|
|
|
|
`, `:1m_count_samples 1
|
|
|
|
:1m_count_samples{abc="123"} 2
|
|
|
|
:1m_count_samples{abc="456",de="fg"} 1
|
|
|
|
:1m_count_series 1
|
|
|
|
:1m_count_series{abc="123"} 1
|
|
|
|
:1m_count_series{abc="456",de="fg"} 1
|
|
|
|
:1m_sum_samples 5
|
|
|
|
:1m_sum_samples{abc="123"} 12.5
|
|
|
|
:1m_sum_samples{abc="456",de="fg"} 8
|
2023-07-25 01:44:09 +02:00
|
|
|
`, "1111")
|
2023-01-04 07:19:18 +01:00
|
|
|
|
|
|
|
// drop some input metrics
|
|
|
|
f(`
|
|
|
|
- interval: 1m
|
|
|
|
without: [abc]
|
|
|
|
outputs: [count_samples, sum_samples, count_series]
|
|
|
|
input_relabel_configs:
|
|
|
|
- if: 'foo'
|
|
|
|
action: drop
|
|
|
|
`, `
|
|
|
|
foo{abc="123"} 4
|
|
|
|
bar 5
|
|
|
|
foo{abc="123"} 8.5
|
|
|
|
foo{abc="456",de="fg"} 8
|
|
|
|
`, `bar:1m_without_abc_count_samples 1
|
|
|
|
bar:1m_without_abc_count_series 1
|
|
|
|
bar:1m_without_abc_sum_samples 5
|
2023-07-25 01:44:09 +02:00
|
|
|
`, "1111")
|
2023-01-04 07:19:18 +01:00
|
|
|
|
|
|
|
// rename output metrics
|
|
|
|
f(`
|
|
|
|
- interval: 1m
|
|
|
|
without: [abc]
|
|
|
|
outputs: [count_samples, sum_samples, count_series]
|
|
|
|
output_relabel_configs:
|
|
|
|
- action: replace_all
|
|
|
|
source_labels: [__name__]
|
|
|
|
regex: ":|_"
|
|
|
|
replacement: "-"
|
|
|
|
target_label: __name__
|
|
|
|
- action: drop
|
|
|
|
source_labels: [de]
|
|
|
|
regex: fg
|
|
|
|
`, `
|
|
|
|
foo{abc="123"} 4
|
|
|
|
bar 5
|
|
|
|
foo{abc="123"} 8.5
|
|
|
|
foo{abc="456",de="fg"} 8
|
|
|
|
`, `bar-1m-without-abc-count-samples 1
|
|
|
|
bar-1m-without-abc-count-series 1
|
|
|
|
bar-1m-without-abc-sum-samples 5
|
|
|
|
foo-1m-without-abc-count-samples 2
|
|
|
|
foo-1m-without-abc-count-series 1
|
|
|
|
foo-1m-without-abc-sum-samples 12.5
|
2023-07-25 01:44:09 +02:00
|
|
|
`, "1111")
|
2023-01-04 07:19:18 +01:00
|
|
|
|
|
|
|
// match doesn't match anything
|
|
|
|
f(`
|
|
|
|
- interval: 1m
|
|
|
|
without: [abc]
|
|
|
|
outputs: [count_samples, sum_samples, count_series]
|
|
|
|
match: '{non_existing_label!=""}'
|
|
|
|
`, `
|
|
|
|
foo{abc="123"} 4
|
|
|
|
bar 5
|
|
|
|
foo{abc="123"} 8.5
|
|
|
|
foo{abc="456",de="fg"} 8
|
2023-07-25 01:44:09 +02:00
|
|
|
`, ``, "0000")
|
2023-01-04 07:19:18 +01:00
|
|
|
|
|
|
|
// match matches foo series with non-empty abc label
|
|
|
|
f(`
|
|
|
|
- interval: 1m
|
|
|
|
by: [abc]
|
|
|
|
outputs: [count_samples, sum_samples, count_series]
|
2023-07-25 01:10:47 +02:00
|
|
|
match:
|
|
|
|
- foo{abc=~".+"}
|
|
|
|
- '{non_existing_label!=""}'
|
2023-01-04 07:19:18 +01:00
|
|
|
`, `
|
|
|
|
foo{abc="123"} 4
|
|
|
|
bar 5
|
|
|
|
foo{abc="123"} 8.5
|
|
|
|
foo{abc="456",de="fg"} 8
|
|
|
|
`, `foo:1m_by_abc_count_samples{abc="123"} 2
|
|
|
|
foo:1m_by_abc_count_samples{abc="456"} 1
|
|
|
|
foo:1m_by_abc_count_series{abc="123"} 1
|
|
|
|
foo:1m_by_abc_count_series{abc="456"} 1
|
|
|
|
foo:1m_by_abc_sum_samples{abc="123"} 12.5
|
|
|
|
foo:1m_by_abc_sum_samples{abc="456"} 8
|
2023-07-25 01:44:09 +02:00
|
|
|
`, "1011")
|
2023-01-04 07:19:18 +01:00
|
|
|
|
|
|
|
// total output for non-repeated series
|
|
|
|
f(`
|
|
|
|
- interval: 1m
|
|
|
|
outputs: [total]
|
|
|
|
`, `
|
|
|
|
foo 123
|
|
|
|
bar{baz="qwe"} 4.34
|
2024-03-04 00:49:26 +01:00
|
|
|
`, `bar:1m_total{baz="qwe"} 0
|
|
|
|
foo:1m_total 0
|
lib/streamaggr: huge pile of changes
- Reduce memory usage by up to 5x when de-duplicating samples across big number of time series.
- Reduce memory usage by up to 5x when aggregating across big number of output time series.
- Add lib/promutils.LabelsCompressor, which is going to be used by other VictoriaMetrics components
for reducing memory usage for marshaled []prompbmarshal.Label.
- Add `dedup_interval` option at aggregation config, which allows setting individual
deduplication intervals per each aggregation.
- Add `keep_metric_names` option at aggregation config, which allows keeping the original
metric names in the output samples.
- Add `unique_samples` output, which counts the number of unique sample values.
- Add `increase_prometheus` and `total_prometheus` outputs, which ignore the first sample
per each newly encountered time series.
- Use 64-bit hashes instead of marshaled labels as map keys when calculating `count_series` output.
This makes obsolete https://github.com/VictoriaMetrics/VictoriaMetrics/pull/5579
- Expose various metrics, which may help debugging stream aggregation:
- vm_streamaggr_dedup_state_size_bytes - the size of data structures responsible for deduplication
- vm_streamaggr_dedup_state_items_count - the number of items in the deduplication data structures
- vm_streamaggr_labels_compressor_size_bytes - the size of labels compressor data structures
- vm_streamaggr_labels_compressor_items_count - the number of entries in the labels compressor
- vm_streamaggr_flush_duration_seconds - a histogram, which shows the duration of stream aggregation flushes
- vm_streamaggr_dedup_flush_duration_seconds - a histogram, which shows the duration of deduplication flushes
- vm_streamaggr_flush_timeouts_total - counter for timed out stream aggregation flushes,
which took longer than the configured interval
- vm_streamaggr_dedup_flush_timeouts_total - counter for timed out deduplication flushes,
which took longer than the configured dedup_interval
- Actualize docs/stream-aggregation.md
The memory usage reduction increases CPU usage during stream aggregation by up to 30%.
This commit is based on https://github.com/VictoriaMetrics/VictoriaMetrics/pull/5850
Updates https://github.com/VictoriaMetrics/VictoriaMetrics/issues/5898
2024-03-02 01:42:26 +01:00
|
|
|
`, "11")
|
|
|
|
|
|
|
|
// total_prometheus output for non-repeated series
|
|
|
|
f(`
|
|
|
|
- interval: 1m
|
|
|
|
outputs: [total_prometheus]
|
|
|
|
`, `
|
|
|
|
foo 123
|
|
|
|
bar{baz="qwe"} 4.34
|
2024-05-08 13:11:30 +02:00
|
|
|
`, `bar:1m_total_prometheus{baz="qwe"} 0
|
|
|
|
foo:1m_total_prometheus 0
|
2023-07-25 01:44:09 +02:00
|
|
|
`, "11")
|
2023-01-04 07:19:18 +01:00
|
|
|
|
|
|
|
// total output for repeated series
|
|
|
|
f(`
|
|
|
|
- interval: 1m
|
|
|
|
outputs: [total]
|
|
|
|
`, `
|
|
|
|
foo 123
|
2024-03-17 21:03:01 +01:00
|
|
|
bar{baz="qwe"} 1.31
|
|
|
|
bar{baz="qwe"} 4.34 1000
|
2023-01-04 07:19:18 +01:00
|
|
|
bar{baz="qwe"} 2
|
|
|
|
foo{baz="qwe"} -5
|
|
|
|
bar{baz="qwer"} 343
|
|
|
|
bar{baz="qwer"} 344
|
|
|
|
foo{baz="qwe"} 10
|
2024-03-17 21:03:01 +01:00
|
|
|
`, `bar:1m_total{baz="qwe"} 3.03
|
2024-03-04 00:49:26 +01:00
|
|
|
bar:1m_total{baz="qwer"} 1
|
|
|
|
foo:1m_total 0
|
|
|
|
foo:1m_total{baz="qwe"} 15
|
lib/streamaggr: huge pile of changes
- Reduce memory usage by up to 5x when de-duplicating samples across big number of time series.
- Reduce memory usage by up to 5x when aggregating across big number of output time series.
- Add lib/promutils.LabelsCompressor, which is going to be used by other VictoriaMetrics components
for reducing memory usage for marshaled []prompbmarshal.Label.
- Add `dedup_interval` option at aggregation config, which allows setting individual
deduplication intervals per each aggregation.
- Add `keep_metric_names` option at aggregation config, which allows keeping the original
metric names in the output samples.
- Add `unique_samples` output, which counts the number of unique sample values.
- Add `increase_prometheus` and `total_prometheus` outputs, which ignore the first sample
per each newly encountered time series.
- Use 64-bit hashes instead of marshaled labels as map keys when calculating `count_series` output.
This makes obsolete https://github.com/VictoriaMetrics/VictoriaMetrics/pull/5579
- Expose various metrics, which may help debugging stream aggregation:
- vm_streamaggr_dedup_state_size_bytes - the size of data structures responsible for deduplication
- vm_streamaggr_dedup_state_items_count - the number of items in the deduplication data structures
- vm_streamaggr_labels_compressor_size_bytes - the size of labels compressor data structures
- vm_streamaggr_labels_compressor_items_count - the number of entries in the labels compressor
- vm_streamaggr_flush_duration_seconds - a histogram, which shows the duration of stream aggregation flushes
- vm_streamaggr_dedup_flush_duration_seconds - a histogram, which shows the duration of deduplication flushes
- vm_streamaggr_flush_timeouts_total - counter for timed out stream aggregation flushes,
which took longer than the configured interval
- vm_streamaggr_dedup_flush_timeouts_total - counter for timed out deduplication flushes,
which took longer than the configured dedup_interval
- Actualize docs/stream-aggregation.md
The memory usage reduction increases CPU usage during stream aggregation by up to 30%.
This commit is based on https://github.com/VictoriaMetrics/VictoriaMetrics/pull/5850
Updates https://github.com/VictoriaMetrics/VictoriaMetrics/issues/5898
2024-03-02 01:42:26 +01:00
|
|
|
`, "11111111")
|
|
|
|
|
|
|
|
// total_prometheus output for repeated series
|
|
|
|
f(`
|
|
|
|
- interval: 1m
|
|
|
|
outputs: [total_prometheus]
|
|
|
|
`, `
|
|
|
|
foo 123
|
|
|
|
bar{baz="qwe"} 1.32
|
|
|
|
bar{baz="qwe"} 4.34
|
|
|
|
bar{baz="qwe"} 2
|
|
|
|
foo{baz="qwe"} -5
|
|
|
|
bar{baz="qwer"} 343
|
|
|
|
bar{baz="qwer"} 344
|
|
|
|
foo{baz="qwe"} 10
|
2024-05-08 13:11:30 +02:00
|
|
|
`, `bar:1m_total_prometheus{baz="qwe"} 5.02
|
|
|
|
bar:1m_total_prometheus{baz="qwer"} 1
|
|
|
|
foo:1m_total_prometheus 0
|
|
|
|
foo:1m_total_prometheus{baz="qwe"} 15
|
2023-07-25 01:44:09 +02:00
|
|
|
`, "11111111")
|
2023-01-04 07:19:18 +01:00
|
|
|
|
|
|
|
// total output for repeated series with group by __name__
|
|
|
|
f(`
|
|
|
|
- interval: 1m
|
|
|
|
by: [__name__]
|
|
|
|
outputs: [total]
|
|
|
|
`, `
|
|
|
|
foo 123
|
|
|
|
bar{baz="qwe"} 1.32
|
|
|
|
bar{baz="qwe"} 4.34
|
|
|
|
bar{baz="qwe"} 2
|
|
|
|
foo{baz="qwe"} -5
|
|
|
|
bar{baz="qwer"} 343
|
|
|
|
bar{baz="qwer"} 344
|
|
|
|
foo{baz="qwe"} 10
|
2024-03-04 00:49:26 +01:00
|
|
|
`, `bar:1m_total 6.02
|
|
|
|
foo:1m_total 15
|
lib/streamaggr: huge pile of changes
- Reduce memory usage by up to 5x when de-duplicating samples across big number of time series.
- Reduce memory usage by up to 5x when aggregating across big number of output time series.
- Add lib/promutils.LabelsCompressor, which is going to be used by other VictoriaMetrics components
for reducing memory usage for marshaled []prompbmarshal.Label.
- Add `dedup_interval` option at aggregation config, which allows setting individual
deduplication intervals per each aggregation.
- Add `keep_metric_names` option at aggregation config, which allows keeping the original
metric names in the output samples.
- Add `unique_samples` output, which counts the number of unique sample values.
- Add `increase_prometheus` and `total_prometheus` outputs, which ignore the first sample
per each newly encountered time series.
- Use 64-bit hashes instead of marshaled labels as map keys when calculating `count_series` output.
This makes obsolete https://github.com/VictoriaMetrics/VictoriaMetrics/pull/5579
- Expose various metrics, which may help debugging stream aggregation:
- vm_streamaggr_dedup_state_size_bytes - the size of data structures responsible for deduplication
- vm_streamaggr_dedup_state_items_count - the number of items in the deduplication data structures
- vm_streamaggr_labels_compressor_size_bytes - the size of labels compressor data structures
- vm_streamaggr_labels_compressor_items_count - the number of entries in the labels compressor
- vm_streamaggr_flush_duration_seconds - a histogram, which shows the duration of stream aggregation flushes
- vm_streamaggr_dedup_flush_duration_seconds - a histogram, which shows the duration of deduplication flushes
- vm_streamaggr_flush_timeouts_total - counter for timed out stream aggregation flushes,
which took longer than the configured interval
- vm_streamaggr_dedup_flush_timeouts_total - counter for timed out deduplication flushes,
which took longer than the configured dedup_interval
- Actualize docs/stream-aggregation.md
The memory usage reduction increases CPU usage during stream aggregation by up to 30%.
This commit is based on https://github.com/VictoriaMetrics/VictoriaMetrics/pull/5850
Updates https://github.com/VictoriaMetrics/VictoriaMetrics/issues/5898
2024-03-02 01:42:26 +01:00
|
|
|
`, "11111111")
|
|
|
|
|
|
|
|
// total_prometheus output for repeated series with group by __name__
|
|
|
|
f(`
|
|
|
|
- interval: 1m
|
|
|
|
by: [__name__]
|
|
|
|
outputs: [total_prometheus]
|
|
|
|
`, `
|
|
|
|
foo 123
|
|
|
|
bar{baz="qwe"} 1.32
|
|
|
|
bar{baz="qwe"} 4.34
|
|
|
|
bar{baz="qwe"} 2
|
|
|
|
foo{baz="qwe"} -5
|
|
|
|
bar{baz="qwer"} 343
|
|
|
|
bar{baz="qwer"} 344
|
|
|
|
foo{baz="qwe"} 10
|
2024-05-08 13:11:30 +02:00
|
|
|
`, `bar:1m_total_prometheus 6.02
|
|
|
|
foo:1m_total_prometheus 15
|
2023-07-25 01:44:09 +02:00
|
|
|
`, "11111111")
|
2023-01-04 07:19:18 +01:00
|
|
|
|
|
|
|
// increase output for non-repeated series
|
|
|
|
f(`
|
|
|
|
- interval: 1m
|
|
|
|
outputs: [increase]
|
|
|
|
`, `
|
|
|
|
foo 123
|
|
|
|
bar{baz="qwe"} 4.34
|
2024-03-04 00:49:26 +01:00
|
|
|
`, `bar:1m_increase{baz="qwe"} 0
|
|
|
|
foo:1m_increase 0
|
lib/streamaggr: huge pile of changes
- Reduce memory usage by up to 5x when de-duplicating samples across big number of time series.
- Reduce memory usage by up to 5x when aggregating across big number of output time series.
- Add lib/promutils.LabelsCompressor, which is going to be used by other VictoriaMetrics components
for reducing memory usage for marshaled []prompbmarshal.Label.
- Add `dedup_interval` option at aggregation config, which allows setting individual
deduplication intervals per each aggregation.
- Add `keep_metric_names` option at aggregation config, which allows keeping the original
metric names in the output samples.
- Add `unique_samples` output, which counts the number of unique sample values.
- Add `increase_prometheus` and `total_prometheus` outputs, which ignore the first sample
per each newly encountered time series.
- Use 64-bit hashes instead of marshaled labels as map keys when calculating `count_series` output.
This makes obsolete https://github.com/VictoriaMetrics/VictoriaMetrics/pull/5579
- Expose various metrics, which may help debugging stream aggregation:
- vm_streamaggr_dedup_state_size_bytes - the size of data structures responsible for deduplication
- vm_streamaggr_dedup_state_items_count - the number of items in the deduplication data structures
- vm_streamaggr_labels_compressor_size_bytes - the size of labels compressor data structures
- vm_streamaggr_labels_compressor_items_count - the number of entries in the labels compressor
- vm_streamaggr_flush_duration_seconds - a histogram, which shows the duration of stream aggregation flushes
- vm_streamaggr_dedup_flush_duration_seconds - a histogram, which shows the duration of deduplication flushes
- vm_streamaggr_flush_timeouts_total - counter for timed out stream aggregation flushes,
which took longer than the configured interval
- vm_streamaggr_dedup_flush_timeouts_total - counter for timed out deduplication flushes,
which took longer than the configured dedup_interval
- Actualize docs/stream-aggregation.md
The memory usage reduction increases CPU usage during stream aggregation by up to 30%.
This commit is based on https://github.com/VictoriaMetrics/VictoriaMetrics/pull/5850
Updates https://github.com/VictoriaMetrics/VictoriaMetrics/issues/5898
2024-03-02 01:42:26 +01:00
|
|
|
`, "11")
|
|
|
|
|
|
|
|
// increase_prometheus output for non-repeated series
|
|
|
|
f(`
|
|
|
|
- interval: 1m
|
|
|
|
outputs: [increase_prometheus]
|
|
|
|
`, `
|
|
|
|
foo 123
|
|
|
|
bar{baz="qwe"} 4.34
|
2024-05-08 13:11:30 +02:00
|
|
|
`, `bar:1m_increase_prometheus{baz="qwe"} 0
|
|
|
|
foo:1m_increase_prometheus 0
|
2023-07-25 01:44:09 +02:00
|
|
|
`, "11")
|
2023-01-04 07:19:18 +01:00
|
|
|
|
|
|
|
// increase output for repeated series
|
|
|
|
f(`
|
|
|
|
- interval: 1m
|
|
|
|
outputs: [increase]
|
|
|
|
`, `
|
|
|
|
foo 123
|
|
|
|
bar{baz="qwe"} 1.32
|
|
|
|
bar{baz="qwe"} 4.34
|
|
|
|
bar{baz="qwe"} 2
|
|
|
|
foo{baz="qwe"} -5
|
|
|
|
bar{baz="qwer"} 343
|
|
|
|
bar{baz="qwer"} 344
|
|
|
|
foo{baz="qwe"} 10
|
2024-03-04 00:49:26 +01:00
|
|
|
`, `bar:1m_increase{baz="qwe"} 5.02
|
|
|
|
bar:1m_increase{baz="qwer"} 1
|
|
|
|
foo:1m_increase 0
|
|
|
|
foo:1m_increase{baz="qwe"} 15
|
lib/streamaggr: huge pile of changes
- Reduce memory usage by up to 5x when de-duplicating samples across big number of time series.
- Reduce memory usage by up to 5x when aggregating across big number of output time series.
- Add lib/promutils.LabelsCompressor, which is going to be used by other VictoriaMetrics components
for reducing memory usage for marshaled []prompbmarshal.Label.
- Add `dedup_interval` option at aggregation config, which allows setting individual
deduplication intervals per each aggregation.
- Add `keep_metric_names` option at aggregation config, which allows keeping the original
metric names in the output samples.
- Add `unique_samples` output, which counts the number of unique sample values.
- Add `increase_prometheus` and `total_prometheus` outputs, which ignore the first sample
per each newly encountered time series.
- Use 64-bit hashes instead of marshaled labels as map keys when calculating `count_series` output.
This makes obsolete https://github.com/VictoriaMetrics/VictoriaMetrics/pull/5579
- Expose various metrics, which may help debugging stream aggregation:
- vm_streamaggr_dedup_state_size_bytes - the size of data structures responsible for deduplication
- vm_streamaggr_dedup_state_items_count - the number of items in the deduplication data structures
- vm_streamaggr_labels_compressor_size_bytes - the size of labels compressor data structures
- vm_streamaggr_labels_compressor_items_count - the number of entries in the labels compressor
- vm_streamaggr_flush_duration_seconds - a histogram, which shows the duration of stream aggregation flushes
- vm_streamaggr_dedup_flush_duration_seconds - a histogram, which shows the duration of deduplication flushes
- vm_streamaggr_flush_timeouts_total - counter for timed out stream aggregation flushes,
which took longer than the configured interval
- vm_streamaggr_dedup_flush_timeouts_total - counter for timed out deduplication flushes,
which took longer than the configured dedup_interval
- Actualize docs/stream-aggregation.md
The memory usage reduction increases CPU usage during stream aggregation by up to 30%.
This commit is based on https://github.com/VictoriaMetrics/VictoriaMetrics/pull/5850
Updates https://github.com/VictoriaMetrics/VictoriaMetrics/issues/5898
2024-03-02 01:42:26 +01:00
|
|
|
`, "11111111")
|
|
|
|
|
|
|
|
// increase_prometheus output for repeated series
|
|
|
|
f(`
|
|
|
|
- interval: 1m
|
|
|
|
outputs: [increase_prometheus]
|
|
|
|
`, `
|
|
|
|
foo 123
|
|
|
|
bar{baz="qwe"} 1.32
|
|
|
|
bar{baz="qwe"} 4.34
|
|
|
|
bar{baz="qwe"} 2
|
|
|
|
foo{baz="qwe"} -5
|
|
|
|
bar{baz="qwer"} 343
|
|
|
|
bar{baz="qwer"} 344
|
|
|
|
foo{baz="qwe"} 10
|
2024-05-08 13:11:30 +02:00
|
|
|
`, `bar:1m_increase_prometheus{baz="qwe"} 5.02
|
|
|
|
bar:1m_increase_prometheus{baz="qwer"} 1
|
|
|
|
foo:1m_increase_prometheus 0
|
|
|
|
foo:1m_increase_prometheus{baz="qwe"} 15
|
2023-07-25 01:44:09 +02:00
|
|
|
`, "11111111")
|
2024-03-04 00:49:26 +01:00
|
|
|
|
2023-01-04 07:19:18 +01:00
|
|
|
// multiple aggregate configs
|
|
|
|
f(`
|
|
|
|
- interval: 1m
|
|
|
|
outputs: [count_series, sum_samples]
|
|
|
|
- interval: 5m
|
|
|
|
by: [bar]
|
|
|
|
outputs: [sum_samples]
|
|
|
|
`, `
|
|
|
|
foo 1
|
|
|
|
foo{bar="baz"} 2
|
|
|
|
foo 3.3
|
|
|
|
`, `foo:1m_count_series 1
|
|
|
|
foo:1m_count_series{bar="baz"} 1
|
|
|
|
foo:1m_sum_samples 4.3
|
|
|
|
foo:1m_sum_samples{bar="baz"} 2
|
|
|
|
foo:5m_by_bar_sum_samples 4.3
|
|
|
|
foo:5m_by_bar_sum_samples{bar="baz"} 2
|
2023-07-25 01:44:09 +02:00
|
|
|
`, "111")
|
2023-01-04 07:19:18 +01:00
|
|
|
|
|
|
|
// min and max outputs
|
|
|
|
f(`
|
|
|
|
- interval: 1m
|
|
|
|
outputs: [min, max]
|
|
|
|
`, `
|
|
|
|
foo{abc="123"} 4
|
|
|
|
bar 5
|
|
|
|
foo{abc="123"} 8.5
|
|
|
|
foo{abc="456",de="fg"} 8
|
|
|
|
`, `bar:1m_max 5
|
|
|
|
bar:1m_min 5
|
|
|
|
foo:1m_max{abc="123"} 8.5
|
|
|
|
foo:1m_max{abc="456",de="fg"} 8
|
|
|
|
foo:1m_min{abc="123"} 4
|
|
|
|
foo:1m_min{abc="456",de="fg"} 8
|
2023-07-25 01:44:09 +02:00
|
|
|
`, "1111")
|
2023-01-04 07:19:18 +01:00
|
|
|
|
|
|
|
// avg output
|
|
|
|
f(`
|
|
|
|
- interval: 1m
|
|
|
|
outputs: [avg]
|
|
|
|
`, `
|
|
|
|
foo{abc="123"} 4
|
|
|
|
bar 5
|
|
|
|
foo{abc="123"} 8.5
|
|
|
|
foo{abc="456",de="fg"} 8
|
|
|
|
`, `bar:1m_avg 5
|
|
|
|
foo:1m_avg{abc="123"} 6.25
|
|
|
|
foo:1m_avg{abc="456",de="fg"} 8
|
2023-07-25 01:44:09 +02:00
|
|
|
`, "1111")
|
2023-01-04 07:19:18 +01:00
|
|
|
|
|
|
|
// stddev output
|
|
|
|
f(`
|
|
|
|
- interval: 1m
|
|
|
|
outputs: [stddev]
|
|
|
|
`, `
|
|
|
|
foo{abc="123"} 4
|
|
|
|
bar 5
|
|
|
|
foo{abc="123"} 8.5
|
|
|
|
foo{abc="456",de="fg"} 8
|
|
|
|
`, `bar:1m_stddev 0
|
|
|
|
foo:1m_stddev{abc="123"} 2.25
|
|
|
|
foo:1m_stddev{abc="456",de="fg"} 0
|
2023-07-25 01:44:09 +02:00
|
|
|
`, "1111")
|
2023-01-04 07:19:18 +01:00
|
|
|
|
|
|
|
// stdvar output
|
|
|
|
f(`
|
|
|
|
- interval: 1m
|
|
|
|
outputs: [stdvar]
|
|
|
|
`, `
|
|
|
|
foo{abc="123"} 4
|
|
|
|
bar 5
|
|
|
|
foo{abc="123"} 8.5
|
|
|
|
foo{abc="456",de="fg"} 8
|
|
|
|
`, `bar:1m_stdvar 0
|
|
|
|
foo:1m_stdvar{abc="123"} 5.0625
|
|
|
|
foo:1m_stdvar{abc="456",de="fg"} 0
|
2023-07-25 01:44:09 +02:00
|
|
|
`, "1111")
|
2023-01-04 07:19:18 +01:00
|
|
|
|
|
|
|
// histogram_bucket output
|
|
|
|
f(`
|
|
|
|
- interval: 1m
|
|
|
|
outputs: [histogram_bucket]
|
|
|
|
`, `
|
|
|
|
cpu_usage{cpu="1"} 12.5
|
|
|
|
cpu_usage{cpu="1"} 13.3
|
|
|
|
cpu_usage{cpu="1"} 13
|
|
|
|
cpu_usage{cpu="1"} 12
|
|
|
|
cpu_usage{cpu="1"} 14
|
|
|
|
cpu_usage{cpu="1"} 25
|
|
|
|
cpu_usage{cpu="2"} 90
|
|
|
|
`, `cpu_usage:1m_histogram_bucket{cpu="1",vmrange="1.136e+01...1.292e+01"} 2
|
|
|
|
cpu_usage:1m_histogram_bucket{cpu="1",vmrange="1.292e+01...1.468e+01"} 3
|
|
|
|
cpu_usage:1m_histogram_bucket{cpu="1",vmrange="2.448e+01...2.783e+01"} 1
|
|
|
|
cpu_usage:1m_histogram_bucket{cpu="2",vmrange="8.799e+01...1.000e+02"} 1
|
2023-07-25 01:44:09 +02:00
|
|
|
`, "1111111")
|
2023-01-04 07:19:18 +01:00
|
|
|
|
|
|
|
// histogram_bucket output without cpu
|
|
|
|
f(`
|
|
|
|
- interval: 1m
|
|
|
|
without: [cpu]
|
|
|
|
outputs: [histogram_bucket]
|
|
|
|
`, `
|
|
|
|
cpu_usage{cpu="1"} 12.5
|
|
|
|
cpu_usage{cpu="1"} 13.3
|
|
|
|
cpu_usage{cpu="1"} 13
|
|
|
|
cpu_usage{cpu="1"} 12
|
|
|
|
cpu_usage{cpu="1"} 14
|
|
|
|
cpu_usage{cpu="1"} 25
|
|
|
|
cpu_usage{cpu="2"} 90
|
|
|
|
`, `cpu_usage:1m_without_cpu_histogram_bucket{vmrange="1.136e+01...1.292e+01"} 2
|
|
|
|
cpu_usage:1m_without_cpu_histogram_bucket{vmrange="1.292e+01...1.468e+01"} 3
|
|
|
|
cpu_usage:1m_without_cpu_histogram_bucket{vmrange="2.448e+01...2.783e+01"} 1
|
|
|
|
cpu_usage:1m_without_cpu_histogram_bucket{vmrange="8.799e+01...1.000e+02"} 1
|
2023-07-25 01:44:09 +02:00
|
|
|
`, "1111111")
|
2023-01-04 07:19:18 +01:00
|
|
|
|
|
|
|
// quantiles output
|
|
|
|
f(`
|
|
|
|
- interval: 1m
|
|
|
|
outputs: ["quantiles(0, 0.5, 1)"]
|
|
|
|
`, `
|
|
|
|
cpu_usage{cpu="1"} 12.5
|
|
|
|
cpu_usage{cpu="1"} 13.3
|
|
|
|
cpu_usage{cpu="1"} 13
|
|
|
|
cpu_usage{cpu="1"} 12
|
|
|
|
cpu_usage{cpu="1"} 14
|
|
|
|
cpu_usage{cpu="1"} 25
|
|
|
|
cpu_usage{cpu="2"} 90
|
|
|
|
`, `cpu_usage:1m_quantiles{cpu="1",quantile="0"} 12
|
|
|
|
cpu_usage:1m_quantiles{cpu="1",quantile="0.5"} 13.3
|
|
|
|
cpu_usage:1m_quantiles{cpu="1",quantile="1"} 25
|
|
|
|
cpu_usage:1m_quantiles{cpu="2",quantile="0"} 90
|
|
|
|
cpu_usage:1m_quantiles{cpu="2",quantile="0.5"} 90
|
|
|
|
cpu_usage:1m_quantiles{cpu="2",quantile="1"} 90
|
2023-07-25 01:44:09 +02:00
|
|
|
`, "1111111")
|
2023-01-04 07:19:18 +01:00
|
|
|
|
|
|
|
// quantiles output without cpu
|
|
|
|
f(`
|
|
|
|
- interval: 1m
|
|
|
|
without: [cpu]
|
|
|
|
outputs: ["quantiles(0, 0.5, 1)"]
|
|
|
|
`, `
|
|
|
|
cpu_usage{cpu="1"} 12.5
|
|
|
|
cpu_usage{cpu="1"} 13.3
|
|
|
|
cpu_usage{cpu="1"} 13
|
|
|
|
cpu_usage{cpu="1"} 12
|
|
|
|
cpu_usage{cpu="1"} 14
|
|
|
|
cpu_usage{cpu="1"} 25
|
|
|
|
cpu_usage{cpu="2"} 90
|
|
|
|
`, `cpu_usage:1m_without_cpu_quantiles{quantile="0"} 12
|
|
|
|
cpu_usage:1m_without_cpu_quantiles{quantile="0.5"} 13.3
|
|
|
|
cpu_usage:1m_without_cpu_quantiles{quantile="1"} 90
|
2023-07-25 01:44:09 +02:00
|
|
|
`, "1111111")
|
2023-11-29 09:03:04 +01:00
|
|
|
|
|
|
|
// append additional label
|
|
|
|
f(`
|
|
|
|
- interval: 1m
|
|
|
|
without: [abc]
|
|
|
|
outputs: [count_samples, sum_samples, count_series]
|
|
|
|
output_relabel_configs:
|
|
|
|
- action: replace_all
|
|
|
|
source_labels: [__name__]
|
|
|
|
regex: ":|_"
|
|
|
|
replacement: "-"
|
|
|
|
target_label: __name__
|
|
|
|
- action: drop
|
|
|
|
source_labels: [de]
|
|
|
|
regex: fg
|
|
|
|
- target_label: new_label
|
|
|
|
replacement: must_keep_metric_name
|
|
|
|
`, `
|
|
|
|
foo{abc="123"} 4
|
|
|
|
bar 5
|
2024-05-13 15:39:49 +02:00
|
|
|
foo{abc="123"} 8.5 10
|
2023-11-29 09:03:04 +01:00
|
|
|
foo{abc="456",de="fg"} 8
|
|
|
|
`, `bar-1m-without-abc-count-samples{new_label="must_keep_metric_name"} 1
|
|
|
|
bar-1m-without-abc-count-series{new_label="must_keep_metric_name"} 1
|
|
|
|
bar-1m-without-abc-sum-samples{new_label="must_keep_metric_name"} 5
|
|
|
|
foo-1m-without-abc-count-samples{new_label="must_keep_metric_name"} 2
|
|
|
|
foo-1m-without-abc-count-series{new_label="must_keep_metric_name"} 1
|
|
|
|
foo-1m-without-abc-sum-samples{new_label="must_keep_metric_name"} 12.5
|
2024-05-13 15:39:49 +02:00
|
|
|
`, "1111")
|
|
|
|
|
|
|
|
// test rate_sum and rate_avg
|
|
|
|
f(`
|
|
|
|
- interval: 1m
|
|
|
|
by: [cde]
|
|
|
|
outputs: [rate_sum, rate_avg]
|
|
|
|
`, `
|
|
|
|
foo{abc="123", cde="1"} 4
|
|
|
|
foo{abc="123", cde="1"} 8.5 10
|
|
|
|
foo{abc="456", cde="1"} 8
|
|
|
|
foo{abc="456", cde="1"} 10 10
|
|
|
|
`, `foo:1m_by_cde_rate_avg{cde="1"} 0.325
|
|
|
|
foo:1m_by_cde_rate_sum{cde="1"} 0.65
|
2023-11-29 09:03:04 +01:00
|
|
|
`, "1111")
|
2024-03-06 17:34:04 +01:00
|
|
|
|
2024-06-14 10:06:22 +02:00
|
|
|
// rate with duplicated events
|
|
|
|
f(`
|
|
|
|
- interval: 1m
|
|
|
|
by: [cde]
|
|
|
|
outputs: [rate_sum, rate_avg]
|
|
|
|
`, `
|
|
|
|
foo{abc="123", cde="1"} 4 10
|
|
|
|
foo{abc="123", cde="1"} 4 10
|
|
|
|
`, `foo:1m_by_cde_rate_avg{cde="1"} 0
|
|
|
|
foo:1m_by_cde_rate_sum{cde="1"} 0
|
|
|
|
`, "11")
|
|
|
|
|
2024-03-06 17:34:04 +01:00
|
|
|
// keep_metric_names
|
|
|
|
f(`
|
|
|
|
- interval: 1m
|
|
|
|
keep_metric_names: true
|
|
|
|
outputs: [count_samples]
|
|
|
|
`, `
|
|
|
|
foo{abc="123"} 4
|
|
|
|
bar 5
|
|
|
|
foo{abc="123"} 8.5
|
|
|
|
bar -34.3
|
|
|
|
foo{abc="456",de="fg"} 8
|
|
|
|
`, `bar 2
|
|
|
|
foo{abc="123"} 2
|
|
|
|
foo{abc="456",de="fg"} 1
|
|
|
|
`, "11111")
|
|
|
|
|
|
|
|
// drop_input_labels
|
|
|
|
f(`
|
|
|
|
- interval: 1m
|
|
|
|
drop_input_labels: [abc]
|
|
|
|
keep_metric_names: true
|
|
|
|
outputs: [count_samples]
|
|
|
|
`, `
|
|
|
|
foo{abc="123"} 4
|
|
|
|
bar 5
|
|
|
|
foo{abc="123"} 8.5
|
|
|
|
bar -34.3
|
|
|
|
foo{abc="456",de="fg"} 8
|
|
|
|
`, `bar 2
|
|
|
|
foo 2
|
|
|
|
foo{de="fg"} 1
|
|
|
|
`, "11111")
|
2023-01-04 07:19:18 +01:00
|
|
|
}
|
|
|
|
|
2023-01-25 18:14:49 +01:00
|
|
|
func TestAggregatorsWithDedupInterval(t *testing.T) {
|
2023-07-25 01:44:09 +02:00
|
|
|
f := func(config, inputMetrics, outputMetricsExpected, matchIdxsStrExpected string) {
|
2023-01-25 18:14:49 +01:00
|
|
|
t.Helper()
|
|
|
|
|
|
|
|
// Initialize Aggregators
|
|
|
|
var tssOutput []prompbmarshal.TimeSeries
|
|
|
|
var tssOutputLock sync.Mutex
|
|
|
|
pushFunc := func(tss []prompbmarshal.TimeSeries) {
|
|
|
|
tssOutputLock.Lock()
|
|
|
|
for _, ts := range tss {
|
|
|
|
labelsCopy := append([]prompbmarshal.Label{}, ts.Labels...)
|
|
|
|
samplesCopy := append([]prompbmarshal.Sample{}, ts.Samples...)
|
|
|
|
tssOutput = append(tssOutput, prompbmarshal.TimeSeries{
|
|
|
|
Labels: labelsCopy,
|
|
|
|
Samples: samplesCopy,
|
|
|
|
})
|
|
|
|
}
|
|
|
|
tssOutputLock.Unlock()
|
|
|
|
}
|
2024-03-04 04:42:55 +01:00
|
|
|
opts := &Options{
|
|
|
|
DedupInterval: 30 * time.Second,
|
|
|
|
FlushOnShutdown: true,
|
|
|
|
}
|
|
|
|
a, err := newAggregatorsFromData([]byte(config), pushFunc, opts)
|
2023-01-25 18:14:49 +01:00
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("cannot initialize aggregators: %s", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
// Push the inputMetrics to Aggregators
|
|
|
|
tssInput := mustParsePromMetrics(inputMetrics)
|
2023-07-25 01:44:09 +02:00
|
|
|
matchIdxs := a.Push(tssInput, nil)
|
2023-01-25 18:14:49 +01:00
|
|
|
a.MustStop()
|
|
|
|
|
2023-07-25 01:44:09 +02:00
|
|
|
// Verify matchIdxs equals to matchIdxsExpected
|
|
|
|
matchIdxsStr := ""
|
|
|
|
for _, v := range matchIdxs {
|
|
|
|
matchIdxsStr += strconv.Itoa(int(v))
|
|
|
|
}
|
|
|
|
if matchIdxsStr != matchIdxsStrExpected {
|
|
|
|
t.Fatalf("unexpected matchIdxs;\ngot\n%s\nwant\n%s", matchIdxsStr, matchIdxsStrExpected)
|
|
|
|
}
|
|
|
|
|
2023-01-25 18:14:49 +01:00
|
|
|
// Verify the tssOutput contains the expected metrics
|
|
|
|
tsStrings := make([]string, len(tssOutput))
|
|
|
|
for i, ts := range tssOutput {
|
|
|
|
tsStrings[i] = timeSeriesToString(ts)
|
|
|
|
}
|
|
|
|
sort.Strings(tsStrings)
|
|
|
|
outputMetrics := strings.Join(tsStrings, "")
|
|
|
|
if outputMetrics != outputMetricsExpected {
|
|
|
|
t.Fatalf("unexpected output metrics;\ngot\n%s\nwant\n%s", outputMetrics, outputMetricsExpected)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
f(`
|
|
|
|
- interval: 1m
|
|
|
|
outputs: [sum_samples]
|
|
|
|
`, `
|
|
|
|
foo 123
|
|
|
|
bar 567
|
|
|
|
`, `bar:1m_sum_samples 567
|
|
|
|
foo:1m_sum_samples 123
|
2023-07-25 01:44:09 +02:00
|
|
|
`, "11")
|
2023-01-25 18:14:49 +01:00
|
|
|
|
|
|
|
f(`
|
|
|
|
- interval: 1m
|
|
|
|
outputs: [sum_samples]
|
|
|
|
`, `
|
|
|
|
foo 123
|
|
|
|
bar{baz="qwe"} 1.32
|
|
|
|
bar{baz="qwe"} 4.34
|
|
|
|
bar{baz="qwe"} 2
|
|
|
|
foo{baz="qwe"} -5
|
|
|
|
bar{baz="qwer"} 343
|
|
|
|
bar{baz="qwer"} 344
|
|
|
|
foo{baz="qwe"} 10
|
2024-03-12 22:47:29 +01:00
|
|
|
`, `bar:1m_sum_samples{baz="qwe"} 4.34
|
2023-01-25 18:14:49 +01:00
|
|
|
bar:1m_sum_samples{baz="qwer"} 344
|
|
|
|
foo:1m_sum_samples 123
|
|
|
|
foo:1m_sum_samples{baz="qwe"} 10
|
2023-07-25 01:44:09 +02:00
|
|
|
`, "11111111")
|
2023-01-25 18:14:49 +01:00
|
|
|
}
|
|
|
|
|
2024-03-04 23:45:22 +01:00
|
|
|
func timeSeriessToString(tss []prompbmarshal.TimeSeries) string {
|
|
|
|
a := make([]string, len(tss))
|
|
|
|
for i, ts := range tss {
|
|
|
|
a[i] = timeSeriesToString(ts)
|
|
|
|
}
|
|
|
|
sort.Strings(a)
|
|
|
|
return strings.Join(a, "")
|
|
|
|
}
|
|
|
|
|
2023-01-04 07:19:18 +01:00
|
|
|
func timeSeriesToString(ts prompbmarshal.TimeSeries) string {
|
|
|
|
labelsString := promrelabel.LabelsToString(ts.Labels)
|
|
|
|
if len(ts.Samples) != 1 {
|
|
|
|
panic(fmt.Errorf("unexpected number of samples for %s: %d; want 1", labelsString, len(ts.Samples)))
|
|
|
|
}
|
|
|
|
return fmt.Sprintf("%s %v\n", labelsString, ts.Samples[0].Value)
|
|
|
|
}
|
|
|
|
|
|
|
|
func mustParsePromMetrics(s string) []prompbmarshal.TimeSeries {
|
|
|
|
var rows prometheus.Rows
|
|
|
|
errLogger := func(s string) {
|
|
|
|
panic(fmt.Errorf("unexpected error when parsing Prometheus metrics: %s", s))
|
|
|
|
}
|
|
|
|
rows.UnmarshalWithErrLogger(s, errLogger)
|
|
|
|
var tss []prompbmarshal.TimeSeries
|
2024-05-13 15:39:49 +02:00
|
|
|
now := time.Now().UnixMilli()
|
2023-01-04 07:19:18 +01:00
|
|
|
samples := make([]prompbmarshal.Sample, 0, len(rows.Rows))
|
|
|
|
for _, row := range rows.Rows {
|
|
|
|
labels := make([]prompbmarshal.Label, 0, len(row.Tags)+1)
|
|
|
|
labels = append(labels, prompbmarshal.Label{
|
|
|
|
Name: "__name__",
|
|
|
|
Value: row.Metric,
|
|
|
|
})
|
|
|
|
for _, tag := range row.Tags {
|
|
|
|
labels = append(labels, prompbmarshal.Label{
|
|
|
|
Name: tag.Key,
|
|
|
|
Value: tag.Value,
|
|
|
|
})
|
|
|
|
}
|
|
|
|
samples = append(samples, prompbmarshal.Sample{
|
|
|
|
Value: row.Value,
|
2024-05-13 15:39:49 +02:00
|
|
|
Timestamp: now + row.Timestamp,
|
2023-01-04 07:19:18 +01:00
|
|
|
})
|
|
|
|
ts := prompbmarshal.TimeSeries{
|
|
|
|
Labels: labels,
|
|
|
|
Samples: samples[len(samples)-1:],
|
|
|
|
}
|
|
|
|
tss = append(tss, ts)
|
|
|
|
}
|
|
|
|
return tss
|
|
|
|
}
|
2024-03-04 23:45:22 +01:00
|
|
|
|
|
|
|
func appendClonedTimeseries(dst, src []prompbmarshal.TimeSeries) []prompbmarshal.TimeSeries {
|
|
|
|
for _, ts := range src {
|
|
|
|
dst = append(dst, prompbmarshal.TimeSeries{
|
|
|
|
Labels: append(ts.Labels[:0:0], ts.Labels...),
|
|
|
|
Samples: append(ts.Samples[:0:0], ts.Samples...),
|
|
|
|
})
|
|
|
|
}
|
|
|
|
return dst
|
|
|
|
}
|