open-telemetry / opentelemetry-js

OpenTelemetry JavaScript Client
https://opentelemetry.io
Apache License 2.0
2.57k stars 743 forks source link

[next] Use diagnostics_channel for http instrumentations #4319

Open dyladan opened 7 months ago

dyladan commented 7 months ago

Now that we've removed support for old runtimes, we can use the new diagnostics channels to instrument node core http libraries.

Known issues

http.client.request.start - event.request is not writeable

Because the event is emitted after the request is already in flight, we cannot modify the headers. This means we cannot add the required tracing headers for context propagation. We will still need to rely on patching the http and https modules for at least this purpose unless the http channel implementations change.

If nodejs adds something similar to undici's undici:request:create, this issue may be solved and we may be able to remove all manual monkeypatching from the instrumentation. In this case, we may even be able to remove {require|import}-in-the-middle.

Context Management

See https://github.com/open-telemetry/opentelemetry-js/issues/4319#issuecomment-1823302033 below

dyladan commented 7 months ago

/cc @legendecas

Flarna commented 7 months ago

Another topic is likely the context manage.

Hooks to get lifecycle of an request is enough to start/end a span and maybe even inject headers. But ContextManger requires to wrap the http.request() call with context.with() to get the context with the span active. Otherwise an inner DNS request wouldn't result in a child span.

There is an advanced diag channel API TracingChannel which puts AsyncLocalStore and DiagChannel together. But as of now noone did the work to actually adapt the http implementation in node to use this.

dyladan commented 7 months ago

Thanks for the info. It came up in the meeting today but nobody brought up the TracingChannel point. I think the current solution of using bind() on the request/response objects should be ok, but i'll make sure to test that.

Flarna commented 7 months ago

I think for client http the req/res objects are bound on the context holding the parent span. This is because whatever is triggered in e.g. a data or response event is actually no inner operation of the http request (which would be a child span) - it's a followup operation running afterwards so a sibling.

github-actions[bot] commented 5 months ago

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.

github-actions[bot] commented 4 months ago

This issue was closed because it has been stale for 14 days with no activity.