feat(llmobs): implement multi-tenant routing context support#15781
feat(llmobs): implement multi-tenant routing context support#15781
Conversation
|
@codex review |
|
To use Codex here, create a Codex account and connect to github. |
Performance SLOsComparing candidate alex/MLOB-4999_multi-tenant-routing-context-support (2c11fcf) with baseline main (e327013) 📈 Performance Regressions (3 suites)📈 iastaspects - 118/118✅ add_aspectTime: ✅ 17.940µs (SLO: <20.000µs 📉 -10.3%) vs baseline: 📈 +21.3% Memory: ✅ 42.585MB (SLO: <43.250MB 🟡 -1.5%) vs baseline: +4.9% ✅ add_inplace_aspectTime: ✅ 14.976µs (SLO: <20.000µs 📉 -25.1%) vs baseline: +0.8% Memory: ✅ 42.546MB (SLO: <43.250MB 🟡 -1.6%) vs baseline: +4.8% ✅ add_inplace_noaspectTime: ✅ 0.339µs (SLO: <10.000µs 📉 -96.6%) vs baseline: -0.6% Memory: ✅ 42.546MB (SLO: <43.500MB -2.2%) vs baseline: +4.5% ✅ add_noaspectTime: ✅ 0.548µs (SLO: <10.000µs 📉 -94.5%) vs baseline: +0.5% Memory: ✅ 42.585MB (SLO: <43.500MB -2.1%) vs baseline: +5.0% ✅ bytearray_aspectTime: ✅ 18.052µs (SLO: <30.000µs 📉 -39.8%) vs baseline: ~same Memory: ✅ 42.605MB (SLO: <43.500MB -2.1%) vs baseline: +4.9% ✅ bytearray_extend_aspectTime: ✅ 23.867µs (SLO: <30.000µs 📉 -20.4%) vs baseline: +0.6% Memory: ✅ 42.625MB (SLO: <43.500MB -2.0%) vs baseline: +5.1% ✅ bytearray_extend_noaspectTime: ✅ 2.764µs (SLO: <10.000µs 📉 -72.4%) vs baseline: +0.2% Memory: ✅ 42.605MB (SLO: <43.500MB -2.1%) vs baseline: +4.9% ✅ bytearray_noaspectTime: ✅ 1.468µs (SLO: <10.000µs 📉 -85.3%) vs baseline: -1.5% Memory: ✅ 42.546MB (SLO: <43.500MB -2.2%) vs baseline: +4.8% ✅ bytes_aspectTime: ✅ 16.793µs (SLO: <20.000µs 📉 -16.0%) vs baseline: +1.3% Memory: ✅ 42.684MB (SLO: <43.500MB 🟡 -1.9%) vs baseline: +5.1% ✅ bytes_noaspectTime: ✅ 1.416µs (SLO: <10.000µs 📉 -85.8%) vs baseline: -1.0% Memory: ✅ 42.585MB (SLO: <43.500MB -2.1%) vs baseline: +4.9% ✅ bytesio_aspectTime: ✅ 55.380µs (SLO: <70.000µs 📉 -20.9%) vs baseline: ~same Memory: ✅ 42.566MB (SLO: <43.500MB -2.1%) vs baseline: +4.8% ✅ bytesio_noaspectTime: ✅ 3.295µs (SLO: <10.000µs 📉 -67.1%) vs baseline: +0.8% Memory: ✅ 42.625MB (SLO: <43.500MB -2.0%) vs baseline: +5.0% ✅ capitalize_aspectTime: ✅ 14.629µs (SLO: <20.000µs 📉 -26.9%) vs baseline: ~same Memory: ✅ 42.605MB (SLO: <43.500MB -2.1%) vs baseline: +5.0% ✅ capitalize_noaspectTime: ✅ 2.574µs (SLO: <10.000µs 📉 -74.3%) vs baseline: -0.1% Memory: ✅ 42.507MB (SLO: <43.500MB -2.3%) vs baseline: +4.7% ✅ casefold_aspectTime: ✅ 14.663µs (SLO: <20.000µs 📉 -26.7%) vs baseline: +0.2% Memory: ✅ 42.703MB (SLO: <43.500MB 🟡 -1.8%) vs baseline: +5.1% ✅ casefold_noaspectTime: ✅ 3.153µs (SLO: <10.000µs 📉 -68.5%) vs baseline: -0.9% Memory: ✅ 42.566MB (SLO: <43.500MB -2.1%) vs baseline: +4.8% ✅ decode_aspectTime: ✅ 15.542µs (SLO: <30.000µs 📉 -48.2%) vs baseline: ~same Memory: ✅ 42.566MB (SLO: <43.500MB -2.1%) vs baseline: +4.9% ✅ decode_noaspectTime: ✅ 1.590µs (SLO: <10.000µs 📉 -84.1%) vs baseline: -0.5% Memory: ✅ 42.625MB (SLO: <43.500MB -2.0%) vs baseline: +5.0% ✅ encode_aspectTime: ✅ 18.128µs (SLO: <30.000µs 📉 -39.6%) vs baseline: 📈 +23.0% Memory: ✅ 42.566MB (SLO: <43.500MB -2.1%) vs baseline: +4.9% ✅ encode_noaspectTime: ✅ 1.496µs (SLO: <10.000µs 📉 -85.0%) vs baseline: -0.3% Memory: ✅ 42.546MB (SLO: <43.500MB -2.2%) vs baseline: +4.7% ✅ format_aspectTime: ✅ 171.115µs (SLO: <200.000µs 📉 -14.4%) vs baseline: ~same Memory: ✅ 42.664MB (SLO: <43.250MB 🟡 -1.4%) vs baseline: +4.6% ✅ format_map_aspectTime: ✅ 190.937µs (SLO: <200.000µs -4.5%) vs baseline: +0.2% Memory: ✅ 42.802MB (SLO: <43.500MB 🟡 -1.6%) vs baseline: +4.8% ✅ format_map_noaspectTime: ✅ 3.780µs (SLO: <10.000µs 📉 -62.2%) vs baseline: -1.0% Memory: ✅ 42.625MB (SLO: <43.250MB 🟡 -1.4%) vs baseline: +5.0% ✅ format_noaspectTime: ✅ 3.182µs (SLO: <10.000µs 📉 -68.2%) vs baseline: +1.2% Memory: ✅ 42.507MB (SLO: <43.250MB 🟡 -1.7%) vs baseline: +4.6% ✅ index_aspectTime: ✅ 15.406µs (SLO: <20.000µs 📉 -23.0%) vs baseline: +0.8% Memory: ✅ 42.625MB (SLO: <43.250MB 🟡 -1.4%) vs baseline: +5.0% ✅ index_noaspectTime: ✅ 0.462µs (SLO: <10.000µs 📉 -95.4%) vs baseline: -0.3% Memory: ✅ 42.664MB (SLO: <43.500MB 🟡 -1.9%) vs baseline: +5.1% ✅ join_aspectTime: ✅ 16.989µs (SLO: <20.000µs 📉 -15.1%) vs baseline: +0.3% Memory: ✅ 42.585MB (SLO: <43.500MB -2.1%) vs baseline: +5.0% ✅ join_noaspectTime: ✅ 1.547µs (SLO: <10.000µs 📉 -84.5%) vs baseline: -0.7% Memory: ✅ 42.566MB (SLO: <43.250MB 🟡 -1.6%) vs baseline: +4.7% ✅ ljust_aspectTime: ✅ 20.688µs (SLO: <30.000µs 📉 -31.0%) vs baseline: +0.2% Memory: ✅ 42.684MB (SLO: <43.250MB 🟡 -1.3%) vs baseline: +5.1% ✅ ljust_noaspectTime: ✅ 2.720µs (SLO: <10.000µs 📉 -72.8%) vs baseline: +0.6% Memory: ✅ 42.585MB (SLO: <43.250MB 🟡 -1.5%) vs baseline: +4.6% ✅ lower_aspectTime: ✅ 17.979µs (SLO: <30.000µs 📉 -40.1%) vs baseline: +1.0% Memory: ✅ 42.605MB (SLO: <43.500MB -2.1%) vs baseline: +4.9% ✅ lower_noaspectTime: ✅ 2.431µs (SLO: <10.000µs 📉 -75.7%) vs baseline: -0.3% Memory: ✅ 42.546MB (SLO: <43.250MB 🟡 -1.6%) vs baseline: +4.8% ✅ lstrip_aspectTime: ✅ 17.771µs (SLO: <30.000µs 📉 -40.8%) vs baseline: +0.8% Memory: ✅ 42.605MB (SLO: <43.250MB 🟡 -1.5%) vs baseline: +4.7% ✅ lstrip_noaspectTime: ✅ 1.859µs (SLO: <10.000µs 📉 -81.4%) vs baseline: -0.8% Memory: ✅ 42.507MB (SLO: <43.500MB -2.3%) vs baseline: +4.7% ✅ modulo_aspectTime: ✅ 166.247µs (SLO: <200.000µs 📉 -16.9%) vs baseline: +0.2% Memory: ✅ 42.644MB (SLO: <43.500MB 🟡 -2.0%) vs baseline: +4.7% ✅ modulo_aspect_for_bytearray_bytearrayTime: ✅ 174.237µs (SLO: <200.000µs 📉 -12.9%) vs baseline: +0.3% Memory: ✅ 42.625MB (SLO: <43.500MB -2.0%) vs baseline: +4.5% ✅ modulo_aspect_for_bytesTime: ✅ 168.619µs (SLO: <200.000µs 📉 -15.7%) vs baseline: ~same Memory: ✅ 42.625MB (SLO: <43.500MB -2.0%) vs baseline: +4.6% ✅ modulo_aspect_for_bytes_bytearrayTime: ✅ 171.266µs (SLO: <200.000µs 📉 -14.4%) vs baseline: -0.1% Memory: ✅ 42.546MB (SLO: <43.500MB -2.2%) vs baseline: +4.3% ✅ modulo_noaspectTime: ✅ 3.673µs (SLO: <10.000µs 📉 -63.3%) vs baseline: -0.4% Memory: ✅ 42.585MB (SLO: <43.500MB -2.1%) vs baseline: +5.0% ✅ replace_aspectTime: ✅ 219.585µs (SLO: <300.000µs 📉 -26.8%) vs baseline: +3.6% Memory: ✅ 42.684MB (SLO: <44.000MB -3.0%) vs baseline: +4.3% ✅ replace_noaspectTime: ✅ 2.899µs (SLO: <10.000µs 📉 -71.0%) vs baseline: ~same Memory: ✅ 42.625MB (SLO: <43.500MB -2.0%) vs baseline: +4.9% ✅ repr_aspectTime: ✅ 1.431µs (SLO: <10.000µs 📉 -85.7%) vs baseline: +1.8% Memory: ✅ 42.644MB (SLO: <43.500MB 🟡 -2.0%) vs baseline: +4.8% ✅ repr_noaspectTime: ✅ 0.524µs (SLO: <10.000µs 📉 -94.8%) vs baseline: -0.2% Memory: ✅ 42.526MB (SLO: <43.500MB -2.2%) vs baseline: +4.8% ✅ rstrip_aspectTime: ✅ 23.053µs (SLO: <30.000µs 📉 -23.2%) vs baseline: 📈 +21.0% Memory: ✅ 42.664MB (SLO: <43.500MB 🟡 -1.9%) vs baseline: +5.1% ✅ rstrip_noaspectTime: ✅ 1.932µs (SLO: <10.000µs 📉 -80.7%) vs baseline: +0.4% Memory: ✅ 42.625MB (SLO: <43.500MB -2.0%) vs baseline: +5.1% ✅ slice_aspectTime: ✅ 15.951µs (SLO: <20.000µs 📉 -20.2%) vs baseline: +0.2% Memory: ✅ 42.625MB (SLO: <43.500MB -2.0%) vs baseline: +4.7% ✅ slice_noaspectTime: ✅ 0.597µs (SLO: <10.000µs 📉 -94.0%) vs baseline: -0.5% Memory: ✅ 42.585MB (SLO: <43.500MB -2.1%) vs baseline: +4.8% ✅ stringio_aspectTime: ✅ 53.994µs (SLO: <80.000µs 📉 -32.5%) vs baseline: ~same Memory: ✅ 42.605MB (SLO: <43.500MB -2.1%) vs baseline: +5.0% ✅ stringio_noaspectTime: ✅ 3.651µs (SLO: <10.000µs 📉 -63.5%) vs baseline: -0.1% Memory: ✅ 42.644MB (SLO: <43.500MB 🟡 -2.0%) vs baseline: +4.9% ✅ strip_aspectTime: ✅ 17.596µs (SLO: <20.000µs 📉 -12.0%) vs baseline: -0.9% Memory: ✅ 42.526MB (SLO: <43.500MB -2.2%) vs baseline: +4.8% ✅ strip_noaspectTime: ✅ 1.868µs (SLO: <10.000µs 📉 -81.3%) vs baseline: +0.2% Memory: ✅ 42.546MB (SLO: <43.500MB -2.2%) vs baseline: +4.7% ✅ swapcase_aspectTime: ✅ 18.494µs (SLO: <30.000µs 📉 -38.4%) vs baseline: +0.4% Memory: ✅ 42.605MB (SLO: <43.500MB -2.1%) vs baseline: +5.0% ✅ swapcase_noaspectTime: ✅ 2.793µs (SLO: <10.000µs 📉 -72.1%) vs baseline: -0.5% Memory: ✅ 42.605MB (SLO: <43.500MB -2.1%) vs baseline: +5.0% ✅ title_aspectTime: ✅ 18.355µs (SLO: <30.000µs 📉 -38.8%) vs baseline: +1.3% Memory: ✅ 42.605MB (SLO: <43.000MB 🟡 -0.9%) vs baseline: +5.0% ✅ title_noaspectTime: ✅ 2.687µs (SLO: <10.000µs 📉 -73.1%) vs baseline: +0.7% Memory: ✅ 42.585MB (SLO: <43.500MB -2.1%) vs baseline: +4.9% ✅ translate_aspectTime: ✅ 24.151µs (SLO: <30.000µs 📉 -19.5%) vs baseline: 📈 +17.6% Memory: ✅ 42.566MB (SLO: <43.500MB -2.1%) vs baseline: +4.7% ✅ translate_noaspectTime: ✅ 4.328µs (SLO: <10.000µs 📉 -56.7%) vs baseline: +0.4% Memory: ✅ 42.605MB (SLO: <43.500MB -2.1%) vs baseline: +4.9% ✅ upper_aspectTime: ✅ 18.022µs (SLO: <30.000µs 📉 -39.9%) vs baseline: +0.8% Memory: ✅ 42.546MB (SLO: <43.500MB -2.2%) vs baseline: +4.7% ✅ upper_noaspectTime: ✅ 2.440µs (SLO: <10.000µs 📉 -75.6%) vs baseline: +0.4% Memory: ✅ 42.684MB (SLO: <43.500MB 🟡 -1.9%) vs baseline: +5.2% 📈 iastaspectsospath - 24/24✅ ospathbasename_aspectTime: ✅ 5.169µs (SLO: <10.000µs 📉 -48.3%) vs baseline: 📈 +20.7% Memory: ✅ 42.507MB (SLO: <43.500MB -2.3%) vs baseline: +4.7% ✅ ospathbasename_noaspectTime: ✅ 4.319µs (SLO: <10.000µs 📉 -56.8%) vs baseline: -0.9% Memory: ✅ 42.526MB (SLO: <43.500MB -2.2%) vs baseline: +4.7% ✅ ospathjoin_aspectTime: ✅ 6.267µs (SLO: <10.000µs 📉 -37.3%) vs baseline: +0.1% Memory: ✅ 42.526MB (SLO: <43.500MB -2.2%) vs baseline: +4.8% ✅ ospathjoin_noaspectTime: ✅ 6.289µs (SLO: <10.000µs 📉 -37.1%) vs baseline: +0.1% Memory: ✅ 42.507MB (SLO: <43.500MB -2.3%) vs baseline: +4.9% ✅ ospathnormcase_aspectTime: ✅ 3.567µs (SLO: <10.000µs 📉 -64.3%) vs baseline: -0.8% Memory: ✅ 42.448MB (SLO: <43.500MB -2.4%) vs baseline: +4.5% ✅ ospathnormcase_noaspectTime: ✅ 3.637µs (SLO: <10.000µs 📉 -63.6%) vs baseline: +1.0% Memory: ✅ 42.585MB (SLO: <43.500MB -2.1%) vs baseline: +4.9% ✅ ospathsplit_aspectTime: ✅ 4.913µs (SLO: <10.000µs 📉 -50.9%) vs baseline: -0.5% Memory: ✅ 42.467MB (SLO: <43.500MB -2.4%) vs baseline: +4.8% ✅ ospathsplit_noaspectTime: ✅ 5.014µs (SLO: <10.000µs 📉 -49.9%) vs baseline: -0.2% Memory: ✅ 42.467MB (SLO: <43.500MB -2.4%) vs baseline: +4.8% ✅ ospathsplitdrive_aspectTime: ✅ 3.783µs (SLO: <10.000µs 📉 -62.2%) vs baseline: +0.8% Memory: ✅ 42.467MB (SLO: <43.500MB -2.4%) vs baseline: +4.9% ✅ ospathsplitdrive_noaspectTime: ✅ 0.746µs (SLO: <10.000µs 📉 -92.5%) vs baseline: ~same Memory: ✅ 42.408MB (SLO: <43.500MB -2.5%) vs baseline: +4.4% ✅ ospathsplitext_aspectTime: ✅ 4.669µs (SLO: <10.000µs 📉 -53.3%) vs baseline: +0.8% Memory: ✅ 42.585MB (SLO: <43.500MB -2.1%) vs baseline: +4.9% ✅ ospathsplitext_noaspectTime: ✅ 4.632µs (SLO: <10.000µs 📉 -53.7%) vs baseline: -0.5% Memory: ✅ 42.644MB (SLO: <43.500MB 🟡 -2.0%) vs baseline: +5.1% 📈 telemetryaddmetric - 30/30✅ 1-count-metric-1-timesTime: ✅ 3.394µs (SLO: <20.000µs 📉 -83.0%) vs baseline: 📈 +14.1% Memory: ✅ 34.918MB (SLO: <35.500MB 🟡 -1.6%) vs baseline: +5.5% ✅ 1-count-metrics-100-timesTime: ✅ 200.359µs (SLO: <220.000µs -8.9%) vs baseline: +0.8% Memory: ✅ 34.878MB (SLO: <35.500MB 🟡 -1.8%) vs baseline: +4.7% ✅ 1-distribution-metric-1-timesTime: ✅ 3.325µs (SLO: <20.000µs 📉 -83.4%) vs baseline: +0.2% Memory: ✅ 34.918MB (SLO: <35.500MB 🟡 -1.6%) vs baseline: +5.2% ✅ 1-distribution-metrics-100-timesTime: ✅ 212.885µs (SLO: <230.000µs -7.4%) vs baseline: -0.2% Memory: ✅ 34.898MB (SLO: <35.500MB 🟡 -1.7%) vs baseline: +4.9% ✅ 1-gauge-metric-1-timesTime: ✅ 2.159µs (SLO: <20.000µs 📉 -89.2%) vs baseline: -1.0% Memory: ✅ 34.878MB (SLO: <35.500MB 🟡 -1.8%) vs baseline: +5.2% ✅ 1-gauge-metrics-100-timesTime: ✅ 135.772µs (SLO: <150.000µs -9.5%) vs baseline: -0.7% Memory: ✅ 34.839MB (SLO: <35.500MB 🟡 -1.9%) vs baseline: +5.0% ✅ 1-rate-metric-1-timesTime: ✅ 3.110µs (SLO: <20.000µs 📉 -84.5%) vs baseline: -0.1% Memory: ✅ 34.839MB (SLO: <35.500MB 🟡 -1.9%) vs baseline: +5.0% ✅ 1-rate-metrics-100-timesTime: ✅ 213.489µs (SLO: <250.000µs 📉 -14.6%) vs baseline: +1.0% Memory: ✅ 34.839MB (SLO: <35.500MB 🟡 -1.9%) vs baseline: +4.9% ✅ 100-count-metrics-100-timesTime: ✅ 20.007ms (SLO: <22.000ms -9.1%) vs baseline: -0.9% Memory: ✅ 34.819MB (SLO: <35.500MB 🟡 -1.9%) vs baseline: +4.5% ✅ 100-distribution-metrics-100-timesTime: ✅ 2.243ms (SLO: <2.550ms 📉 -12.1%) vs baseline: -0.3% Memory: ✅ 34.741MB (SLO: <35.500MB -2.1%) vs baseline: +4.4% ✅ 100-gauge-metrics-100-timesTime: ✅ 1.394ms (SLO: <1.550ms 📉 -10.0%) vs baseline: -0.5% Memory: ✅ 34.741MB (SLO: <35.500MB -2.1%) vs baseline: +4.3% ✅ 100-rate-metrics-100-timesTime: ✅ 2.186ms (SLO: <2.550ms 📉 -14.3%) vs baseline: +0.7% Memory: ✅ 34.918MB (SLO: <35.500MB 🟡 -1.6%) vs baseline: +4.9% ✅ flush-1-metricTime: ✅ 4.557µs (SLO: <20.000µs 📉 -77.2%) vs baseline: +0.3% Memory: ✅ 35.154MB (SLO: <35.500MB 🟡 -1.0%) vs baseline: +4.5% ✅ flush-100-metricsTime: ✅ 174.840µs (SLO: <250.000µs 📉 -30.1%) vs baseline: -0.5% Memory: ✅ 35.212MB (SLO: <35.500MB 🟡 -0.8%) vs baseline: +4.4% ✅ flush-1000-metricsTime: ✅ 2.171ms (SLO: <2.500ms 📉 -13.1%) vs baseline: -0.9% Memory: ✅ 36.117MB (SLO: <36.500MB 🟡 -1.0%) vs baseline: +5.0% 🟡 Near SLO Breach (16 suites)🟡 coreapiscenario - 10/10 (1 unstable)
|
…tenant-routing-context-support
1. Dictionary key ordering mismatch - Test expectations had {'role': ..., 'content': ...} but actual LLMObs code produces {'content': ..., 'role': ...} due to how Message TypedDict instances are constructed
2. Missing None routing context - The multi-tenant routing changes added a second routing parameter to enqueue(), but some tests weren't updated to include None in their mock assertions
3. metadata/tool_definitions ordering - Test utility set tool_definitions before metadata, but actual code sets them in reverse order
Codeowners resolved as |
… and update tests to reflect changes
|
let me re-read through it |
|
This pull request has been automatically closed after a period of inactivity. |
Description
Adds multi-tenant routing support to LLM Observability, enabling platforms to route telemetry to different Datadog organizations from a single process.
New Public API
Motivation
Multi-tenant AI platforms (e.g., Dust.tt) need to send LLM Observability data to their customers' Datadog organizations. This enables:
Implementation
Key details:
contextvarsfor thread-safe and async-safe context propagationapi_key:site)Backward Compatibility
enqueue()signature adds optional routing parameter with defaultNonerouting_contextis not usedSecurity
Testing
test_llmobs_routing.pyUnit tests for RoutingContext validation and writer multi-buffer behaviortest_llmobs_routing_integration.pyIntegration tests for full span lifecycle, async isolation, flush behavior, and securityRelated