Repository navigation
Conversation
|
Review requested:
|
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## main #66587 +/- ##
==========================================
- Coverage 92.79% 90.43% -2.36%
==========================================
Files 422 796 +374
Lines 193669 277648 +83979
Branches 29886 53308 +23422
==========================================
+ Hits 179712 251102 +71390
- Misses 13630 16948 +3318
- Partials 327 9598 +9271
🚀 New features to boost your workflow:
|
jasnell
left a comment
There was a problem hiding this comment.
First pass... Generally looks reasonable. Main concern is on instrumentation cost. Left a couple comments.
| } | ||
|
|
||
| setAttribute(key, value) { | ||
| this.#attributes[key] = value; |
There was a problem hiding this comment.
#attributes is going to be put into a slow dictionary mode with a internal shape transition every time an attribute is set... Meaning this is going to have a non-trivial cost.
Could this use a SafeMap instead?
Obviously that makes getAttributes trickier below but I would assume that setAttribute is the hotter path?
There was a problem hiding this comment.
Fair point. The set of attribute keys is closed in this PR (no public API, only the internal instrumentations write attributes), so I went the other way: the attributes object is preallocated with the full key set, one identical shape for every span, and writes only ever hit existing properties. Unused keys are skipped at export time.
This is something that'll need to be revisited once there's a public API, of course.
| } | ||
|
|
||
| addEvent(name, attributes) { | ||
| ArrayPrototypePush(this.#events, { |
There was a problem hiding this comment.
How many events might we expect? If it's a lot, or completely unbounded, this becomes quadratic after a while.
There was a problem hiding this comment.
Right now, without a public API, there's only ever one, and that's for errors.
I left a TODO to cap this (as is typically done in OTel-esque SDKs) once there's a public API.
| The subsystem is independent of the OpenTelemetry JavaScript packages. It | ||
| is not interoperable with `@opentelemetry/api`, and spans created by one | ||
| are not visible to the other. Running both in the same process produces | ||
| duplicate trace and span IDs. The built-in instrumentation also | ||
| overwrites the `traceparent` (and, when present, `tracestate`) header on | ||
| outgoing HTTP requests, discarding whatever a userland propagator may | ||
| have set. Users should run either the built-in subsystem or a userland | ||
| OpenTelemetry SDK, not both. |
There was a problem hiding this comment.
Then I wonder what the purpose of this is. From my perspective, this feature should work in one of two ways:
- Provides an implementation of the API such that compliant instrumentations can register with it and it delivers the appropriate signals data to a collector.
- Registers with whatever OTEL implementation is present such that the signals data is inlined correctly.
With the caveats highlighted in this paragraph, I'm just not clear what this accomplishes.
There was a problem hiding this comment.
I think we need to start somewhere. I can see this eventually working with userland sdk's before it comes out of experimental but in order to make progress at all we should work incrementally here.
There was a problem hiding this comment.
Indeed. This is a step 1 (or maybe a step 0). It serves two purposes:
- Provide OOTB (limited) tracing with no dependencies or code changes.
- Provide a baseline implementation of the data model and egress pipeline in core. This can be followed up in future PRs with all kinds of ideas, like:
- A
TracerProviderimplementation, so as to support@opentelemetry/api - Prototyping a much more minimal interface, like
tracingin Rust, which could then be adopted as official by OTel (like .NET's prior art). - Providing a default core for OTel SDK.
- All kinds of other options!
- A
Basically this PR exists to eliminate the more contentious parts of my previous one, so that we can avoid blocking this core functionality while we deliberate on that.
There was a problem hiding this comment.
I might miss some contexts here about the goal of OpenTelemetry support. OpenTelemetry specification defines a baseline data model and egress pipeline. Would the goal of this built-in support comply with the https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/trace/sdk.md ?
There was a problem hiding this comment.
Would the goal of this built-in support comply with the open-telemetry/opentelemetry-specification@main/specification/trace/sdk.md ?
Eventually, yes, that's an option for future PRs, as indicated by the first bullet point in the purpose number two in my previous comment. This PR only creates OTLP tracing data based on inbound and outbound HTTP calls, and ships it off to a collector. All other concerns/discussions are left for future PRs, and the feature should probably stay experimental until those are figured out.
There was a problem hiding this comment.
Thank you for clarifying! I'm trying to understand the goal of this PR and the future path on a built-in Observability support. So I'd like to make sure the goal is clear even if this is an initial experimental PR.
The PR might be good on its own, but a future work that may create incompat or create preferential/minimal API towards particular observability data backend vendors must be a non-starter. I'd be wary of future paths like "I don't use xxx so let's not implement xxx in OpenTelemetry", or "I need xxx but it's not in OpenTelemetry, let's skip OpenTelemetry and do xxx".
OpenTelemetry has been the de-facto standard and a collaborative project between observability backend vendors, so I'd appreciate that a vendor neutral path is the goal of Node.js built-in observability support.
0128458 to
ac2de76
Compare
Qard
left a comment
There was a problem hiding this comment.
Overall LGTM, though is there any particular reason you chose to limit this to only the main thread? Seems to me like it'd be useful to have this get set up on every worker thread.
|
@jsumners-nr The vendor I work for is also not likely to use this at this stage. It does provide some utility for situations where users can't or won't inject new code into a service, but are happy to change environment variables. As mentioned elsewhere, future PRs can make this more useful to o11y vendors. In the meantime, can you clarify what you're looking for with DC here? |
We chatted privately and concluded with a mutual understanding. |
Adds experimental OpenTelemetry tracing support, as described in the included docs. Tracing is activated via environment variables only and requires the --experimental-otel flag. There is no programmatic API yet. Custom instrumentation is not supported. Assisted-by: pi:glm-5.3 Signed-off-by: Bryan English <bryan@bryanenglish.com>
|
Adding |
Adds experimental OpenTelemetry tracing support, as described in the included docs. Tracing is activated via environment variables only and requires the --experimental-otel flag.
There is no programmatic API yet. Custom instrumentation is not supported.
Assisted-by: pi:glm-5.3
This is a re-hash of #61907 restricting it to the OOTB behaviour only, leaving any API surface as an exercise for future PRs (and decisions around them). All configuration is currently through env vars. Most if not all still-relevant review comments from the previous PR are addressed here. In addition, a benchmark is added to measure future improvements.
Metrics and logging signals are also left to future PRs.