Skip to content
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: add instrumentation for undici versions >=5 <7 and global fetch API #1951

Merged

Conversation

david-luna
Copy link
Contributor

Which problem is this PR solving?

Node's fetch global API is not instrumented therefore any outgoing request made with it are not going to be traced.
Ref: open-telemetry/opentelemetry-js#4333

The fetch API is using undici under the hood and diagnostic channels emit info also when fetch is used. So this instrumentation works for:

  • apps using fetch
  • apps using undici
  • and apps using both

Short description of the changes

  • Add new instrumentation for undici package
  • Add tests for fetch and undici

@david-luna david-luna marked this pull request as draft February 22, 2024 16:40
Copy link

codecov bot commented Feb 22, 2024

Codecov Report

Merging #1951 (e10ac98) into main (dfb2dff) will decrease coverage by 0.16%.
Report is 35 commits behind head on main.
The diff coverage is 98.36%.

Additional details and impacted files
@@            Coverage Diff             @@
##             main    #1951      +/-   ##
==========================================
- Coverage   90.97%   90.82%   -0.16%     
==========================================
  Files         146      148       +2     
  Lines        7492     7672     +180     
  Branches     1502     1537      +35     
==========================================
+ Hits         6816     6968     +152     
- Misses        676      704      +28     
Files Coverage Δ
...rumentation-undici/src/enums/SemanticAttributes.ts 100.00% <100.00%> (ø)
plugins/node/instrumentation-undici/src/undici.ts 98.36% <98.36%> (ø)

... and 8 files with indirect coverage changes

@david-luna david-luna marked this pull request as ready for review February 23, 2024 14:28
Copy link
Member

@pichlermarc pichlermarc left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for working on this 🚀
(some comments from a very quick pass, detailed review to follow 🙂)

.github/component_owners.yml Show resolved Hide resolved
Copy link
Member

@JamieDanielson JamieDanielson left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks so much for working on this! I tested it out locally and it works great 🎉

I've added some suggestions for a few typos (those should be one-click-commit), and also I'd like to rethink the semantic attributes approach and instead use the semantic-convention package. It will then use some older conventions, yes, but it will be aligned with the other instrumentations. Then when we're ready we can update the semantic convention package for all instrumentations.

.github/component_owners.yml Show resolved Hide resolved
*/

// DO NOT EDIT, this is an Auto-generated file from scripts/semconv/templates//templates/SemanticAttributes.ts.j2
export const SemanticAttributes = {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hm, I'm not sure it's a good idea to set semantic attributes here in this instrumentation instead of using the semantic convention package. Is there a reason we are doing this? I would suggest using the @opentelemetry/semantic-conventions package instead. For example, here is a section in the http instrumentation using the semantic attributes.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the motivation is to use the latest version of semantic conventions and the way (as agreed in the SIG). The current version available miss most of the attributes:

  • http.request.method
  • url.full
  • url.path
  • url.query
  • url.scheme
  • server.address
  • server.port
  • user_agent.original
  • network.peer.address
  • network.peer.port
  • ...

We could import semantic conventions for a couple of attributes but the rest are not available yet therefore we need to have it in this package and replace them when we finally get semconv updated

Copy link
Member

@pichlermarc pichlermarc Mar 5, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, we did this with a couple of packages already where we needed names that were not available in @opentelemetry/semantic-conventions yet. As David said, the package is very outdated but we can't re-generate it until @opentelemetry/[email protected], as it's already stable.

I agree that it's not optimal, but let's do it like this for now where we add it to the instrumentation package then follow-up once the @opentelemetry/[email protected] situation is solved.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay, sorry I missed that conversation about adding them here. My bigger concern really is about the http semantic conventions that changed, and trying to be consistent with other instrumentations and help end users. For example, look at this trace that contains both http and undici instrumentation. The http instrumentation uses the older semantic conventions, and the undici uses the newer. This means the same fields have different attribute names, which can be difficult for folks to deal with and compare in their backend. For the attributes that are the same, can we use the old ones and/or introduce the environment variable for http/dup to let folks get both?

old and new http attributes in trace

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay, sorry I missed that conversation about adding them here. My bigger concern really is about the http semantic conventions that changed, and trying to be consistent with other instrumentations and help end users. For example, look at this trace that contains both http and undici instrumentation. The http instrumentation uses the older semantic conventions, and the undici uses the newer. This means the same fields have different attribute names, which can be difficult for folks to deal with and compare in their backend. For the attributes that are the same, can we use the old ones and/or introduce the environment variable for http/dup to let folks get both?

Aaah, I see. I completely agree that the inconsistency is a major headache. However, I it's in accordance with the semantic conventions for a new instrumentation to only emit new attributes. If we start requiring new instrumentations to also do that, we'll be burning a lot of our time doing so.

I think the better way forward to solve the issue would be to actually update the HTTP instrumentation to allow dual-emitting of old and new attributes as defined here.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd volunteer on update the HTTP instrumentation. I wonder if undici instrumentation should be blocked until HTTP has the dual mode

Copy link
Member

@pichlermarc pichlermarc Mar 6, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@david-luna IMO it should not block this PR as it does not make the package part of the auto-instrumentation package. Users already explicitly opt-in to the new semconv based telemetry by installing and using the undici-instrumentation directly.

@david-luna david-luna requested a review from pichlermarc March 27, 2024 22:24
This instrumetation subscribes to certain [diagnostics_channel](https://nodejs.org/api/diagnostics_channel.html) to intercept the client requests
and generate traces and metrics. In particular tracing spans are started when [undici:request:create](https://undici.nodejs.org/#/docs/api/DiagnosticsChannel?id=undicirequestcreate)
channel receives a message and ended when [undici:request:trailers](https://undici.nodejs.org/#/docs/api/DiagnosticsChannel?id=undicirequesttrailers) channel receive a message.
This means the full reponse body is received when the instrumentation ends the span.
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems a little unclear - how about This means the full response body is received within the span if that's correct, or This means the full response body has been received when the instrumentation ends the span

(typo in reponse as well)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thanks for your feedback :) I'm inclined to replace it with the 2nd option you gave

@david-luna david-luna requested a review from GraemeF April 3, 2024 11:43
Copy link
Member

@pichlermarc pichlermarc left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A final round of nits; thanks for working on this. 🙂

plugins/node/instrumentation-undici/README.md Outdated Show resolved Hide resolved
plugins/node/instrumentation-undici/README.md Outdated Show resolved Hide resolved
plugins/node/instrumentation-undici/test/undici.test.ts Outdated Show resolved Hide resolved
plugins/node/instrumentation-undici/package.json Outdated Show resolved Hide resolved
Copy link
Contributor

@trentm trentm left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM. Nice work.

@trentm trentm merged commit fe18e2f into open-telemetry:main Apr 4, 2024
15 checks passed
@dyladan dyladan mentioned this pull request Apr 4, 2024
@pckilgore
Copy link

Thanks to everyone who put time into this. Can't wait to let it rip.

maryliag pushed a commit to maryliag/opentelemetry-js-contrib that referenced this pull request Apr 9, 2024
…` and global `fetch` API (open-telemetry#1951)

Closes: open-telemetry/opentelemetry-js#4333
Co-authored-by: Jamie Danielson <[email protected]>
Co-authored-by: Trent Mick <[email protected]>
Co-authored-by: Marc Pichler <[email protected]>
@Lp-Francois
Copy link

Thanks so much for this feature @david-luna 🙏 🥳

Just tested it with our micro-services and it works great 😍

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants