-
Notifications
You must be signed in to change notification settings - Fork 527
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
OpenTelemetry active message consumption spans are incorrectly classified as transactions #7001
Comments
Hi @ymotongpoo! Yes, this is still the case.
Can you share the snippet? I can't tell from the screenshot which spans should or should not be considered transactions. The code relevant to this bug is: apm-server/internal/processor/otel/traces.go Lines 196 to 225 in efc8be5
If/when the linked OTEP is accepted and implemented, then instead of checking |
Hi @axw, thanks for the response! Here's the code snippet I used for the demo. func handler(w http.ResponseWriter, r *http.Request) {
q := r.URL.Query()
c := q.Get("c")
n, err := strconv.Atoi(c)
if err != nil {
n = 2
}
if n > 8 {
n = 8
}
ctx, span := otel.Tracer("handler").Start(r.Context(), "sample.handler.call.foo")
foo(ctx, n)
span.End()
w.WriteHeader(http.StatusOK)
fmt.Fprintf(w, "requested: %v, executed: %v", c, n)
}
func foo(ctx context.Context, n int) {
if n == 0 {
return
}
ctx, span := otel.Tracer("handler").Start(ctx, "sample.foo")
span.SetAttributes(attribute.Key("iteration").Int(n))
time.Sleep(interval)
span.AddEvent(fmt.Sprintf("mid-interval-%v", n))
time.Sleep(interval)
foo(ctx, n-1)
span.End()
} I didn't used OpenTelemetry Collector and directly sent the traces with OTLP exporter from the app. // OTLP exporter config for Elastic Observability
otlpexp, err := otlptracegrpc.New(
context.Background(),
otlptracegrpc.WithEndpoint(OTLPEndpoint),
otlptracegrpc.WithHeaders(OTLPHeaders),
)
if err != nil {
return nil, err
} Because this is a standalone demo running on Cloud Run and doesn't have other depending services, so the traces should be either of:
|
I see, thanks. This is not exactly the same issue as in the description, but would also be solved by the change I described. For this case you have a workaround: set the |
Thank you for the workaround, @axw. However, neither of SpanKind worked and still all traces are recognized as transactions. Just in case, I changed the SpanKind of func handler(w http.ResponseWriter, r *http.Request) {
q := r.URL.Query()
c := q.Get("c")
n, err := strconv.Atoi(c)
if err != nil {
n = 2
}
if n > 8 {
n = 8
}
ctx, span := otel.Tracer("handler").Start(
r.Context(),
"sample.handler.call.foo",
trace.WithSpanKind(trace.SpanKindInternal),
)
foo(ctx, n)
span.End()
w.WriteHeader(http.StatusOK)
fmt.Fprintf(w, "requested: %v, executed: %v", c, n)
}
func foo(ctx context.Context, n int) {
if n == 0 {
return
}
ctx, span := otel.Tracer("handler").Start(
ctx,
"sample.foo",
trace.WithSpanKind(trace.SpanKindInternal),
)
span.SetAttributes(attribute.Key("iteration").Int(n))
time.Sleep(interval)
span.AddEvent(fmt.Sprintf("mid-interval-%v", n))
time.Sleep(interval)
foo(ctx, n-1)
span.End()
} |
@ymotongpoo sorry, I missed something in your original comment and went off track a bit. I think what you're seeing here is related to Cloud Run injecting a
I guess you already know this, but just so we're on the same page: https://opentelemetry.io/docs/reference/specification/trace/api/#spankind says:
I think I misunderstood your trace before, and thought that Going back to your initial comment, I overlooked something:
The Traces page is simply listing root transactions, by looking for any transactions without a parent ID. In your example we should expect that Assuming that's the case, I think you're hitting something similar to this issue: elastic/apm#609. i.e. I expect Cloud Run is injecting a |
@axw Thank you for the detailed answer.
I realized I missed the fact that Cloud Run injects the
As you suggested, I tried creating span with The snippet was: otelHandler := otelhttp.NewHandler(
http.HandlerFunc(handler),
"sample.handler",
otelhttp.WithSpanOptions(trace.WithNewRoot()),
) Given above, as you pointed out, my case seems about elastic/apm#609. |
APM Server converts OpenTelemetry spans to either transactions or spans, depending on several criteria:
The issue with converting all consumer OTel spans to Elastic APM transactions is that not all consumer spans represent service entrypoints. For example, a message may be actively consumed (e.g. with active polling) within another OTel span. In this case, the outer span should become an Elastic APM transaction, and the message consumption span should become an Elastic APM span.
We require additional information to be recorded in OTLP for this: see open-telemetry/oteps#182
The text was updated successfully, but these errors were encountered: