-
Notifications
You must be signed in to change notification settings - Fork 810
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
feat(http): Allow to opt-out of instrumenting incoming/outgoing requests #4643
feat(http): Allow to opt-out of instrumenting incoming/outgoing requests #4643
Conversation
Hi @mydea This is an interesting feature. I think having more control over the instrumentation is good :)
I didn't get that. Not instrumenting the incoming requests is actually suppressing tracing and metrics for all incoming requests. Also I'm not an expert but I wonder if there would be trace context issues if one of the instrumentations is disabled. I guess there will be no issues if both instrumentations are using the OTEL API but it would be an issue if one of them does not. |
It's not the same, because if we suppress tracing, any other auto-instrumentation inside of this will also be suppressed, vs. not suppressing it at all just does nothing. It's something like this: function incomingHttpRequest() {
// this does something, imagine this is inside of `http`
}
suppressTracing(context.active(), () => {
return nextjsInstrumentHttp(incomingHttpRequest);
}); |
This PR 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. |
Any thoughts about merging this? I think it would be valuable, but also happy to close otherwise... |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@mydea Thanks for the PR and sorry for the long delay.
We discussed this in the OTel JS SIG meeting last week: https://docs.google.com/document/d/1tCyoQK49WVcE-x8oryZOTTToFm7sIeUhxFPm9g-qL1k/edit#heading=h.a8usr2qdq202
The carrying argument, IMO, was that while the instrumentations are "experimental" (i.e. pre-1.0), we should experiment with them more. IOW, this PR generally sounds good. Some specifics below.
Also note the link from the SIG meeting notes: https://opentelemetry.io/docs/zero-code/java/agent/configuration/#instrumentation-span-suppression-behavior
What the OTel Java SDK is offering is interesting. IIUC, the default span-suppression-strategy=semconv
setting would handle the use case you are describing. From the Java code implementing that semconv strategy:
* <p>For example, nested HTTP client spans will be suppressed; but an RPC client span will not
* suppress an HTTP client span, if the instrumented RPC client uses HTTP as transport.
Of course, this PR isn't expected to implement something so general.
Regarding your use case: Are you getting an HTTP spec from Next.js with spanKind=SERVER for an incoming request, and then a child span of that from instrumentation-http that is also spanKind=SERVER?
| `instrumentOutgoingRequests` | `boolean` | Set to false to avoid instrumenting outgoing requests at all. | | ||
| `instrumentIncomingRequests` | `boolean` | Set to false to avoid instrumenting incoming requests at all. | |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Some issues here:
- Generally the JS SDK, at least, tries to use config vars that are false-y by default. This is because then a
false
value is treated the same as anundefined
value. The<Instrumentation>._config
object on the various instrumentations in this and the opentelemetry-js-contrib repo are often just a sparse object where undefined config vars implies the default value. (The huge exception here is theenabled: true
config var on all instrumentations. :sadface:) It would potentially be error prone to have a config var wherefalse
andundefined
are different behaviours. - From the config vars and documentation, it isn't clear which of
instrumentOutgoingRequests
andignoreOutgoingRequestHook
should take precedence.
Without complicating this PR by getting too general, one possible option:
- Change the verb from "instrument" to "disable", e.g.
disableIncomingRequestInstrumentation
. This flips the boolean sense to deal with issue 1. The term "disable" is closer to the enable/disable state on the an entire Instrumentation, which helps imply that this take precedence over theignore*Hook
vars -- though the docs should still spell that out.
What do you think?
- It isn't clear from the docs here that
instrument*
vars are just skipping this one span and theignore*
are supressing. What exactly the existingignore*RequestHook
vars were doing already wasn't clear -- which is an existing issue. Even the term "suppress" here isn't clear ... given that the OTel Java SDK is using (https://opentelemetry.io/docs/zero-code/java/agent/configuration/#instrumentation-span-suppression-behavior) "suppression" to mean just dropping a span and not suppressing the full trace.
- I think this could be solved by expanding on the description (or in a
[1] ...
-note below the options table) in this section of the README. Personally, I think mentioning the particular use case could be helpful for other users to understand why they might want to use this, and to inform a possible future generalization.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Changing the name to disableIncomingRequestInstrumentation
makes a lot of sense to me, that's def. better! I'll update the PR accordingly. I'll also update the docs part to explain this better, thanks for the feedback!
); | ||
if (isWrapped(moduleExports.get)) { | ||
this._unwrap(moduleExports, 'get'); | ||
if (this._getConfig().instrumentOutgoingRequests !== false) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since your PR, there has been a change from _getConfig()
to getConfig()
that you'll need to update for. Let me know if you need help with that.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
all good I believe, I rebased on master and incorporated the changes, should be OK!
101488b
to
321f07c
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks!
I think it would still be worthwhile to have a paragraph in the README options section mentioning that the disable...
settings effectively take precedence over others. However, that could be done in a separate PR -- and I'm happy to do that README update.
I'll leave this for a little bit and probably merge it tomorrow.
^^ I merged from main, dealing with the http.ts conflict resulting from my merge of #4866 |
…sts (open-telemetry#4643) * feat(http): Allow to opt-out of instrumenting incoming/outgoing requests * fix tests * PR feedback * add a changelog entry --------- Co-authored-by: Trent Mick <[email protected]>
this._unwrap(moduleExports, 'request'); | ||
this._unwrap(moduleExports, 'get'); | ||
this._unwrap(moduleExports.Server.prototype, 'emit'); | ||
if (!this.getConfig().disableOutgoingRequestInstrumentation) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
wouldn't this be better using the isWrapped
check ?
if (isWrapped(module.request)) {
this._unwrap(module, 'request')
}
This PR introduces two new options for the HTTP instrumentation:
disableIncomingRequestInstrumentation
&disableOutgoingRequestInstrumentation
.If these are set to
true
, the instrumentation will completely skip instrumenting the respective methods on the http(s) modules.Why is this useful
This can be useful/necessary if there is other instrumentation that handles incoming or outgoing requests. For example, Next.js handles incoming requests but not outgoing http requests - today, this leaves the user in a weird state where either they add the http instrumentation and get duplicated incoming request spans, or they do not add it and get no outgoing request spans at all.
Note that the existing options like
ignoreIncomingRequestHook
cannot be used for this, because they actually suppress tracing, which is not necessarily what we want there.