Skip to content

Commit 74d424b

Browse files
ptodevkgeckhart
andauthored
feat: support metadata in Remote Write V2 (#5045)
* Support metadata in Remote Write V2 * Apply suggestions from code review Co-authored-by: Kyle Eckhart <kgeckhart@users.noreply.github.com> * Fix lint issues * PR review fixes * Batch the test samples into a singe remote write request as soon as possible. This reduces flakyness and reduce test times. --------- Co-authored-by: Kyle Eckhart <kgeckhart@users.noreply.github.com>
1 parent 2e48aff commit 74d424b

File tree

20 files changed

+1360
-295
lines changed

20 files changed

+1360
-295
lines changed

docs/sources/reference/components/prometheus/prometheus.remote_write.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -292,6 +292,7 @@ In those cases, exported fields are kept at their last healthy values.
292292
* `prometheus_remote_storage_shards` (gauge): The number of shards used for concurrent delivery of metrics to an endpoint.
293293
* `prometheus_remote_write_wal_exemplars_appended_total` (counter): Total number of exemplars appended to the WAL.
294294
* `prometheus_remote_write_wal_out_of_order_samples_total` (counter): Total number of out of order samples ingestion failed attempts.
295+
* `prometheus_remote_write_wal_metadata_updates_total` (counter): Total number of metadata updates sent through the WAL.
295296
* `prometheus_remote_write_wal_samples_appended_total` (counter): Total number of samples appended to the WAL.
296297
* `prometheus_remote_write_wal_storage_active_series` (gauge): Current number of active series being tracked by the WAL.
297298
* `prometheus_remote_write_wal_storage_created_series_total` (counter): Total number of created series appended to the WAL.

docs/sources/reference/components/prometheus/prometheus.scrape.md

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -91,8 +91,14 @@ You can use the following arguments with `prometheus.scrape`:
9191
> **EXPERIMENTAL**: The `honor_metadata` argument is an [experimental][] feature.
9292
> Enabling it may increase resource consumption, particularly if a lot of metrics with different names are ingested.
9393
> Not all downstream components may be compatible with Prometheus metadata yet.
94-
> For example, `otelcol.receiver.prometheus` may work, but `prometheus.remote_write` may not.
95-
> Support for more components will be added soon.
94+
> Currently, the compatible components are:
95+
>
96+
> * `otelcol.receiver.prometheus`
97+
> * `prometheus.remote_write` only when configured for Remote Write v2.
98+
> * `prometheus.write_queue`
99+
>
100+
> Metadata support for Remote Write v1 in `prometheus.remote_write` will be added soon.
101+
>
96102
> Experimental features are subject to frequent breaking changes, and may be removed with no equivalent replacement.
97103
> To enable and use an experimental feature, you must set the `stability.level` [flag][] to `experimental`.
98104

internal/cmd/integration-tests/common/metadata_asserts.go

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,12 @@ import (
1010
"golang.org/x/exp/maps"
1111
)
1212

13-
// Default metrics metadata
14-
var PromDefaultMetricMetadata = map[string]Metadata{
13+
// Default metrics metadata that the prometheus.write_queue component creates in Mimir.
14+
// For some reason it causes _bucket, _count, and _sum metrics to be visible on Mimir's /metadata endpoint.
15+
// This is not normal. When Prometheus or Alloy's prometheus.remote_write components send metrics to Mimir,
16+
// only the metric family is visible on Mimir's /metadata endpoint.
17+
// TODO: Look into why the write_queue components causes Mimir to behave this way.
18+
var WriteQueueDefaultMetricMetadata = map[string]Metadata{
1519
"golang_counter": {Type: "counter", Help: "The counter description string"},
1620
"golang_gauge": {Type: "gauge", Help: "The gauge description string"},
1721
"golang_histogram_bucket": {Type: "histogram", Help: "The histogram description string"},
@@ -23,11 +27,8 @@ var PromDefaultMetricMetadata = map[string]Metadata{
2327
"golang_summary": {Type: "summary", Help: "The summary description string"},
2428
}
2529

26-
// Default metrics metadata for OTLP generated metrics.
27-
// When you send metrics to Mimir's OTLP endpoint,
28-
// Mimir doesn't generate metadata for
29-
// _bucket, _count, and _sum metrics of classic histograms.
30-
var OtlpDefaultMetricMetadata = map[string]Metadata{
30+
// Default metrics metadata that the prometheus.remote_write and otelcol.exporter.otlphttp components create in Mimir.
31+
var PromDefaultMetricMetadata = map[string]Metadata{
3132
"golang_counter": {Type: "counter", Help: "The counter description string"},
3233
"golang_gauge": {Type: "gauge", Help: "The gauge description string"},
3334
"golang_histogram": {Type: "histogram", Help: "The histogram description string"},

internal/cmd/integration-tests/docker-compose.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
name: alloy-integration-tests
22
services:
33
mimir:
4-
image: grafana/mimir:2.17.0
4+
image: grafana/mimir:3.0.0
55
volumes:
66
- ./configs/mimir:/etc/mimir-config
77
entrypoint:

internal/cmd/integration-tests/tests/otlp-metadata/otlp_metadata_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,8 @@ func TestOtlpMetadata(t *testing.T) {
2626

2727
// Make sure we got the expected metrics before checking metadata
2828
common.MimirMetricsTest(t, metadataTestMetrics, metadataTestHistogram, testName)
29-
expectedMetadata := make(map[string]common.Metadata, len(common.OtlpDefaultMetricMetadata)+len(common.PromDefaultNativeHistogramMetadata))
30-
for k, v := range common.OtlpDefaultMetricMetadata {
29+
expectedMetadata := make(map[string]common.Metadata, len(common.PromDefaultMetricMetadata)+len(common.PromDefaultNativeHistogramMetadata))
30+
for k, v := range common.PromDefaultMetricMetadata {
3131
expectedMetadata[toTestMetric(k)] = v
3232
}
3333
for k, v := range common.PromDefaultNativeHistogramMetadata {

internal/cmd/integration-tests/tests/prom-metadata/config.alloy

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,3 +30,30 @@ prometheus.write.queue "prom_metadata" {
3030
}
3131
}
3232
}
33+
34+
prometheus.scrape "prom_metadata_remote_write_v2" {
35+
targets = [
36+
{"__address__" = "prom-gen:9001"},
37+
]
38+
params = { "metric-prefix" = ["prom_metadata_remote_write_v2_"] }
39+
forward_to = [
40+
prometheus.remote_write.prom_metadata_remote_write_v2.receiver,
41+
]
42+
scrape_classic_histograms = true
43+
scrape_native_histograms = true
44+
scrape_interval = "1s"
45+
scrape_timeout = "500ms"
46+
// Required for metadata support
47+
honor_metadata = true
48+
}
49+
50+
prometheus.remote_write "prom_metadata_remote_write_v2" {
51+
external_labels = {
52+
test_name = "prom_metadata_remote_write_v2",
53+
}
54+
endpoint {
55+
url = "http://mimir:9009/api/v1/push"
56+
protobuf_message = "io.prometheus.write.v2.Request"
57+
send_native_histograms = true
58+
}
59+
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
package main
2+
3+
import (
4+
"fmt"
5+
"testing"
6+
7+
"github.com/grafana/alloy/internal/cmd/integration-tests/common"
8+
)
9+
10+
func TestPromMetadataRemoteWriteV2(t *testing.T) {
11+
testName := "prom_metadata_remote_write_v2"
12+
toTestMetric := func(metricName string) string {
13+
return fmt.Sprintf("%s_%s", testName, metricName)
14+
}
15+
16+
// Metadata queries cannot use a series matcher so the metrics all need to be unqiue to the test
17+
metadataTestMetrics := make([]string, 0, len(common.PromDefaultMetrics))
18+
for _, metricName := range common.PromDefaultMetrics {
19+
metadataTestMetrics = append(metadataTestMetrics, toTestMetric(metricName))
20+
}
21+
22+
// Make sure we got the expected metrics before checking metadata
23+
common.MimirMetricsTest(t, metadataTestMetrics, nil, testName)
24+
expectedMetadata := make(map[string]common.Metadata, len(common.PromDefaultMetricMetadata)+len(common.PromDefaultNativeHistogramMetadata))
25+
for k, v := range common.PromDefaultMetricMetadata {
26+
expectedMetadata[toTestMetric(k)] = v
27+
}
28+
common.MimirMetadataTest(t, expectedMetadata)
29+
}

internal/cmd/integration-tests/tests/prom-metadata/prom_metadata_writequeue_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,8 @@ func TestPromMetadataWriteQueue(t *testing.T) {
2626

2727
// Make sure we got the expected metrics before checking metadata
2828
common.MimirMetricsTest(t, metadataTestMetrics, metadataTestHistogram, testName)
29-
expectedMetadata := make(map[string]common.Metadata, len(common.PromDefaultMetricMetadata)+len(common.PromDefaultNativeHistogramMetadata))
30-
for k, v := range common.PromDefaultMetricMetadata {
29+
expectedMetadata := make(map[string]common.Metadata, len(common.WriteQueueDefaultMetricMetadata)+len(common.PromDefaultNativeHistogramMetadata))
30+
for k, v := range common.WriteQueueDefaultMetricMetadata {
3131
expectedMetadata[toTestMetric(k)] = v
3232
}
3333
for k, v := range common.PromDefaultNativeHistogramMetadata {

0 commit comments

Comments
 (0)