opentelemetry-java icon indicating copy to clipboard operation
opentelemetry-java copied to clipboard

Add documentation on how to remove the span and disable implicit child spans for a particular code path

Open anuraaga opened this issue 5 years ago • 16 comments

Currently, the best way to how to remove the span and disable implicit child spans for a particular code path is probably this

try (Scope ignored = TracingContextUtils.currentContextWith(DefaultSpan.getInvalid())) {
  // Since scoped span is invalid, no tracing happens.
}

This should be documented, possibly with a helper somewhere, something like Scope withTracingDisabled().

/cc @marcingrzejszczak

anuraaga avatar Sep 28 '20 08:09 anuraaga

Your code snippet just clears the current span, I don't know if that counts as "disable tracing". For disabling tracing, a spec issue is open at https://github.com/open-telemetry/opentelemetry-specification/issues/530. EDIT: I think here you just want to clear the active span, so please be careful with terminology 😃

Oberon00 avatar Sep 28 '20 09:09 Oberon00

@Oberon00 I'm trying to differentiate between only clearing the active span, meaning a new span could be made, or making sure no new spans are made within that scope of code. Unless someone explicitly brings in a valid span with something like TracingContextUtils.currentContextWith(tracer.spanBuilder().setParent(validParent).start()), I think this does basically "disable tracing", no?

Edit: Parent would also need to be explicit to re-enable tracing

anuraaga avatar Sep 28 '20 09:09 anuraaga

Tracing is enabled, everything works as expected, there is just no current span. For example, if you set an attribute, you would usually not do it on the return value of getCurrentSpan, but on some span object you already have, which would still work. So I am against calling this "disable tracing". Also, it would easily be confused with what open-telemetry/opentelemetry-specification#530 wants to specify.

Oberon00 avatar Sep 28 '20 09:09 Oberon00

If your code snippet disables tracing, then tracing is always initially disabled in opentelemetry-java.

Oberon00 avatar Sep 28 '20 09:09 Oberon00

Well - changed the title to be more explicit, but IMO less clear. The difference between disable and stop tracing in my mind I think is

Disabled: No spans are generated, nothing is propagated Stopped: No spans are generated, but current span is still propagated

At least I think that's what open-telemetry/opentelemetry-specification#530 says.

As you say, the extractors have the power to set the current span, but that's about it, and happens before user code so if a user sets the Scope to an invalid Span, I'd still say tracing's disabled for all intents and purposes :P

anuraaga avatar Sep 28 '20 09:09 anuraaga

I think there was no intention to introduce a difference between disabling and stopping tracing.

As you say, the extractors have the power to set the current span, but that's about it, and happens before user code so if a user sets the Scope to an invalid Span, I'd still say tracing's disabled for all intents and purposes :P

Why only extractors? If the user

  • Starts a span like usual, it will work as usual (it will be a root span, as the parent was cleared)
  • Sets any, also previously started, span as active, e.g. using Tracer.withSpan, it will work as usual.

Note that while the invalid span has sampled=false, this is ignored due to it being invalid.

Oberon00 avatar Sep 28 '20 09:09 Oberon00

Starts a span like usual, it will work as usual (it will be a root span, as the parent was cleared)

You mean using setNoParent? Yeah I guess that's true, but it's really rare to use that. I think in documentation we can refer to this as disabling "implicit tracing" - normal operations that instrument based on the current span will be no-op because the current span is invalid. We can mention it can still be explicitly overridden by a non-parented span, or a span from an unrelated ancestor - these are pretty rare cases and can be called out as exceptions I think.

anuraaga avatar Sep 28 '20 09:09 anuraaga

You mean using setNoParent

No, also using the implicit current span as parent. EDIT: See also #1690

Oberon00 avatar Sep 28 '20 09:09 Oberon00

Ah oops - thanks yeah forgot the non-default tracer does that. It's related to that spec PR indeed.

anuraaga avatar Sep 28 '20 09:09 anuraaga

Yeah, I'd assume that were talking about removing the span from scope. That means that if I call tracer.currentSpan() I will get a null.

marcingrzejszczak avatar Sep 28 '20 10:09 marcingrzejszczak

currentSpan will never return null, but an invalid span if there is no current span. This is so that you never have to check if for null and calling anything on it is a no-op instead of crashing.

Oberon00 avatar Sep 28 '20 10:09 Oberon00

@anuraaga do you think this is still needed, or is this blocked on spec changes?

jkwatson avatar Mar 05 '21 18:03 jkwatson

I think this is still needed and needing someone to drive the spec change

anuraaga avatar Mar 06 '21 01:03 anuraaga

I am trying to figure out if this a solution to a problem I have. What I would like to do is to be able to determine programmatically that a given span (and all its children) are uninteresting and should not be traced. Indeed maybe I want to discard the entire trace at this point and not send it to the collector.

In other words, I think I want some way to say "isSampled=false" programmatically. Is there a way to do that today? The original post seems to imply there's a way to at least prune out some children by making the current span invalid but that seems more like a workaround?

lordpixel23 avatar Sep 17 '23 13:09 lordpixel23

So, I am wondering, is there any news on this?

I have manually instrumented my Kotlin Ktor API application, and use a Java Agent to collect all OpenTelemetry data. This works nice, but I also get traces for my health_check endpoint and my prewarm method (which calls instrumented methods), which I don't want.

So how do I disable all child spans from being recorded?

I am contemplating adding a root span attribute like ignore=true and then filtering stuff out at the collector, but would prefer just a simple way to make sure that a certain trace does not get sent at all, right from my code.

peterdk avatar Jun 29 '24 19:06 peterdk

Hi @peterdk - we're unfortunately still waiting for a language agnostic answer in the spec (https://github.com/open-telemetry/opentelemetry-specification/issues/530). But in the mean time, check out #6546. Its a java specific solution, and requires coordination with instrumentation which has to check if the supress context key is set, but I believe instrumentations from opentelemetry-java-instrumentation will check this.

cc @open-telemetry/java-instrumentation-maintainers to fact check me

jack-berg avatar Jul 11 '24 22:07 jack-berg