@@ -20,20 +20,44 @@ import (
20
20
"go.opencensus.io/stats"
21
21
"go.opencensus.io/tag"
22
22
"go.opentelemetry.io/otel/attribute"
23
+ "go.opentelemetry.io/otel/metric"
24
+ "go.opentelemetry.io/otel/metric/instrument"
25
+ "go.opentelemetry.io/otel/metric/instrument/syncint64"
26
+ "go.opentelemetry.io/otel/metric/unit"
23
27
"go.opentelemetry.io/otel/trace"
28
+ "go.uber.org/zap"
24
29
25
30
"go.opentelemetry.io/collector/component"
26
31
"go.opentelemetry.io/collector/config"
27
32
"go.opentelemetry.io/collector/config/configtelemetry"
33
+ "go.opentelemetry.io/collector/featuregate"
34
+ "go.opentelemetry.io/collector/internal/obsreportconfig"
28
35
"go.opentelemetry.io/collector/internal/obsreportconfig/obsmetrics"
29
36
)
30
37
38
+ const (
39
+ exporterName = "exporter"
40
+
41
+ exporterScope = scopeName + nameSep + exporterName
42
+ )
43
+
31
44
// Exporter is a helper to add observability to a component.Exporter.
32
45
type Exporter struct {
33
46
level configtelemetry.Level
34
47
spanNamePrefix string
35
48
mutators []tag.Mutator
36
49
tracer trace.Tracer
50
+ meter metric.Meter
51
+ logger * zap.Logger
52
+
53
+ useOtelForMetrics bool
54
+ otelAttrs []attribute.KeyValue
55
+ sentSpans syncint64.Counter
56
+ failedToSendSpans syncint64.Counter
57
+ sentMetricPoints syncint64.Counter
58
+ failedToSendMetricPoints syncint64.Counter
59
+ sentLogRecords syncint64.Counter
60
+ failedToSendLogRecords syncint64.Counter
37
61
}
38
62
39
63
// ExporterSettings are settings for creating an Exporter.
@@ -44,12 +68,70 @@ type ExporterSettings struct {
44
68
45
69
// NewExporter creates a new Exporter.
46
70
func NewExporter (cfg ExporterSettings ) * Exporter {
47
- return & Exporter {
71
+ exp := & Exporter {
48
72
level : cfg .ExporterCreateSettings .TelemetrySettings .MetricsLevel ,
49
73
spanNamePrefix : obsmetrics .ExporterPrefix + cfg .ExporterID .String (),
50
74
mutators : []tag.Mutator {tag .Upsert (obsmetrics .TagKeyExporter , cfg .ExporterID .String (), tag .WithTTL (tag .TTLNoPropagation ))},
51
75
tracer : cfg .ExporterCreateSettings .TracerProvider .Tracer (cfg .ExporterID .String ()),
76
+ meter : cfg .ExporterCreateSettings .MeterProvider .Meter (exporterScope ),
77
+ logger : cfg .ExporterCreateSettings .Logger ,
78
+
79
+ useOtelForMetrics : featuregate .GetRegistry ().IsEnabled (obsreportconfig .UseOtelForInternalMetricsfeatureGateID ),
80
+ otelAttrs : []attribute.KeyValue {
81
+ attribute .String (obsmetrics .ExporterKey , cfg .ExporterID .String ()),
82
+ },
52
83
}
84
+ exp .createOtelMetrics ()
85
+
86
+ return exp
87
+ }
88
+
89
+ func (exp * Exporter ) createOtelMetrics () {
90
+ if ! exp .useOtelForMetrics {
91
+ return
92
+ }
93
+
94
+ var err error
95
+ handleError := func (metricName string , err error ) {
96
+ if err != nil {
97
+ exp .logger .Warn ("failed to create otel instrument" , zap .Error (err ), zap .String ("metric" , metricName ))
98
+ }
99
+ }
100
+ exp .sentSpans , err = exp .meter .SyncInt64 ().Counter (
101
+ obsmetrics .ExporterPrefix + obsmetrics .SentSpansKey ,
102
+ instrument .WithDescription ("Number of spans successfully sent to destination." ),
103
+ instrument .WithUnit (unit .Dimensionless ))
104
+ handleError (obsmetrics .ExporterPrefix + obsmetrics .SentSpansKey , err )
105
+
106
+ exp .failedToSendSpans , err = exp .meter .SyncInt64 ().Counter (
107
+ obsmetrics .ExporterPrefix + obsmetrics .FailedToSendSpansKey ,
108
+ instrument .WithDescription ("Number of spans in failed attempts to send to destination." ),
109
+ instrument .WithUnit (unit .Dimensionless ))
110
+ handleError (obsmetrics .ExporterPrefix + obsmetrics .FailedToSendSpansKey , err )
111
+
112
+ exp .sentMetricPoints , err = exp .meter .SyncInt64 ().Counter (
113
+ obsmetrics .ExporterPrefix + obsmetrics .SentMetricPointsKey ,
114
+ instrument .WithDescription ("Number of metric points successfully sent to destination." ),
115
+ instrument .WithUnit (unit .Dimensionless ))
116
+ handleError (obsmetrics .ExporterPrefix + obsmetrics .SentMetricPointsKey , err )
117
+
118
+ exp .failedToSendMetricPoints , err = exp .meter .SyncInt64 ().Counter (
119
+ obsmetrics .ExporterPrefix + obsmetrics .FailedToSendMetricPointsKey ,
120
+ instrument .WithDescription ("Number of metric points in failed attempts to send to destination." ),
121
+ instrument .WithUnit (unit .Dimensionless ))
122
+ handleError (obsmetrics .ExporterPrefix + obsmetrics .FailedToSendMetricPointsKey , err )
123
+
124
+ exp .sentLogRecords , err = exp .meter .SyncInt64 ().Counter (
125
+ obsmetrics .ExporterPrefix + obsmetrics .SentLogRecordsKey ,
126
+ instrument .WithDescription ("Number of log record successfully sent to destination." ),
127
+ instrument .WithUnit (unit .Dimensionless ))
128
+ handleError (obsmetrics .ExporterPrefix + obsmetrics .SentLogRecordsKey , err )
129
+
130
+ exp .failedToSendLogRecords , err = exp .meter .SyncInt64 ().Counter (
131
+ obsmetrics .ExporterPrefix + obsmetrics .FailedToSendLogRecordsKey ,
132
+ instrument .WithDescription ("Number of log records in failed attempts to send to destination." ),
133
+ instrument .WithUnit (unit .Dimensionless ))
134
+ handleError (obsmetrics .ExporterPrefix + obsmetrics .FailedToSendLogRecordsKey , err )
53
135
}
54
136
55
137
// StartTracesOp is called at the start of an Export operation.
@@ -62,7 +144,7 @@ func (exp *Exporter) StartTracesOp(ctx context.Context) context.Context {
62
144
// EndTracesOp completes the export operation that was started with StartTracesOp.
63
145
func (exp * Exporter ) EndTracesOp (ctx context.Context , numSpans int , err error ) {
64
146
numSent , numFailedToSend := toNumItems (numSpans , err )
65
- exp .recordMetrics (ctx , numSent , numFailedToSend , obsmetrics . ExporterSentSpans , obsmetrics . ExporterFailedToSendSpans )
147
+ exp .recordMetrics (ctx , config . TracesDataType , numSent , numFailedToSend )
66
148
endSpan (ctx , err , numSent , numFailedToSend , obsmetrics .SentSpansKey , obsmetrics .FailedToSendSpansKey )
67
149
}
68
150
@@ -77,7 +159,7 @@ func (exp *Exporter) StartMetricsOp(ctx context.Context) context.Context {
77
159
// StartMetricsOp.
78
160
func (exp * Exporter ) EndMetricsOp (ctx context.Context , numMetricPoints int , err error ) {
79
161
numSent , numFailedToSend := toNumItems (numMetricPoints , err )
80
- exp .recordMetrics (ctx , numSent , numFailedToSend , obsmetrics . ExporterSentMetricPoints , obsmetrics . ExporterFailedToSendMetricPoints )
162
+ exp .recordMetrics (ctx , config . MetricsDataType , numSent , numFailedToSend )
81
163
endSpan (ctx , err , numSent , numFailedToSend , obsmetrics .SentMetricPointsKey , obsmetrics .FailedToSendMetricPointsKey )
82
164
}
83
165
@@ -91,7 +173,7 @@ func (exp *Exporter) StartLogsOp(ctx context.Context) context.Context {
91
173
// EndLogsOp completes the export operation that was started with StartLogsOp.
92
174
func (exp * Exporter ) EndLogsOp (ctx context.Context , numLogRecords int , err error ) {
93
175
numSent , numFailedToSend := toNumItems (numLogRecords , err )
94
- exp .recordMetrics (ctx , numSent , numFailedToSend , obsmetrics . ExporterSentLogRecords , obsmetrics . ExporterFailedToSendLogRecords )
176
+ exp .recordMetrics (ctx , config . LogsDataType , numSent , numFailedToSend )
95
177
endSpan (ctx , err , numSent , numFailedToSend , obsmetrics .SentLogRecordsKey , obsmetrics .FailedToSendLogRecordsKey )
96
178
}
97
179
@@ -103,16 +185,54 @@ func (exp *Exporter) startOp(ctx context.Context, operationSuffix string) contex
103
185
return ctx
104
186
}
105
187
106
- func (exp * Exporter ) recordMetrics (ctx context.Context , numSent , numFailedToSend int64 , sentMeasure , failedToSendMeasure * stats. Int64Measure ) {
188
+ func (exp * Exporter ) recordMetrics (ctx context.Context , dataType config. DataType , numSent , numFailed int64 ) {
107
189
if exp .level == configtelemetry .LevelNone {
108
190
return
109
191
}
110
- // Ignore the error for now. This should not happen.
111
- if numFailedToSend > 0 {
112
- _ = stats .RecordWithTags (ctx , exp .mutators , sentMeasure .M (numSent ), failedToSendMeasure .M (numFailedToSend ))
192
+ if exp .useOtelForMetrics {
193
+ exp .recordWithOtel (ctx , dataType , numSent , numFailed )
113
194
} else {
114
- _ = stats .RecordWithTags (ctx , exp .mutators , sentMeasure .M (numSent ))
195
+ exp .recordWithOC (ctx , dataType , numSent , numFailed )
196
+ }
197
+ }
198
+
199
+ func (exp * Exporter ) recordWithOtel (ctx context.Context , dataType config.DataType , sent int64 , failed int64 ) {
200
+ var sentMeasure , failedMeasure syncint64.Counter
201
+ switch dataType {
202
+ case config .TracesDataType :
203
+ sentMeasure = exp .sentSpans
204
+ failedMeasure = exp .failedToSendSpans
205
+ case config .MetricsDataType :
206
+ sentMeasure = exp .sentMetricPoints
207
+ failedMeasure = exp .failedToSendMetricPoints
208
+ case config .LogsDataType :
209
+ sentMeasure = exp .sentLogRecords
210
+ failedMeasure = exp .failedToSendLogRecords
211
+ }
212
+
213
+ sentMeasure .Add (ctx , sent , exp .otelAttrs ... )
214
+ failedMeasure .Add (ctx , failed , exp .otelAttrs ... )
215
+ }
216
+
217
+ func (exp * Exporter ) recordWithOC (ctx context.Context , dataType config.DataType , sent int64 , failed int64 ) {
218
+ var sentMeasure , failedMeasure * stats.Int64Measure
219
+ switch dataType {
220
+ case config .TracesDataType :
221
+ sentMeasure = obsmetrics .ExporterSentSpans
222
+ failedMeasure = obsmetrics .ExporterFailedToSendSpans
223
+ case config .MetricsDataType :
224
+ sentMeasure = obsmetrics .ReceiverAcceptedMetricPoints
225
+ failedMeasure = obsmetrics .ExporterFailedToSendMetricPoints
226
+ case config .LogsDataType :
227
+ sentMeasure = obsmetrics .ReceiverAcceptedLogRecords
228
+ failedMeasure = obsmetrics .ExporterFailedToSendLogRecords
115
229
}
230
+
231
+ _ = stats .RecordWithTags (
232
+ ctx ,
233
+ exp .mutators ,
234
+ sentMeasure .M (sent ),
235
+ failedMeasure .M (failed ))
116
236
}
117
237
118
238
func endSpan (ctx context.Context , err error , numSent , numFailedToSend int64 , sentItemsKey , failedToSendItemsKey string ) {
0 commit comments