Aggregate LLMObs span.finished telemetry counts per interval - #12136
Draft
Yun-Kim wants to merge 1 commit into
Draft
Aggregate LLMObs span.finished telemetry counts per interval#12136Yun-Kim wants to merge 1 commit into
Yun-Kim wants to merge 1 commit into
Conversation
LLMObsMetricCollector enqueued one raw metric of value 1 per finished span and left prepareMetrics() as a no-op, so the count was never aggregated in-process. Two problems followed: - Metric timestamps are second-granularity, so all points a series emits within the same second collapse to one value at the metrics intake. The reported rate was pinned at ~1/s per series regardless of the real span rate. - The raw queue holds RAW_QUEUE_SIZE (1024) entries per 10s metrics interval, silently dropping anything above ~102 spans/s per JVM. Count per tag combination with a LongAdder and emit one metric carrying the summed value in prepareMetrics(), matching CoreMetricCollector and the other tracers. The queue now holds one entry per tag combination per interval instead of one per span. A counter whose metric cannot be staged keeps its count for a later interval rather than losing it, and the number of tracked tag combinations is bounded. Also migrates the two affected Groovy tests to JUnit 5 / Java per the repo test convention. The previous "test aggregation of identical metrics" case asserted the buggy shape (three points of value 1); it is replaced by cases asserting a single point carrying the summed count, including one well above RAW_QUEUE_SIZE. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Contributor
|
🎯 Code Coverage (details) 🔗 Commit SHA: d8d5dad | Docs | Datadog PR Page | Give us feedback! |
Contributor
🟢 Java Benchmark SLOs — All performance SLOs passed
PR vs. master results
Commit: Load and DaCapo benchmarks can be triggered manually in the GitLab pipeline. Results will appear in the Benchmarking Platform UI after completion. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What Does This Do
Makes
LLMObsMetricCollectoraggregatemlobs.span.finishedcounts per tag combination in-process and emit one metric carrying the summed value per metrics interval, instead of enqueuing one raw metric of value1per finished span.Motivation
dd.instrumentation_telemetry_data.mlobs.span.finishedunderreports ~100x under-count on the spans that are received by Datadog LLM Observability backend.recordSpanFinishedenqueued oneLLMObsMetricof value1per span, andprepareMetrics()was an explicit no-op, so no summation ever happened. Two independent failures result:1. Same-second point collapse (the ~100x).
MetricCollector.Metrictimestamps at second granularity (System.currentTimeMillis() / 1000). Every point a series emits within the same second collapses to a single value at the metrics intake, so the reported rate is pinned at ~1/s per series no matter the real span rate. Confirmed on the affected org:max:dd.instrumentation_telemetry_data.mlobs.span.finished{org_id:...}.as_rate()sits flat at exactly 1.0/s, and the org-widesumof ~1k/min is just the ~17 active tag combinations each contributing 1/s.2. Raw queue overflow. The queue holds
RAW_QUEUE_SIZE(1024) entries and is drained once per 10s metrics interval, capping reporting at ~102 spans/s per JVM. Overflow was dropped atdebuglevel. This is currently masked by (1) but would bind on its own.How It Works
recordSpanFinishedincrements aLongAdderkeyed by tag combination; no per-span allocation into the queue.prepareMetrics()drains each counter withsumThenReset()and stages one metric per tag combination carrying the true count.LongAdder, so removing one would drop a concurrent increment. Tag values come from bounded sets, so idle entries cost at mostMAX_TAG_COMBINATIONS.Claude session:
05402794-04c0-4abe-a984-4b7b4eeb71ecResume:
claude --resume 05402794-04c0-4abe-a984-4b7b4eeb71ec🤖 Generated with Claude Code