Skip to content

Commit 6e55752

Browse files
committed
[exporterhelper] Add data_type attribute to internal queue metric
Add data_type attribute to the internal otelcol_exporter_queue_size metric to report the type of data being processed. All other metrics have the data type reported as part of their names. We could've done the same for queue metrics, but that would introduce a significant breaking change. We want to avoid that until we have all the metrics standardized with OpenTelemetry semantic conventions.
1 parent 9ef6356 commit 6e55752

File tree

8 files changed

+69
-25
lines changed

8 files changed

+69
-25
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
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. otlpreceiver)
7+
component: exporterhelper
8+
9+
# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`).
10+
note: Add data_type attribute to `otelcol_exporter_queue_size` metric to report the type of data being processed.
11+
12+
# One or more tracking issues or pull requests related to the change
13+
issues: [9943]
14+
15+
# Optional: The change log or logs in which this entry should be included.
16+
# e.g. '[user]' or '[user, api]'
17+
# Include 'user' if the change is relevant to end users.
18+
# Include 'api' if there is a change to a library API.
19+
# Default: '[user]'
20+
change_logs: [user]

component/componenttest/obsreporttest.go

+13-1
Original file line numberDiff line numberDiff line change
@@ -66,14 +66,26 @@ func (tts *TestTelemetry) CheckExporterEnqueueFailedLogs(enqueueFailed int64) er
6666
return tts.prometheusChecker.checkExporterEnqueueFailed(tts.id, "log_records", enqueueFailed)
6767
}
6868

69+
func (tts *TestTelemetry) CheckExporterQueueSizeMetric(size int64) error {
70+
return tts.prometheusChecker.checkExporterQueueSize(tts.id, component.DataTypeMetrics, size)
71+
}
72+
73+
func (tts *TestTelemetry) CheckExporterQueueSizeTraces(size int64) error {
74+
return tts.prometheusChecker.checkExporterQueueSize(tts.id, component.DataTypeTraces, size)
75+
}
76+
77+
func (tts *TestTelemetry) CheckExporterQueueSizeLogs(size int64) error {
78+
return tts.prometheusChecker.checkExporterQueueSize(tts.id, component.DataTypeLogs, size)
79+
}
80+
6981
// CheckExporterLogs checks that for the current exported values for logs exporter metrics match given values.
7082
// When this function is called it is required to also call SetupTelemetry as first thing.
7183
func (tts *TestTelemetry) CheckExporterLogs(sentLogRecords, sendFailedLogRecords int64) error {
7284
return tts.prometheusChecker.checkExporterLogs(tts.id, sentLogRecords, sendFailedLogRecords)
7385
}
7486

7587
func (tts *TestTelemetry) CheckExporterMetricGauge(metric string, val int64) error {
76-
return tts.prometheusChecker.checkExporterMetricGauge(tts.id, metric, val)
88+
return tts.prometheusChecker.checkGauge(metric, val, attributesForExporterMetrics(tts.id))
7789
}
7890

7991
// CheckProcessorTraces checks that for the current exported values for trace exporter metrics match given values.

component/componenttest/otelprometheuschecker.go

+8-4
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,12 @@ func (pc *prometheusChecker) checkExporter(exporter component.ID, datatype strin
9292
return errs
9393
}
9494

