Skip to content

Commit 8fc45ba

Browse files
authored
Do not handle empty partial OTLP successes (#3438)
* Do not handle empty partial OTLP successes Fix #3432. The OTLP server will respond with empty partial success responses (i.e. empty messages and 0 count). Treat these as equivalent to it not being set/present like the documentation specifies in the proto: https://github.com/open-telemetry/opentelemetry-proto/blob/724e427879e3d2bae2edc0218fff06e37b9eb46e/opentelemetry/proto/collector/trace/v1/trace_service.proto#L58 * Fix tests * Add changes to changelog
1 parent 2a2d1ec commit 8fc45ba

File tree

5 files changed

+32
-34
lines changed

5 files changed

+32
-34
lines changed

CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm
3232
- Cumulative metrics from the OpenCensus bridge (`go.opentelemetry.io/otel/bridge/opencensus`) are defined as monotonic sums, instead of non-monotonic. (#3389)
3333
- Asynchronous counters (`Counter` and `UpDownCounter`) from the metric SDK now produce delta sums when configured with delta temporality. (#3398)
3434
- Exported `Status` codes in the `go.opentelemetry.io/otel/exporters/zipkin` exporter are now exported as all upper case values. (#3340)
35+
- Do not report empty partial-success responses in the `go.opentelemetry.io/otel/exporters/otlp` exporters. (#3438, #3432)
3536

3637
## [1.11.1/0.33.0] 2022-10-19
3738

exporters/otlp/internal/partialsuccess.go

+15-19
Original file line numberDiff line numberDiff line change
@@ -16,27 +16,14 @@ package internal // import "go.opentelemetry.io/otel/exporters/otlp/internal"
1616

1717
import "fmt"
1818

19-
// PartialSuccessDropKind indicates the kind of partial success error
20-
// received by an OTLP exporter, which corresponds with the signal
21-
// being exported.
22-
type PartialSuccessDropKind string
23-
24-
const (
25-
// TracingPartialSuccess indicates that some spans were rejected.
26-
TracingPartialSuccess PartialSuccessDropKind = "spans"
27-
28-
// MetricsPartialSuccess indicates that some metric data points were rejected.
29-
MetricsPartialSuccess PartialSuccessDropKind = "metric data points"
30-
)
31-
3219
// PartialSuccess represents the underlying error for all handling
3320
// OTLP partial success messages. Use `errors.Is(err,
3421
// PartialSuccess{})` to test whether an error passed to the OTel
3522
// error handler belongs to this category.
3623
type PartialSuccess struct {
3724
ErrorMessage string
3825
RejectedItems int64
39-
RejectedKind PartialSuccessDropKind
26+
RejectedKind string
4027
}
4128

4229
var _ error = PartialSuccess{}
@@ -56,13 +43,22 @@ func (ps PartialSuccess) Is(err error) bool {
5643
return ok
5744
}
5845

59-
// PartialSuccessToError produces an error suitable for passing to
60-
// `otel.Handle()` out of the fields in a partial success response,
61-
// independent of which signal produced the outcome.
62-
func PartialSuccessToError(kind PartialSuccessDropKind, itemsRejected int64, errorMessage string) error {
46+
// TracePartialSuccessError returns an error describing a partial success
47+
// response for the trace signal.
48+
func TracePartialSuccessError(itemsRejected int64, errorMessage string) error {
49+
return PartialSuccess{
50+
ErrorMessage: errorMessage,
51+
RejectedItems: itemsRejected,
52+
RejectedKind: "spans",
53+
}
54+
}
55+
56+
// MetricPartialSuccessError returns an error describing a partial success
57+
// response for the metric signal.
58+
func MetricPartialSuccessError(itemsRejected int64, errorMessage string) error {
6359
return PartialSuccess{
6460
ErrorMessage: errorMessage,
6561
RejectedItems: itemsRejected,
66-
RejectedKind: kind,
62+
RejectedKind: "metric data points",
6763
}
6864
}

exporters/otlp/internal/partialsuccess_test.go

+4-5
Original file line numberDiff line numberDiff line change
@@ -36,9 +36,8 @@ func requireErrorString(t *testing.T, expect string, err error) {
3636
}
3737

3838
func TestPartialSuccessFormat(t *testing.T) {
39-
requireErrorString(t, "empty message (0 metric data points rejected)", PartialSuccessToError(MetricsPartialSuccess, 0, ""))
40-
requireErrorString(t, "help help (0 metric data points rejected)", PartialSuccessToError(MetricsPartialSuccess, 0, "help help"))
41-
requireErrorString(t, "what happened (10 metric data points rejected)", PartialSuccessToError(MetricsPartialSuccess, 10, "what happened"))
42-
requireErrorString(t, "what happened (15 spans rejected)", PartialSuccessToError(TracingPartialSuccess, 15, "what happened"))
43-
requireErrorString(t, "empty message (7 log records rejected)", PartialSuccessToError("log records", 7, ""))
39+
requireErrorString(t, "empty message (0 metric data points rejected)", MetricPartialSuccessError(0, ""))
40+
requireErrorString(t, "help help (0 metric data points rejected)", MetricPartialSuccessError(0, "help help"))
41+
requireErrorString(t, "what happened (10 metric data points rejected)", MetricPartialSuccessError(10, "what happened"))
42+
requireErrorString(t, "what happened (15 spans rejected)", TracePartialSuccessError(15, "what happened"))
4443
}

exporters/otlp/otlptrace/otlptracegrpc/client.go

+6-5
Original file line numberDiff line numberDiff line change
@@ -202,11 +202,12 @@ func (c *client) UploadTraces(ctx context.Context, protoSpans []*tracepb.Resourc
202202
ResourceSpans: protoSpans,
203203
})
204204
if resp != nil && resp.PartialSuccess != nil {
205-
otel.Handle(internal.PartialSuccessToError(
206-
internal.TracingPartialSuccess,
207-
resp.PartialSuccess.RejectedSpans,
208-
resp.PartialSuccess.ErrorMessage,
209-
))
205+
msg := resp.PartialSuccess.GetErrorMessage()
206+
n := resp.PartialSuccess.GetRejectedSpans()
207+
if n != 0 || msg != "" {
208+
err := internal.TracePartialSuccessError(n, msg)
209+
otel.Handle(err)
210+
}
210211
}
211212
// nil is converted to OK.
212213
if status.Code(err) == codes.OK {

exporters/otlp/otlptrace/otlptracehttp/client.go

+6-5
Original file line numberDiff line numberDiff line change
@@ -180,11 +180,12 @@ func (d *client) UploadTraces(ctx context.Context, protoSpans []*tracepb.Resourc
180180
}
181181

182182
if respProto.PartialSuccess != nil {
183-
otel.Handle(internal.PartialSuccessToError(
184-
internal.TracingPartialSuccess,
185-
respProto.PartialSuccess.RejectedSpans,
186-
respProto.PartialSuccess.ErrorMessage,
187-
))
183+
msg := respProto.PartialSuccess.GetErrorMessage()
184+
n := respProto.PartialSuccess.GetRejectedSpans()
185+
if n != 0 || msg != "" {
186+
err := internal.TracePartialSuccessError(n, msg)
187+
otel.Handle(err)
188+
}
188189
}
189190
}
190191
return nil

0 commit comments

Comments
 (0)