You've already forked opentelemetry-go
mirror of
https://github.com/open-telemetry/opentelemetry-go.git
synced 2026-06-19 21:45:50 +02:00
fix counting of spans/logs in self-observability metrics in otlp trace and log exporters (#8254)
Fixes https://github.com/open-telemetry/opentelemetry-go/issues/8253
This commit is contained in:
@@ -75,6 +75,7 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm
|
|||||||
- Fix stale status code reporting on self-observability metrics in `go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp` and `go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp`. (#8226)
|
- Fix stale status code reporting on self-observability metrics in `go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp` and `go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp`. (#8226)
|
||||||
- Fix a concurrent `Collect` data race and potential panic in `go.opentelemetry.io/otel/exporters/prometheus` when `WithResourceAsConstantLabels` option is used. (#8227)
|
- Fix a concurrent `Collect` data race and potential panic in `go.opentelemetry.io/otel/exporters/prometheus` when `WithResourceAsConstantLabels` option is used. (#8227)
|
||||||
- Fix race condition in `FixedSizeReservoir` in `go.opentelemetry.io/otel/sdk/metric/exemplar` by reverting #7447. (#8249)
|
- Fix race condition in `FixedSizeReservoir` in `go.opentelemetry.io/otel/sdk/metric/exemplar` by reverting #7447. (#8249)
|
||||||
|
- Fix counting of spans and logs in self-observability metrics in `go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc`, `go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp`, `go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc`, and `go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp`. (#8254)
|
||||||
|
|
||||||
<!-- Released section -->
|
<!-- Released section -->
|
||||||
<!-- Don't change this section unless doing release -->
|
<!-- Don't change this section unless doing release -->
|
||||||
|
|||||||
@@ -151,8 +151,13 @@ func (c *client) UploadLogs(ctx context.Context, rl []*logpb.ResourceLogs) (uplo
|
|||||||
defer cancel()
|
defer cancel()
|
||||||
|
|
||||||
pbRequest := &collogpb.ExportLogsServiceRequest{ResourceLogs: rl}
|
pbRequest := &collogpb.ExportLogsServiceRequest{ResourceLogs: rl}
|
||||||
count := int64(len(rl))
|
|
||||||
if c.instrumentation != nil {
|
if c.instrumentation != nil {
|
||||||
|
var count int64
|
||||||
|
for _, resLogs := range rl {
|
||||||
|
for _, scopeLogs := range resLogs.ScopeLogs {
|
||||||
|
count += int64(len(scopeLogs.LogRecords))
|
||||||
|
}
|
||||||
|
}
|
||||||
eo := c.instrumentation.ExportLogs(ctx, count)
|
eo := c.instrumentation.ExportLogs(ctx, count)
|
||||||
defer func() {
|
defer func() {
|
||||||
eo.End(uploadErr)
|
eo.End(uploadErr)
|
||||||
|
|||||||
@@ -705,7 +705,7 @@ func TestClientObservability(t *testing.T) {
|
|||||||
serverAddrAttrs[0],
|
serverAddrAttrs[0],
|
||||||
serverAddrAttrs[1],
|
serverAddrAttrs[1],
|
||||||
),
|
),
|
||||||
Value: int64(len(resourceLogs)),
|
Value: int64(len(logRecords)),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -831,7 +831,7 @@ func TestClientObservability(t *testing.T) {
|
|||||||
serverAddrAttrs[0],
|
serverAddrAttrs[0],
|
||||||
serverAddrAttrs[1],
|
serverAddrAttrs[1],
|
||||||
),
|
),
|
||||||
Value: 0,
|
Value: 2,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Attributes: attribute.NewSet(
|
Attributes: attribute.NewSet(
|
||||||
@@ -843,7 +843,7 @@ func TestClientObservability(t *testing.T) {
|
|||||||
serverAddrAttrs[1],
|
serverAddrAttrs[1],
|
||||||
semconv.ErrorType(wantErr),
|
semconv.ErrorType(wantErr),
|
||||||
),
|
),
|
||||||
Value: 1,
|
Value: 2,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -976,7 +976,7 @@ func TestClientObservability(t *testing.T) {
|
|||||||
serverAddrAttrs[1],
|
serverAddrAttrs[1],
|
||||||
wantErrTypeAttr,
|
wantErrTypeAttr,
|
||||||
),
|
),
|
||||||
Value: 1,
|
Value: int64(len(logRecords)),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -1144,7 +1144,7 @@ func TestClientObservabilityWithRetry(t *testing.T) {
|
|||||||
serverAddrAttrs[0],
|
serverAddrAttrs[0],
|
||||||
serverAddrAttrs[1],
|
serverAddrAttrs[1],
|
||||||
),
|
),
|
||||||
Value: int64(len(resourceLogs)) - n,
|
Value: int64(len(logRecords)) - n,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Attributes: attribute.NewSet(
|
Attributes: attribute.NewSet(
|
||||||
|
|||||||
@@ -164,7 +164,13 @@ func (c *httpClient) uploadLogs(ctx context.Context, data []*logpb.ResourceLogs)
|
|||||||
|
|
||||||
var statusCode int
|
var statusCode int
|
||||||
if c.inst != nil {
|
if c.inst != nil {
|
||||||
op := c.inst.ExportLogs(ctx, int64(len(data)))
|
var count int64
|
||||||
|
for _, resLogs := range data {
|
||||||
|
for _, scopeLogs := range resLogs.ScopeLogs {
|
||||||
|
count += int64(len(scopeLogs.LogRecords))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
op := c.inst.ExportLogs(ctx, count)
|
||||||
defer func() { op.End(uploadErr, statusCode) }()
|
defer func() { op.End(uploadErr, statusCode) }()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1038,7 +1038,7 @@ func TestClientInstrumentation(t *testing.T) {
|
|||||||
Unit: otelconv.SDKExporterLogInflight{}.Unit(),
|
Unit: otelconv.SDKExporterLogInflight{}.Unit(),
|
||||||
Data: metricdata.Sum[int64]{
|
Data: metricdata.Sum[int64]{
|
||||||
DataPoints: []metricdata.DataPoint[int64]{
|
DataPoints: []metricdata.DataPoint[int64]{
|
||||||
{Attributes: attribute.NewSet(baseAttrs...)},
|
{Attributes: attribute.NewSet(baseAttrs...), Value: 0},
|
||||||
},
|
},
|
||||||
Temporality: metricdata.CumulativeTemporality,
|
Temporality: metricdata.CumulativeTemporality,
|
||||||
},
|
},
|
||||||
@@ -1049,11 +1049,11 @@ func TestClientInstrumentation(t *testing.T) {
|
|||||||
Unit: otelconv.SDKExporterLogExported{}.Unit(),
|
Unit: otelconv.SDKExporterLogExported{}.Unit(),
|
||||||
Data: metricdata.Sum[int64]{
|
Data: metricdata.Sum[int64]{
|
||||||
DataPoints: []metricdata.DataPoint[int64]{
|
DataPoints: []metricdata.DataPoint[int64]{
|
||||||
{Attributes: attribute.NewSet(baseAttrs...)},
|
{Attributes: attribute.NewSet(baseAttrs...), Value: 2},
|
||||||
{Attributes: attribute.NewSet(append(
|
{Attributes: attribute.NewSet(append(
|
||||||
baseAttrs,
|
baseAttrs,
|
||||||
otelconv.SDKExporterLogExported{}.AttrErrorType("*errors.joinError"),
|
otelconv.SDKExporterLogExported{}.AttrErrorType("*errors.joinError"),
|
||||||
)...)},
|
)...), Value: 2},
|
||||||
},
|
},
|
||||||
Temporality: 0x1,
|
Temporality: 0x1,
|
||||||
IsMonotonic: true,
|
IsMonotonic: true,
|
||||||
@@ -1078,12 +1078,25 @@ func TestClientInstrumentation(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
require.Len(t, got.ScopeMetrics, 1)
|
require.Len(t, got.ScopeMetrics, 1)
|
||||||
opt := []metricdatatest.Option{
|
|
||||||
|
gotMetrics := got.ScopeMetrics[0].Metrics
|
||||||
|
require.Len(t, gotMetrics, 3, "expected 3 metrics")
|
||||||
|
|
||||||
|
// Assert counters without IgnoreValue
|
||||||
|
optCounters := []metricdatatest.Option{
|
||||||
|
metricdatatest.IgnoreTimestamp(),
|
||||||
|
metricdatatest.IgnoreExemplars(),
|
||||||
|
}
|
||||||
|
metricdatatest.AssertEqual(t, want.Metrics[0], gotMetrics[0], optCounters...)
|
||||||
|
metricdatatest.AssertEqual(t, want.Metrics[1], gotMetrics[1], optCounters...)
|
||||||
|
|
||||||
|
// Assert duration with IgnoreValue
|
||||||
|
optDuration := []metricdatatest.Option{
|
||||||
metricdatatest.IgnoreTimestamp(),
|
metricdatatest.IgnoreTimestamp(),
|
||||||
metricdatatest.IgnoreExemplars(),
|
metricdatatest.IgnoreExemplars(),
|
||||||
metricdatatest.IgnoreValue(),
|
metricdatatest.IgnoreValue(),
|
||||||
}
|
}
|
||||||
metricdatatest.AssertEqual(t, want, got.ScopeMetrics[0], opt...)
|
metricdatatest.AssertEqual(t, want.Metrics[2], gotMetrics[2], optDuration...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestResponseBodySizeLimit(t *testing.T) {
|
func TestResponseBodySizeLimit(t *testing.T) {
|
||||||
|
|||||||
@@ -215,7 +215,13 @@ func (c *client) UploadTraces(ctx context.Context, protoSpans []*tracepb.Resourc
|
|||||||
|
|
||||||
code := codes.Unknown
|
code := codes.Unknown
|
||||||
if c.inst != nil {
|
if c.inst != nil {
|
||||||
op := c.inst.ExportSpans(ctx, len(protoSpans))
|
var spanCount int
|
||||||
|
for _, rs := range protoSpans {
|
||||||
|
for _, ss := range rs.ScopeSpans {
|
||||||
|
spanCount += len(ss.Spans)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
op := c.inst.ExportSpans(ctx, spanCount)
|
||||||
defer func() { op.End(uploadErr, code) }()
|
defer func() { op.End(uploadErr, code) }()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -491,7 +491,8 @@ func TestClientInstrumentation(t *testing.T) {
|
|||||||
t.Cleanup(func() { require.NoError(t, mc.stop()) })
|
t.Cleanup(func() { require.NoError(t, mc.stop()) })
|
||||||
|
|
||||||
exp := newGRPCExporter(t, t.Context(), mc.endpoint)
|
exp := newGRPCExporter(t, t.Context(), mc.endpoint)
|
||||||
err := exp.ExportSpans(t.Context(), roSpans)
|
localSpans := tracetest.SpanStubs{{Name: "Span 0"}, {Name: "Span 1"}}.Snapshots()
|
||||||
|
err := exp.ExportSpans(t.Context(), localSpans)
|
||||||
assert.ErrorIs(t, err, internal.TracePartialSuccessError(n, msg))
|
assert.ErrorIs(t, err, internal.TracePartialSuccessError(n, msg))
|
||||||
require.NoError(t, exp.Shutdown(t.Context()))
|
require.NoError(t, exp.Shutdown(t.Context()))
|
||||||
|
|
||||||
@@ -512,7 +513,7 @@ func TestClientInstrumentation(t *testing.T) {
|
|||||||
Unit: otelconv.SDKExporterSpanInflight{}.Unit(),
|
Unit: otelconv.SDKExporterSpanInflight{}.Unit(),
|
||||||
Data: metricdata.Sum[int64]{
|
Data: metricdata.Sum[int64]{
|
||||||
DataPoints: []metricdata.DataPoint[int64]{
|
DataPoints: []metricdata.DataPoint[int64]{
|
||||||
{Attributes: attribute.NewSet(attrs...)},
|
{Attributes: attribute.NewSet(attrs...), Value: 0},
|
||||||
},
|
},
|
||||||
Temporality: metricdata.CumulativeTemporality,
|
Temporality: metricdata.CumulativeTemporality,
|
||||||
},
|
},
|
||||||
@@ -523,11 +524,11 @@ func TestClientInstrumentation(t *testing.T) {
|
|||||||
Unit: otelconv.SDKExporterSpanExported{}.Unit(),
|
Unit: otelconv.SDKExporterSpanExported{}.Unit(),
|
||||||
Data: metricdata.Sum[int64]{
|
Data: metricdata.Sum[int64]{
|
||||||
DataPoints: []metricdata.DataPoint[int64]{
|
DataPoints: []metricdata.DataPoint[int64]{
|
||||||
{Attributes: attribute.NewSet(attrs...)},
|
{Attributes: attribute.NewSet(attrs...), Value: 0},
|
||||||
{Attributes: attribute.NewSet(append(
|
{Attributes: attribute.NewSet(append(
|
||||||
attrs,
|
attrs,
|
||||||
otelconv.SDKExporterSpanExported{}.AttrErrorType("*errors.joinError"),
|
otelconv.SDKExporterSpanExported{}.AttrErrorType("*errors.joinError"),
|
||||||
)...)},
|
)...), Value: 2},
|
||||||
},
|
},
|
||||||
Temporality: 0x1,
|
Temporality: 0x1,
|
||||||
IsMonotonic: true,
|
IsMonotonic: true,
|
||||||
@@ -553,12 +554,18 @@ func TestClientInstrumentation(t *testing.T) {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
require.Len(t, got.ScopeMetrics, 1)
|
require.Len(t, got.ScopeMetrics, 1)
|
||||||
opt := []metricdatatest.Option{
|
gotMetrics := got.ScopeMetrics[0].Metrics
|
||||||
|
require.Len(t, gotMetrics, 3)
|
||||||
|
|
||||||
|
metricdatatest.AssertEqual(t, want.Metrics[0], gotMetrics[0], metricdatatest.IgnoreTimestamp())
|
||||||
|
metricdatatest.AssertEqual(t, want.Metrics[1], gotMetrics[1], metricdatatest.IgnoreTimestamp())
|
||||||
|
metricdatatest.AssertEqual(
|
||||||
|
t,
|
||||||
|
want.Metrics[2],
|
||||||
|
gotMetrics[2],
|
||||||
metricdatatest.IgnoreTimestamp(),
|
metricdatatest.IgnoreTimestamp(),
|
||||||
metricdatatest.IgnoreExemplars(),
|
|
||||||
metricdatatest.IgnoreValue(),
|
metricdatatest.IgnoreValue(),
|
||||||
}
|
)
|
||||||
metricdatatest.AssertEqual(t, want, got.ScopeMetrics[0], opt...)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func canonical(t *testing.T, endpoint string) string {
|
func canonical(t *testing.T, endpoint string) string {
|
||||||
|
|||||||
@@ -179,7 +179,13 @@ func (d *client) UploadTraces(ctx context.Context, protoSpans []*tracepb.Resourc
|
|||||||
|
|
||||||
var statusCode int
|
var statusCode int
|
||||||
if d.inst != nil {
|
if d.inst != nil {
|
||||||
op := d.inst.ExportSpans(ctx, len(protoSpans))
|
var spanCount int
|
||||||
|
for _, rs := range protoSpans {
|
||||||
|
for _, ss := range rs.ScopeSpans {
|
||||||
|
spanCount += len(ss.Spans)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
op := d.inst.ExportSpans(ctx, spanCount)
|
||||||
defer func() { op.End(uploadErr, statusCode) }()
|
defer func() { op.End(uploadErr, statusCode) }()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -531,7 +531,8 @@ func TestClientInstrumentation(t *testing.T) {
|
|||||||
exporter, err := otlptrace.New(t.Context(), driver)
|
exporter, err := otlptrace.New(t.Context(), driver)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
err = exporter.ExportSpans(t.Context(), otlptracetest.SingleReadOnlySpan())
|
localSpans := tracetest.SpanStubs{{Name: "Span 0"}, {Name: "Span 1"}}.Snapshots()
|
||||||
|
err = exporter.ExportSpans(t.Context(), localSpans)
|
||||||
assert.Error(t, err)
|
assert.Error(t, err)
|
||||||
|
|
||||||
require.NoError(t, exporter.Shutdown(t.Context()))
|
require.NoError(t, exporter.Shutdown(t.Context()))
|
||||||
@@ -553,7 +554,7 @@ func TestClientInstrumentation(t *testing.T) {
|
|||||||
Unit: otelconv.SDKExporterSpanInflight{}.Unit(),
|
Unit: otelconv.SDKExporterSpanInflight{}.Unit(),
|
||||||
Data: metricdata.Sum[int64]{
|
Data: metricdata.Sum[int64]{
|
||||||
DataPoints: []metricdata.DataPoint[int64]{
|
DataPoints: []metricdata.DataPoint[int64]{
|
||||||
{Attributes: attribute.NewSet(attrs...)},
|
{Attributes: attribute.NewSet(attrs...), Value: 0},
|
||||||
},
|
},
|
||||||
Temporality: metricdata.CumulativeTemporality,
|
Temporality: metricdata.CumulativeTemporality,
|
||||||
},
|
},
|
||||||
@@ -564,11 +565,11 @@ func TestClientInstrumentation(t *testing.T) {
|
|||||||
Unit: otelconv.SDKExporterSpanExported{}.Unit(),
|
Unit: otelconv.SDKExporterSpanExported{}.Unit(),
|
||||||
Data: metricdata.Sum[int64]{
|
Data: metricdata.Sum[int64]{
|
||||||
DataPoints: []metricdata.DataPoint[int64]{
|
DataPoints: []metricdata.DataPoint[int64]{
|
||||||
{Attributes: attribute.NewSet(attrs...)},
|
{Attributes: attribute.NewSet(attrs...), Value: 0},
|
||||||
{Attributes: attribute.NewSet(append(
|
{Attributes: attribute.NewSet(append(
|
||||||
attrs,
|
attrs,
|
||||||
otelconv.SDKExporterSpanExported{}.AttrErrorType("*errors.joinError"),
|
otelconv.SDKExporterSpanExported{}.AttrErrorType("*errors.joinError"),
|
||||||
)...)},
|
)...), Value: 2},
|
||||||
},
|
},
|
||||||
Temporality: 0x1,
|
Temporality: 0x1,
|
||||||
IsMonotonic: true,
|
IsMonotonic: true,
|
||||||
@@ -592,12 +593,18 @@ func TestClientInstrumentation(t *testing.T) {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
require.Len(t, got.ScopeMetrics, 1)
|
require.Len(t, got.ScopeMetrics, 1)
|
||||||
opt := []metricdatatest.Option{
|
gotMetrics := got.ScopeMetrics[0].Metrics
|
||||||
|
require.Len(t, gotMetrics, 3)
|
||||||
|
|
||||||
|
metricdatatest.AssertEqual(t, want.Metrics[0], gotMetrics[0], metricdatatest.IgnoreTimestamp())
|
||||||
|
metricdatatest.AssertEqual(t, want.Metrics[1], gotMetrics[1], metricdatatest.IgnoreTimestamp())
|
||||||
|
metricdatatest.AssertEqual(
|
||||||
|
t,
|
||||||
|
want.Metrics[2],
|
||||||
|
gotMetrics[2],
|
||||||
metricdatatest.IgnoreTimestamp(),
|
metricdatatest.IgnoreTimestamp(),
|
||||||
metricdatatest.IgnoreExemplars(),
|
|
||||||
metricdatatest.IgnoreValue(),
|
metricdatatest.IgnoreValue(),
|
||||||
}
|
)
|
||||||
metricdatatest.AssertEqual(t, want, got.ScopeMetrics[0], opt...)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestResponseBodySizeLimit(t *testing.T) {
|
func TestResponseBodySizeLimit(t *testing.T) {
|
||||||
|
|||||||
Reference in New Issue
Block a user