Skip to content

Commit bbb77d9

Browse files
jmichalek132Dylan-M
authored andcommitted
Prom rw exporter, rw2 generate metrics from written headers (open-telemetry#40866)
<!--Ex. Fixing a bug - Describe the bug and how this fixes the issue. Ex. Adding a feature - Explain what this achieves.--> #### Description Implements metrics based on the written header in RW2 response as discussed here open-telemetry#40559 (comment) Review please @ArthurSens @dashpole @ywwg. <!-- Issue number (e.g. open-telemetry#1234) or full URL to issue, if applicable. --> #### Link to tracking issue Partially implements open-telemetry#33661 (when merging PR please don't close the tracing issue) <!--Describe what testing was performed and which tests were added.--> #### Testing * [x] e2e ran with prometheus locally ![Screenshot 2025-06-23 at 18 38 39](https://github.com/user-attachments/assets/15687f8c-b036-483d-aeeb-c9689f0e0128)
1 parent 7901924 commit bbb77d9

File tree

8 files changed

+213
-7
lines changed

8 files changed

+213
-7
lines changed
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
# Use this changelog template to create an entry for release notes.
2+
3+
# One of 'breaking', 'deprecation', 'new_component', 'enhancement', 'bug_fix'
4+
change_type: enhancement
5+
6+
# The name of the component, or a single word describing the area of concern, (e.g. filelogreceiver)
7+
component: prometheusremotewriteexproter
8+
9+
# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`).
10+
note: |
11+
Adds additional metrics to the Prometheus Remote Write Exporter when RW2 enable. The new metrics are:
12+
- `otelcol_exporter_prometheusremotewrite_written_samples`: Number of Prometheus Samples that were successfully written to the remote write endpoint.
13+
- `otelcol_exporter_prometheusremotewrite_written_histograms`: Number of Prometheus Histograms that were successfully written to the remote write endpoint.
14+
- `otelcol_exporter_prometheusremotewrite_written_exemplars`: Number of Prometheus Exemplars that were successfully written to the remote write endpoint.
15+
16+
# Mandatory: One or more tracking issues related to the change. You can use the PR number here if no issue exists.
17+
issues: [33661]
18+
19+
# (Optional) One or more lines of additional information to render under the primary note.
20+
# These lines will be padded with 2 spaces and then inserted directly into the document.
21+
# Use pipe (|) for multiline entries.
22+
subtext:
23+
24+
# If your change doesn't affect end users or the exported elements of any package,
25+
# you should instead start your pull request title with [chore] or use the "Skip Changelog" label.
26+
# Optional: The change log or logs in which this entry should be included.
27+
# e.g. '[user]' or '[user, api]'
28+
# Include 'user' if the change is relevant to end users.
29+
# Include 'api' if there is a change to a library API.
30+
# Default: '[user]'
31+
change_logs: []

exporter/prometheusremotewriteexporter/documentation.md

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,3 +109,27 @@ Number of WAL writes that failed
109109
| Unit | Metric Type | Value Type | Monotonic |
110110
| ---- | ----------- | ---------- | --------- |
111111
| 1 | Sum | Int | true |
112+
113+
### otelcol_exporter_prometheusremotewrite_written_exemplars
114+
115+
Number of Prometheus Exemplars that were successfully written to the remote write endpoint (only available when using remote write v2)
116+
117+
| Unit | Metric Type | Value Type | Monotonic |
118+
| ---- | ----------- | ---------- | --------- |
119+
| {exemplar} | Sum | Int | true |
120+
121+
### otelcol_exporter_prometheusremotewrite_written_histograms
122+
123+
Number of Prometheus Histograms that were successfully written to the remote write endpoint (only available when using remote write v2)
124+
125+
| Unit | Metric Type | Value Type | Monotonic |
126+
| ---- | ----------- | ---------- | --------- |
127+
| {histogram} | Sum | Int | true |
128+
129+
### otelcol_exporter_prometheusremotewrite_written_samples
130+
131+
Number of Prometheus Samples that were successfully written to the remote write endpoint (only available when using remote write v2)
132+
133+
| Unit | Metric Type | Value Type | Monotonic |
134+
| ---- | ----------- | ---------- | --------- |
135+
| {sample} | Sum | Int | true |

exporter/prometheusremotewriteexporter/exporter.go

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,9 @@ type prwTelemetry interface {
4242
recordTranslatedTimeSeries(ctx context.Context, numTS int)
4343
recordRemoteWriteSentBatch(ctx context.Context)
4444
setNumberConsumer(ctx context.Context, n int64)
45+
recordWrittenSamples(ctx context.Context, numSamples int64)
46+
recordWrittenHistograms(ctx context.Context, numHistograms int64)
47+
recordWrittenExemplars(ctx context.Context, numExemplars int64)
4548
}
4649

4750
type prwTelemetryOtel struct {
@@ -65,6 +68,18 @@ func (p *prwTelemetryOtel) recordTranslatedTimeSeries(ctx context.Context, numTS
6568
p.telemetryBuilder.ExporterPrometheusremotewriteTranslatedTimeSeries.Add(ctx, int64(numTS), metric.WithAttributes(p.otelAttrs...))
6669
}
6770

71+
func (p *prwTelemetryOtel) recordWrittenSamples(ctx context.Context, numSamples int64) {
72+
p.telemetryBuilder.ExporterPrometheusremotewriteWrittenSamples.Add(ctx, numSamples, metric.WithAttributes(p.otelAttrs...))
73+
}
74+
75+
func (p *prwTelemetryOtel) recordWrittenHistograms(ctx context.Context, numHistograms int64) {
76+
p.telemetryBuilder.ExporterPrometheusremotewriteWrittenHistograms.Add(ctx, numHistograms, metric.WithAttributes(p.otelAttrs...))
77+
}
78+
79+
func (p *prwTelemetryOtel) recordWrittenExemplars(ctx context.Context, numExemplars int64) {
80+
p.telemetryBuilder.ExporterPrometheusremotewriteWrittenExemplars.Add(ctx, numExemplars, metric.WithAttributes(p.otelAttrs...))
81+
}
82+
6883
type buffer struct {
6984
protobuf *proto.Buffer
7085
snappy []byte
@@ -421,13 +436,7 @@ func (prwe *prwExporter) execute(ctx context.Context, buf *buffer) error {
421436
// implementation is not compliant with the specification. Reference:
422437
// https://prometheus.io/docs/specs/prw/remote_write_spec_2_0/#required-written-response-headers
423438
if enableSendingRW2FeatureGate.IsEnabled() && prwe.RemoteWriteProtoMsg == config.RemoteWriteProtoMsgV2 {
424-
samplesWritten := resp.Header.Get("X-Prometheus-Remote-Write-Samples-Written")
425-
if samplesWritten == "" {
426-
prwe.settings.Logger.Warn(
427-
"X-Prometheus-Remote-Write-Samples-Written header is missing from the response, suggesting that the endpoint doesn't support RW2 and might be silently dropping data.",
428-
zap.String("url", resp.Request.URL.String()),
429-
)
430-
}
439+
prwe.handleWrittenHeaders(ctx, resp)
431440
}
432441

433442
// 2xx status code is considered a success

exporter/prometheusremotewriteexporter/exporter_v2.go

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ package prometheusremotewriteexporter // import "github.com/open-telemetry/opent
66
import (
77
"context"
88
"math"
9+
"net/http"
10+
"strconv"
911
"sync"
1012

1113
writev2 "github.com/prometheus/prometheus/prompb/io/prometheus/write/v2"
@@ -104,3 +106,41 @@ func (prwe *prwExporter) handleExportV2(ctx context.Context, symbolsTable writev
104106

105107
return prwe.exportV2(ctx, requests)
106108
}
109+
110+
func (prwe *prwExporter) handleHeader(ctx context.Context, resp *http.Response, headerName string, metricType string, recordFunc func(context.Context, int64)) {
111+
headerValue := resp.Header.Get(headerName)
112+
if headerValue == "" {
113+
prwe.settings.Logger.Warn(
114+
headerName+" header is missing from the response, suggesting that the endpoint doesn't support RW2 and might be silently dropping data.",
115+
zap.String("url", resp.Request.URL.String()),
116+
)
117+
return
118+
}
119+
120+
value, err := strconv.ParseInt(headerValue, 10, 64)
121+
if err != nil {
122+
prwe.settings.Logger.Warn(
123+
"Failed to convert "+headerName+" header to int64, not counting "+metricType+" written",
124+
zap.String("url", resp.Request.URL.String()),
125+
)
126+
return
127+
}
128+
recordFunc(ctx, value)
129+
}
130+
131+
func (prwe *prwExporter) handleWrittenHeaders(ctx context.Context, resp *http.Response) {
132+
prwe.handleHeader(ctx, resp,
133+
"X-Prometheus-Remote-Write-Samples-Written",
134+
"samples",
135+
prwe.telemetry.recordWrittenSamples)
136+
137+
prwe.handleHeader(ctx, resp,
138+
"X-Prometheus-Remote-Write-Histograms-Written",
139+
"histograms",
140+
prwe.telemetry.recordWrittenHistograms)
141+
142+
prwe.handleHeader(ctx, resp,
143+
"X-Prometheus-Remote-Write-Exemplars-Written",
144+
"exemplars",
145+
prwe.telemetry.recordWrittenExemplars)
146+
}

exporter/prometheusremotewriteexporter/internal/metadata/generated_telemetry.go

Lines changed: 21 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

exporter/prometheusremotewriteexporter/internal/metadatatest/generated_telemetrytest.go

Lines changed: 48 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

exporter/prometheusremotewriteexporter/internal/metadatatest/generated_telemetrytest_test.go

Lines changed: 12 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

exporter/prometheusremotewriteexporter/metadata.yaml

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,27 @@ telemetry:
3232
sum:
3333
value_type: int
3434
monotonic: true
35+
exporter_prometheusremotewrite_written_samples:
36+
enabled: true
37+
description: Number of Prometheus Samples that were successfully written to the remote write endpoint (only available when using remote write v2)
38+
unit: "{sample}"
39+
sum:
40+
value_type: int
41+
monotonic: true
42+
exporter_prometheusremotewrite_written_histograms:
43+
enabled: true
44+
description: Number of Prometheus Histograms that were successfully written to the remote write endpoint (only available when using remote write v2)
45+
unit: "{histogram}"
46+
sum:
47+
value_type: int
48+
monotonic: true
49+
exporter_prometheusremotewrite_written_exemplars:
50+
enabled: true
51+
description: Number of Prometheus Exemplars that were successfully written to the remote write endpoint (only available when using remote write v2)
52+
unit: "{exemplar}"
53+
sum:
54+
value_type: int
55+
monotonic: true
3556
exporter_prometheusremotewrite_consumers:
3657
enabled: true
3758
description: Number of configured workers to use to fan out the outgoing requests

0 commit comments

Comments
 (0)