Skip to content

Instrument fetch (undici) for HTTP client spans - #190

Closed
Jackson Weber (JacksonWeber) wants to merge 1 commit into
microsoft:mainfrom
JacksonWeber:jacksonweber/undici-http-client-spans
Closed

Instrument fetch (undici) for HTTP client spans#190
Jackson Weber (JacksonWeber) wants to merge 1 commit into
microsoft:mainfrom
JacksonWeber:jacksonweber/undici-http-client-spans

Conversation

@JacksonWeber

Copy link
Copy Markdown
Contributor

Summary

Outgoing LLM HTTP calls produced no HTTP client spans. The distro only registered @opentelemetry/instrumentation-http, which patches Node's core http/https modules — but the OpenAI Node SDK used by LangChain (ChatOpenAI / AzureChatOpenAI) issues its requests via the global fetch (undici) on Node 18+, which was never instrumented.

This registers @opentelemetry/instrumentation-undici (enabled by default) so fetch-based HTTP client spans are produced.

Changes

  • Add @opentelemetry/instrumentation-undici@^0.29.0 (matches the pinned @opentelemetry/instrumentation@^0.219.0).
  • Add undici?: UndiciInstrumentationConfig to InstrumentationOptions; enabled by default.
  • Register UndiciInstrumentation in createInstrumentations.
  • Add undici to the A365 disabled-by-default instrumentations.
  • Guard against self-instrumentation: when the fetch-based A365 exporter is active, a merged undici ignoreRequestHook skips its export origin. (Undici does not honor tracing suppression, so exporter traffic would otherwise be traced as spurious dependency spans on other exporters, e.g. Azure Monitor.)

Tests

  • New test/internal/unit/distro/instrumentations.test.ts (10 tests): undici registered by default / disabled on request; ignore-hook filters exporter origins while tracing real fetch; delegates to caller-provided hooks; caller config is cloned not mutated; _resolveA365ExporterOrigins resolution.
  • Updated two SDKStats bitmap assertions in main.test.ts (undici bit now auto-included).
  • Full unit suite (907) + functional suite (30) pass; build + lint green.
  • Verified end-to-end in a sample app: a direct fetch() and a LangChain ChatOpenAI call both emit HTTP client spans (incl. the POST …/chat/completions LLM request); disabling undici reproduces the missing-span behavior.

The distro only registered @opentelemetry/instrumentation-http (Node core
http/https). The OpenAI SDK used by LangChain issues requests via the global
fetch (undici) on Node 18+, so LLM HTTP calls produced no client spans.

Register @opentelemetry/instrumentation-undici (enabled by default). When the
fetch-based A365 exporter is active, a merged undici ignoreRequestHook skips
its export origin so telemetry traffic is not self-traced (undici does not
honor tracing suppression). Adds unit tests for the registration wiring, the
ignore-hook behavior, and A365 origin resolution.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

This PR adds Undici (fetch) instrumentation to ensure outgoing HTTP client spans are emitted for fetch-based SDKs (notably the OpenAI Node SDK used by LangChain) on Node 18+ where fetch is backed by Undici and is not covered by the core http/https instrumentation.

Changes:

  • Add @opentelemetry/instrumentation-undici and enable it by default via InstrumentationOptions.undici.
  • Register UndiciInstrumentation in createInstrumentations, including an optional origin-based ignoreRequestHook to prevent exporter self-instrumentation.
  • Add unit tests covering undici registration/config behavior and A365 exporter-origin resolution; update SDKStats bitmap assertions accordingly.

Reviewed changes

Copilot reviewed 8 out of 9 changed files in this pull request and generated no comments.

Show a summary per file
File Description
test/internal/unit/main.test.ts Updates SDKStats instrumentation bitmap assertions to include UNDICI and adds coverage for disabling undici via options.
test/internal/unit/distro/instrumentations.test.ts New unit tests validating undici instrumentation registration/config and A365 exporter-origin resolution logic.
src/types.ts Adds undici?: UndiciInstrumentationConfig to the public instrumentation options type with explanatory docs.
src/shared/config.ts Enables undici instrumentation by default in internal defaults and updates the documented list of supported instrumentations.
src/distro/instrumentations.ts Registers UndiciInstrumentation and composes an ignoreRequestHook when exporter origins should be filtered.
src/distro/distro.ts Adds undici to A365 “disabled by default” list and resolves exporter origins to avoid tracing exporter traffic via undici.
package.json Adds @opentelemetry/instrumentation-undici dependency.
package-lock.json Adds lock entries for @opentelemetry/instrumentation-undici.
CHANGELOG.md Documents the new fetch/undici instrumentation feature under Unreleased.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/distro/distro.ts
*
* @internal
*/
export function _resolveA365ExporterOrigins(a365Config: A365Configuration): string[] {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

A little confused here, why do we need to do this? I think A365 drops the http spans anyways.

@rads-1996 Radhika Gupta (rads-1996) left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Do you mind sharing a screenshot of the spans?

@JacksonWeber

Copy link
Copy Markdown
Contributor Author

Superseded by #191, which includes this PR's exact commit (a3d5558, the undici/fetch HTTP client span instrumentation) as its first commit, plus the LangChain init-race fix, GenAI span-kind corrections, and wrapRunExecution client-span nesting. Closing in favor of #191.

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.

3 participants