Skip to content

Conversation

@PROFeNoM
Copy link
Contributor

@PROFeNoM PROFeNoM commented Dec 23, 2025

What does this PR do?

Adds multi-tenant API key support for LLM Observability, enabling platforms to route LLMObs telemetry to different Datadog organizations from a single process.

New API:

await llmobs.withRoutingContext({ ddApiKey, ddSite }, async () => {
  // All LLMObs spans here route to the specified Datadog org
})

Motivation

Multi-tenant AI platforms need to send LLM Observability data to their customers' Datadog organizations. This enables:

  • Customer-specific trace visibility
  • Data isolation between tenants
  • Compliance with data residency requirements (different DD sites per customer)

Implementation

  withRoutingContext({ ddApiKey, ddSite }, fn)
      ↓ AsyncLocalStorage
  registerLLMObsSpan()
      ↓ captures routing to span tags
  span.finish()
      ↓
  SpanProcessor.process()
      ↓ extracts routing from tags
  writer.append(event, routing)
      ↓ routes to correct buffer
  setInterval flush()
      ↓ flushes each buffer to its endpoint

Key Changes:

  • withRoutingContext(options, fn) method added to LLMObs SDK (uses AsyncLocalStorage)
  • Routing context captured at span creation time
  • BaseLLMObsWriter refactored to multi-buffer architecture (one buffer per API key)
  • Each buffer flushes independently to its corresponding endpoint
  • Agentless mode only

Testing

  • writers/multi-tenant.spec.js - Tests for buffer routing, endpoint construction, API key isolation, context nesting, and concurrency

@codecov
Copy link

codecov bot commented Dec 23, 2025

Codecov Report

❌ Patch coverage is 51.28205% with 38 lines in your changes missing coverage. Please review.
✅ Project coverage is 86.12%. Comparing base (b9e9246) to head (a3d89ff).

Files with missing lines Patch % Lines
packages/dd-trace/src/llmobs/writers/base.js 59.25% 22 Missing ⚠️
packages/dd-trace/src/llmobs/sdk.js 0.00% 11 Missing ⚠️
packages/dd-trace/src/llmobs/tagger.js 40.00% 3 Missing ⚠️
packages/dd-trace/src/llmobs/index.js 0.00% 1 Missing ⚠️
packages/dd-trace/src/llmobs/noop.js 0.00% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##           master    #7158      +/-   ##
==========================================
- Coverage   86.25%   86.12%   -0.14%     
==========================================
  Files         513      513              
  Lines       22054    22106      +52     
==========================================
+ Hits        19023    19039      +16     
- Misses       3031     3067      +36     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@PROFeNoM
Copy link
Contributor Author

@codex review

@github-actions
Copy link

github-actions bot commented Dec 23, 2025

Overall package size

Self size: 4.41 MB
Deduped: 5.24 MB
No deduping: 5.24 MB

Dependency sizes | name | version | self size | total size | |------|---------|-----------|------------| | import-in-the-middle | 2.0.0 | 68.46 kB | 797.03 kB | | dc-polyfill | 0.1.10 | 26.73 kB | 26.73 kB |

🤖 This report was automatically generated by heaviest-objects-in-the-universe

@chatgpt-codex-connector
Copy link

To use Codex here, create a Codex account and connect to github.

@datadog-datadog-prod-us1
Copy link

datadog-datadog-prod-us1 bot commented Dec 23, 2025

⚠️ Tests

Fix all issues with Cursor

⚠️ Warnings

❄️ 1 New flaky test detected

[email protected] esm early flake detection does not run EFD if the known tests request fails from integration-tests/cypress/cypress.spec.js (Datadog) (Fix with Cursor)
Cannot read properties of undefined (reading 'content')

ℹ️ Info

🧪 All tests passed

This comment will be updated automatically if new data arrives.
🔗 Commit SHA: a3d89ff | Docs | Datadog PR Page | Was this helpful? Give us feedback!

@pr-commenter
Copy link

pr-commenter bot commented Dec 23, 2025

Benchmarks

Benchmark execution time: 2026-01-20 15:52:12

Comparing candidate commit a3d89ff in PR branch alex/MLOB-4999_multi-tenant-routing-context-support with baseline commit b9e9246 in branch master.

Found 0 performance improvements and 0 performance regressions! Performance is the same for 233 metrics, 27 unstable metrics.

@PROFeNoM PROFeNoM force-pushed the alex/MLOB-4999_multi-tenant-routing-context-support branch 2 times, most recently from b34e1f5 to e531090 Compare January 5, 2026 09:36
@PROFeNoM PROFeNoM marked this pull request as ready for review January 5, 2026 09:47
@PROFeNoM PROFeNoM requested a review from a team as a code owner January 5, 2026 09:47
this._eventType = eventType

this._buffer = []
this._buffers = new Map()
Copy link
Collaborator

Choose a reason for hiding this comment

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

Please use private properties instead of underscores for all changed properties and new ones. Changing old ones is nice to have as separate commit :)

Please also add a comment to our Claude.md file that highlights this. Otherwise new code changes will likely come up by the AI that use the underscore instead.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done. Converted to # private syntax where possible (#buffers, #getMaskedRoutingKey, #cleanupEmptyBuffers, #getUrlForRouting)

Kept _getRoutingKey and _getOrCreateBuffer with underscore because LLMObsSpanWriter (subclass) needs to access them.

Also added the convention to AGENTS.md (symlink to claude.md ?) under "Class Properties and Methods".

Copy link
Contributor Author

Choose a reason for hiding this comment

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

FYI, I did keep things like get _buffer, set _buffer with the underscore because they are backward compatibility shims. You were not thinking about changing them as well, right?

@PROFeNoM PROFeNoM requested a review from a team as a code owner January 6, 2026 09:15
@sabrenner sabrenner self-requested a review January 6, 2026 14:42
Copy link
Collaborator

@sabrenner sabrenner left a comment

Choose a reason for hiding this comment

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

mostly small comments but one larger implementation comment i'm curious on your thoughts on. but overall the logic makes sense to me and the sdk api change looks good pending some type definition updates!

@PROFeNoM PROFeNoM marked this pull request as draft January 7, 2026 10:42
@PROFeNoM PROFeNoM marked this pull request as ready for review January 7, 2026 15:32
Copy link
Collaborator

@sabrenner sabrenner left a comment

Choose a reason for hiding this comment

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

left a question on the test file added!

Copy link
Collaborator

@sabrenner sabrenner left a comment

Choose a reason for hiding this comment

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

looks good to me now! just nits, plus some of the nested routing context tests are failing, i'm happy to help with looking into those, so lmk

@PROFeNoM PROFeNoM marked this pull request as draft January 15, 2026 10:18
@PROFeNoM PROFeNoM marked this pull request as ready for review January 15, 2026 14:50
Copy link
Collaborator

@sabrenner sabrenner left a comment

Choose a reason for hiding this comment

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

this looks great now! just one small comment (barring no changes for supporting evals in this as well, see below, i promise it's the last one 😭) about the function name we should consider before shipping, but then i'll approve.

i followed up offline, but if we're not supporting evals in this pr we should call that out for those looking over release notes

@PROFeNoM PROFeNoM force-pushed the alex/MLOB-4999_multi-tenant-routing-context-support branch from 3051004 to a9c0186 Compare January 20, 2026 15:35
Copy link
Collaborator

@sabrenner sabrenner left a comment

Choose a reason for hiding this comment

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

really awesome job!! 🚢

@PROFeNoM PROFeNoM merged commit cb8bc8d into master Jan 20, 2026
796 checks passed
@PROFeNoM PROFeNoM deleted the alex/MLOB-4999_multi-tenant-routing-context-support branch January 20, 2026 16:09
dd-octo-sts bot pushed a commit that referenced this pull request Jan 21, 2026
* feat(routing): implement multi-tenant routing context support

* Removed default parameters from getCurrentRouting, now returns null if no routing context is available.

* restore comment + use size AFTER truncation to make flushing decision

* refactor(routing-context): simplify getCurrentRouting function and enhance withRoutingContext documentation; add test for empty ddApiKey

* Backward compat comment + Nested context test

* fix: API Key Logged in Debug Output

* chore: remove unnecessary comments

* Converted to private # syntax, revised tests, and added rule to AGENTS.md

* fix

* #originalEndpoint

* remove some redundancies

* add comment for legacy

* refactor(routing-context): implement withRoutingContext directly in LLMObs class, remove legacy routing-context module, and enhance multi-tenant event handling with isolated buffers

* refactor

* refactor

* warn + private methods

* refactor(llmobs): simplify warning message for nested routing context and update tests to reflect changes

* Update AGENTS.md

Co-authored-by: Ruben Bridgewater <[email protected]>

* test(llmobs): enhance multi-tenant routing tests with improved assertions and context handling

* refactor(llmobs): introduce LLMObsBuffer for improved event handling and update buffer management in BaseLLMObsWriter

* trim redundancy

* avoid double /evp_proxy/v2/... prefix

* feat(llmobs): add warning for routing context usage in agent proxy mode to improve user awareness

* lint

* Sam's code enhancements

* rename withRoutingContext to routingContextt

* add support for submitEvaluation

* handle signature change

---------

Co-authored-by: Ruben Bridgewater <[email protected]>
@dd-octo-sts dd-octo-sts bot mentioned this pull request Jan 21, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants