-
Notifications
You must be signed in to change notification settings - Fork 826
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
Client side instrumentation with a parent trace that groups child spans #3237
Comments
The picture from Honeycomb's whitepaper is how I hoped/imagined that autoinstrumented After implementing it I was disappointed to see it doesn't 😞 |
Not sure if this behavior should be the default. Note that spans are only exported once they are ended, at least with most exporters (e.g. OTLP, Jaeager, zipkin). So you will get a lot spans with the same traceId but the root span is potentially missing for a long time - if it arrives at all (export on unload may fail). I think you could reach something like this by creating a span manually and set is as active for all code running on your page. But as I'm not an browers expert I don't know how the zone.js context manager usually used on Web works and if this is easily possible. Maybe OTel RUM is intended to solve the actual use case? |
So I'm trying to do manual frontend browser instrumentation for React to get nested fetch request spans. Does anyone have thoughts on why it's not working 🤔 I'm trying to achieve something like the Honeycomb example pointed out by OP I tried the suggested blog approach, but it doesn't work for React 🤔
I am starting a span currently on page load in entrypoint App.tsx and I would like to see all fetched 3rd party requests via fetchInstrumentation. I've tried adding the following to the last component in my page
I've also tried the same with
|
What is missing in your code is the As said I'm not familiar with web and which context is use where so don't know if this solves your issue. But I know how to cheat :o) - here is an implementation of a high performance context manager allowing you to specify the one and only active context: import { trace, ContextManager, Context, ROOT_CONTEXT } from "@opentelemetry/api";
import { BasicTracerProvider, SimpleSpanProcessor, ConsoleSpanExporter } from "@opentelemetry/sdk-trace-base";
class AlwaysSameContextManager implements ContextManager {
static theContext = ROOT_CONTEXT;
active(): Context { return AlwaysSameContextManager.theContext; }
with<A extends unknown[], F extends (...args: A) => ReturnType<F>>(_context: Context, fn: F, thisArg?: ThisParameterType<F>, ...args: A): ReturnType<F> { return Reflect.apply(fn, thisArg, args); }
bind<T>(_context: Context, target: T): T { return target; }
enable(): this { return this; }
disable(): this { return this; }
}
const tp = new BasicTracerProvider();
tp.addSpanProcessor(new SimpleSpanProcessor(new ConsoleSpanExporter()));
tp.register({
contextManager: new AlwaysSameContextManager().enable()
});
const tracer = trace.getTracer("RootTracer");
const span = tracer.startSpan("RootSpan");
AlwaysSameContextManager.theContext = trace.setSpan(ROOT_CONTEXT, span);
tracer.startSpan("a").end(); // child of RootSpan
tracer.startSpan("b").end(); // child of RootSpan
tracer.startActiveSpan("c", (span) => { // child of RootSpan
tracer.startSpan("d").end(); // even this is a child of RootSpan!
span.end();
}); ... not intended for production but you may get what you want. It should be not that difficult to extend it a bit to ensure that propagators inject the right span instead RootSpan. |
The always same context manager shown would mean every span is always disconnected because there is never a parent. I think you would instead want a context manager where you can specify an alternative root context but otherwise uses zone normally. |
@dyladan see But as written this includes propagators so a bit more is needed. |
Hi @Flarna I'm looking into how to get this working with propagators. Can you perhaps give any guidance on what I need to accomplish on a high level? Cheers! |
@AkselAllas Sorry but I don't understand your question. What else is missing besides the hacky |
This issue is stale because it has been open 60 days with no activity. Remove stale label or comment or this will be closed in 14 days. |
Using AlwaysOnContextManager leads to some extremely long and complex traces. Is there any span/trace viewer that allows filtering spans of a trace view using timestamp? |
This issue is stale because it has been open 60 days with no activity. Remove stale label or comment or this will be closed in 14 days. |
Given that single-page apps can be open and continuously interacting with server[s] for many hours, the huge traces would presumably cause UI issues in nearly any trace viewer tool.. I've definitely seen Datadog get squirrely when viewing a trace with ~30,0000 spans. Perhaps a better abstraction is giving a randomized resource attribute to the browser SDK? const provider = new WebTracerProvider({
resource: new Resource({
'service.name': 'my-single-page-app',
'session.id': crypto.randomUUID(), // correlate all traces from this pageload
}),
}); I don't see an attribute like this in the Resource Semantic Conventions, but I'm already using this strategy and find that trace viewers handle filtering quite well. Maybe the OpenTelemetry RUM effort will standardize a similar attribute. |
This issue is stale because it has been open 60 days with no activity. Remove stale label or comment or this will be closed in 14 days. |
This issue was closed because it has been stale for 14 days with no activity. |
Hey, my question is related to enabling the default client side packages to be instrumented with an existing parent trace.
This way we could achieve a waterfall in which we open with the event that could be generated by
@opentelemetry/instrumentation-document-load
and all other events that are generated by@opentelemetry/instrumentation-xml-http-request
and@opentelemetry/instrumentation-fetch
can be grouped under it - this way we can assemble the entire user journey and get the visualization of the entire flow from session start until session end.Taken from Front-end-Observability-Whitepaper by Honeycomb
For now I see these packages exist independently, and looking into the code of each I do not see an out-of-the-box way of achieving this.
I'm wondering what would it take to enable this kind of behaviour by default - or could we add configurations on spans generated by the
xml-http
andfetch
instrumentations to make them child spans at runtime?Or, of course, do you have advice on how to achieve this manually for now writing some custom logic?
Thank you!
The text was updated successfully, but these errors were encountered: