Skip to content
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

A span with a new span ID MUST be created even for a sampling decision of DROP. #3290

Open
Oberon00 opened this issue May 19, 2022 · 13 comments
Milestone

Comments

@Oberon00
Copy link
Member

Oberon00 commented May 19, 2022

Bug Report

This bug should be present in master and at least since 0.5.0-beta (probably since the beginning)

Symptom

If the sampler returns a decision of DROP, StartActivity returns null.

What is the expected behavior?

An unsampled activity with a new span ID is created and returned (and set as current which is not spec-conformant but expected in .NET). This allows correlating logs also to unsampled operations.

Spec references:

https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/trace/sdk.md#shouldsample

DROP - IsRecording() == false, span will not be recorded and all events and attributes will be dropped.

https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/trace/sdk.md#sdk-span-creation

  1. Generate a new span ID for the Span, independently of the sampling decision. This is done so other components (such as logs or exception handling) can rely on a unique span ID, even if the Span is a non-recording instance.
  2. [...] A non-recording span MAY be implemented using the same mechanism as when a Span is created without an SDK installed or as described in wrapping a SpanContext in a Span.

https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/trace/api.md#wrapping-a-spancontext-in-a-span

The behavior is defined as follows:

  • GetContext MUST return the wrapped SpanContext.

What is the actual behavior?

Null is returned for the activity, no span ID is available.

Reproduce

There is a unit test for the wrong behavior here:

// This is not a root activity.
// If sampling returns false, no activity is created at all.
using var innerActivity = activitySource.StartActivity("inner");
Assert.Null(innerActivity);

Additional Context

This is a pretty big deviation from the spec that will inhibit some use cases. Creating a new span ID even for unsampled spans was a very deliberate decision. There were even two competing PRs open-telemetry/opentelemetry-specification#1225 and open-telemetry/opentelemetry-specification#998 and it was explicitly decided on always creating a span ID. See especially the thread ending at open-telemetry/opentelemetry-specification#998 (comment)

@Oberon00 Oberon00 added the bug Something isn't working label May 19, 2022
@Oberon00
Copy link
Member Author

Note that in the case I observed, I even got a null activity despite there being no current span (the parent context was extracted from HTTP headers, having IsRemote=true, TraceFlags=None)

@bledogit
Copy link

Up voting this issue. Furthermore, the behavior of StartActivity should be such that an activity is created with or without the sampled flag turned on, depending on the sampler settings, and the sampler should be such that an exception can change the DROP decision of the Activity and All its parents to record failed Spans created locally.

There should be at least the option to be able to record the root activity resulting of a transaction with no parent, like an API entry point which should return the traceID in the response (https://github.com/w3c/trace-context/blob/main/spec/21-http_response_header_format.md) . The returned TraceID (with possibly an orphan flag) then can be used to query the DB for spans with exceptions coming from an unsampled chain of Spans that where not sampled.

The main objective is to sample a percentage of the healthy transactions, while recording 100% of the local spans that resulted in an error/exception. We must be able to answer the question as why a transaction 00-ttt-xxx-00 failed. Without this distributed tracing becomes no better than debug logs.

@erchirag
Copy link

erchirag commented Nov 1, 2022

Can someone comment on any performance implications of creating activity object always even when sampling decision was to not collect current span ?

@cijothomas
Copy link
Member

https://github.com/open-telemetry/opentelemetry-dotnet/blob/main/test/Benchmarks/Trace/TraceBenchmarks.cs#L38
Creating an activity, and feeding it to a no-op processor, is approximately of this (see above ^) much cost.

@cijothomas
Copy link
Member

https://github.com/open-telemetry/opentelemetry-dotnet/blob/main/test/Benchmarks/Trace/TraceBenchmarks.cs#L38 Creating an activity, and feeding it to a no-op processor, is approximately of this (see above ^) much cost.

https://github.com/open-telemetry/opentelemetry-dotnet/blob/main/test/Benchmarks/Trace/OpenTelemetrySdkBenchmarksActivity.cs#L38

And can go up, if tags/attributes are added. (most likely avoidable, by checking IsAllDataRequested before populating tags)

@erchirag
Copy link

erchirag commented Nov 1, 2022

What about any GC impact if lots of these objects are created in tight loop ?

@cijothomas
Copy link
Member

The benchmarks shows the heap allocation (416B), so yes GC has to clean it up.

@bledogit
Copy link

bledogit commented Nov 2, 2022

If performance is an issue, can't these objects be pooled?

@cijothomas cijothomas added this to the 1.5.0 milestone Feb 14, 2023
@cijothomas
Copy link
Member

Tagging for consideration in 1.5.0

@TimothyMothra
Copy link
Contributor

+1.
I think this is the root cause of #4087.

@cijothomas
Copy link
Member

The PR to address got stale and closed. I suggest to move this out of 1.5 timeline, as this likely requires more discussions.

Copy link
Contributor

github-actions bot commented Oct 8, 2024

This issue was marked stale due to lack of activity and will be closed in 7 days. Commenting will instruct the bot to automatically remove the label. This bot runs once per day.

@github-actions github-actions bot added the Stale Issues and pull requests which have been flagged for closing due to inactivity label Oct 8, 2024
@cijothomas
Copy link
Member

Not stale, spec violation.

@cijothomas cijothomas removed the bug Something isn't working label Oct 8, 2024
@Kielek Kielek added this to the Future milestone Oct 8, 2024
@TimothyMothra TimothyMothra removed the Stale Issues and pull requests which have been flagged for closing due to inactivity label Oct 8, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

7 participants