95+
func (pc *prometheusChecker) checkExporterQueueSize(exporter component.ID, datatype component.DataType, size int64) error {
96+
attrs := attributesForExporterMetrics(exporter)
97+
attrs = append(attrs, attribute.String("data_type", datatype.String()))
98+
return pc.checkGauge("otelcol_exporter_queue_size", size, attrs)
99+
}
100+
95101
func (pc *prometheusChecker) checkExporterEnqueueFailed(exporter component.ID, datatype string, enqueueFailed int64) error {
96102
if enqueueFailed == 0 {
97103
return nil
@@ -100,10 +106,8 @@ func (pc *prometheusChecker) checkExporterEnqueueFailed(exporter component.ID, d
100106
return pc.checkCounter(fmt.Sprintf("exporter_enqueue_failed_%s", datatype), enqueueFailed, exporterAttrs)
101107
}
102108

103-
func (pc *prometheusChecker) checkExporterMetricGauge(exporter component.ID, metric string, val int64) error {
104-
exporterAttrs := attributesForExporterMetrics(exporter)
105-
106-
ts, err := pc.getMetric(metric, io_prometheus_client.MetricType_GAUGE, exporterAttrs)
109+
func (pc *prometheusChecker) checkGauge(metric string, val int64, attrs []attribute.KeyValue) error {
110+
ts, err := pc.getMetric(metric, io_prometheus_client.MetricType_GAUGE, attrs)
107111
if err != nil {
108112
return err
109113
}

exporter/exporterhelper/common.go

+3-3
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@ func WithQueue(config QueueSettings) Option {
110110
NumConsumers: config.NumConsumers,
111111
QueueSize: config.QueueSize,
112112
})
113-
o.queueSender = newQueueSender(q, o.set, config.NumConsumers, o.exportFailureMessage, o.obsrep.telemetryBuilder)
113+
o.queueSender = newQueueSender(q, o.set, config.NumConsumers, o.exportFailureMessage, o.obsrep)
114114
return nil
115115
}
116116
}
@@ -132,7 +132,7 @@ func WithRequestQueue(cfg exporterqueue.Config, queueFactory exporterqueue.Facto
132132
DataType: o.signal,
133133
ExporterSettings: o.set,
134134
}
135-
o.queueSender = newQueueSender(queueFactory(context.Background(), set, cfg), o.set, cfg.NumConsumers, o.exportFailureMessage, o.obsrep.telemetryBuilder)
135+
o.queueSender = newQueueSender(queueFactory(context.Background(), set, cfg), o.set, cfg.NumConsumers, o.exportFailureMessage, o.obsrep)
136136
return nil
137137
}
138138
}
@@ -250,7 +250,7 @@ type baseExporter struct {
250250
}
251251

252252
func newBaseExporter(set exporter.Settings, signal component.DataType, osf obsrepSenderFactory, options ...Option) (*baseExporter, error) {
253-
obsReport, err := NewObsReport(ObsReportSettings{ExporterID: set.ID, ExporterCreateSettings: set})
253+
obsReport, err := NewObsReport(ObsReportSettings{ExporterID: set.ID, ExporterCreateSettings: set, DataType: signal})
254254
if err != nil {
255255
return nil, err
256256
}

exporter/exporterhelper/obsexporter.go

+3-1
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ type ObsReport struct {
2626
level configtelemetry.Level
2727
spanNamePrefix string
2828
tracer trace.Tracer
29+
dataType component.DataType
2930

3031
otelAttrs []attribute.KeyValue
3132
telemetryBuilder *metadata.TelemetryBuilder
@@ -38,6 +39,7 @@ type ObsReport struct {
3839
type ObsReportSettings struct {
3940
ExporterID component.ID
4041
ExporterCreateSettings exporter.Settings
42+
DataType component.DataType
4143
}
4244

4345
// NewObsReport creates a new Exporter.
@@ -58,7 +60,7 @@ func newExporter(cfg ObsReportSettings) (*ObsReport, error) {
5860
level: cfg.ExporterCreateSettings.TelemetrySettings.MetricsLevel,
5961
spanNamePrefix: obsmetrics.ExporterPrefix + cfg.ExporterID.String(),
6062
tracer: cfg.ExporterCreateSettings.TracerProvider.Tracer(cfg.ExporterID.String()),
61-
63+
dataType: cfg.DataType,
6264
otelAttrs: []attribute.KeyValue{
6365
attribute.String(obsmetrics.ExporterKey, cfg.ExporterID.String()),
6466
},

exporter/exporterhelper/queue_sender.go

+13-12
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@ import (
1515

1616
"go.opentelemetry.io/collector/component"
1717
"go.opentelemetry.io/collector/exporter"
18-
"go.opentelemetry.io/collector/exporter/exporterhelper/internal/metadata"
1918
"go.opentelemetry.io/collector/exporter/exporterqueue"
2019
"go.opentelemetry.io/collector/exporter/internal/queue"
2120
"go.opentelemetry.io/collector/internal/obsreportconfig/obsmetrics"
@@ -74,18 +73,18 @@ type queueSender struct {
7473
traceAttribute attribute.KeyValue
7574
consumers *queue.Consumers[Request]
7675

77-
telemetryBuilder *metadata.TelemetryBuilder
78-
exporterID component.ID
76+
obsrep *ObsReport
77+
exporterID component.ID
7978
}
8079

8180
func newQueueSender(q exporterqueue.Queue[Request], set exporter.Settings, numConsumers int,
82-
exportFailureMessage string, telemetryBuilder *metadata.TelemetryBuilder) *queueSender {
81+
exportFailureMessage string, obsrep *ObsReport) *queueSender {
8382
qs := &queueSender{
84-
queue: q,
85-
numConsumers: numConsumers,
86-
traceAttribute: attribute.String(obsmetrics.ExporterKey, set.ID.String()),
87-
telemetryBuilder: telemetryBuilder,
88-
exporterID: set.ID,
83+
queue: q,
84+
numConsumers: numConsumers,
85+
traceAttribute: attribute.String(obsmetrics.ExporterKey, set.ID.String()),
86+
obsrep: obsrep,
87+
exporterID: set.ID,
8988
}
9089
consumeFunc := func(ctx context.Context, req Request) error {
9190
err := qs.nextSender.send(ctx, req)
@@ -105,10 +104,12 @@ func (qs *queueSender) Start(ctx context.Context, host component.Host) error {
105104
return err
106105
}
107106

108-
opts := metric.WithAttributeSet(attribute.NewSet(attribute.String(obsmetrics.ExporterKey, qs.exporterID.String())))
107+
dataTypeAttr := attribute.String(obsmetrics.DataTypeKey, qs.obsrep.dataType.String())
109108
return multierr.Append(
110-
qs.telemetryBuilder.InitExporterQueueSize(func() int64 { return int64(qs.queue.Size()) }, opts),
111-
qs.telemetryBuilder.InitExporterQueueCapacity(func() int64 { return int64(qs.queue.Capacity()) }, opts),
109+
qs.obsrep.telemetryBuilder.InitExporterQueueSize(func() int64 { return int64(qs.queue.Size()) },
110+
metric.WithAttributeSet(attribute.NewSet(qs.traceAttribute, dataTypeAttr))),
111+
qs.obsrep.telemetryBuilder.InitExporterQueueCapacity(func() int64 { return int64(qs.queue.Capacity()) },
112+
metric.WithAttributeSet(attribute.NewSet(qs.traceAttribute))),
112113
)
113114
}
114115

exporter/exporterhelper/queue_sender_test.go

+6-4
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@ import (
1818
"go.opentelemetry.io/collector/component/componenttest"
1919
"go.opentelemetry.io/collector/config/configretry"
2020
"go.opentelemetry.io/collector/exporter"
21-
"go.opentelemetry.io/collector/exporter/exporterhelper/internal/metadata"
2221
"go.opentelemetry.io/collector/exporter/exporterqueue"
2322
"go.opentelemetry.io/collector/exporter/exportertest"
2423
"go.opentelemetry.io/collector/exporter/internal/queue"
@@ -221,7 +220,7 @@ func TestQueuedRetry_QueueMetricsReported(t *testing.T) {
221220
for i := 0; i < 7; i++ {
222221
require.NoError(t, be.send(context.Background(), newErrorRequest()))
223222
}
224-
require.NoError(t, tt.CheckExporterMetricGauge("otelcol_exporter_queue_size", int64(7)))
223+
require.NoError(t, tt.CheckExporterQueueSizeMetric(int64(7)))
225224

226225
assert.NoError(t, be.Shutdown(context.Background()))
227226
}
@@ -426,9 +425,12 @@ func TestQueuedRetryPersistentEnabled_NoDataLossOnShutdown(t *testing.T) {
426425
func TestQueueSenderNoStartShutdown(t *testing.T) {
427426
queue := queue.NewBoundedMemoryQueue[Request](queue.MemoryQueueSettings[Request]{})
428427
set := exportertest.NewNopSettings()
429-
builder, err := metadata.NewTelemetryBuilder(set.TelemetrySettings)
428+
obsrep, err := NewObsReport(ObsReportSettings{
429+
ExporterID: exporterID,
430+
ExporterCreateSettings: exportertest.NewNopSettings(),
431+
})
430432
assert.NoError(t, err)
431-
qs := newQueueSender(queue, set, 1, "", builder)
433+
qs := newQueueSender(queue, set, 1, "", obsrep)
432434
assert.NoError(t, qs.Shutdown(context.Background()))
433435
}
434436

internal/obsreportconfig/obsmetrics/obs_exporter.go

+3
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,9 @@ const (
77
// ExporterKey used to identify exporters in metrics and traces.
88
ExporterKey = "exporter"
99

10+
// DataTypeKey used to identify the data type in the queue size metric.
11+
DataTypeKey = "data_type"
12+
1013
// SentSpansKey used to track spans sent by exporters.
1114
SentSpansKey = "sent_spans"
1215
// FailedToSendSpansKey used to track spans that failed to be sent by exporters.

0 commit comments

Comments
 (0)