Wire per-component cardinality limits from Config#11732
Conversation
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 75f72165fd
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
| return configProvider.getInteger( | ||
| "trace.stats." + tagName + ".cardinality.limit", defaultLimit); |
There was a problem hiding this comment.
Validate stats cardinality limits before returning them
When any of the new DD_TRACE_STATS_*_CARDINALITY_LIMIT values is set to 0, a negative number, or a value above 2^29, this method returns it unchanged; the callers added in AggregateEntry and PeerTagSchema pass it directly into PropertyCardinalityHandler/TagCardinalityHandler, whose constructors throw for those ranges. In that misconfigured environment the stats classes fail initialization instead of falling back to the default/logging, so the accessor should reject invalid limits before handing them to the handlers.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
In my ideal world, config would probably handle this and report a warning immediately at start-up.
Unfortunately, there's no precedence for that in config today.
I'm in full agreement with the sentiment, but I think that's better left to another PR.
| "DD_TRACE_STATS_RESOURCE_CARDINALITY_LIMIT": [ | ||
| { | ||
| "version": "A", | ||
| "type": "integer", |
There was a problem hiding this comment.
Use
int for the new config metadata type
The supported-configurations metadata uses type: "int" for the existing integral settings (including the tracer metrics limits), while these ten new cardinality entries are the only ones using "integer". The local supported-configurations validation/publishing jobs consume this file, so the new configs can be rejected or omitted by downstream metadata consumers even though the agent code reads integers; please use int consistently for these entries.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
Yup, int is used instead of integer in the file.
There was a problem hiding this comment.
@mhlidd WDYT to add a test that will check types and failed if there someone made a typo?
OR probably we can support some sort of aliases like int, integer should be treated as the same type...
But I like the test better.
There was a problem hiding this comment.
No need for aliasing, I'll just fix it. I'm curious why Claude decided to use the wrong value though.
There was a problem hiding this comment.
Yep, Just thinking how to prevent issues in future.
Fir example if there will be a test - Claude with high probability will run it, test will fail, Claude will fix it.
I'm curious why Claude decided to use the wrong value though.
I think it is a nature of LLMs, somehow integer has a bigger weight in model that int and LLM produced wrong output.
🟢 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. |
AlexeyKuznetsov-DD
left a comment
There was a problem hiding this comment.
LGTM, but:
- Code like:
Config.get()
.getTraceStatsCardinalityLimit(
"peer_tag", MetricCardinalityLimits.PEER_TAG_VALUE))
looks a bit noisy, probably can be improved if refactored to enum?
2. JSON descriptor should be fixed integer -> int.
| "resource", | ||
| Config.get().getTraceStatsCardinalityLimit("resource", MetricCardinalityLimits.RESOURCE)); |
There was a problem hiding this comment.
QQ: just curious if this MetricCardinalityLimits can be an enum and no need to pass string and int const. Just enum and get the rest from it where needed.
There was a problem hiding this comment.
Yeah, we might be able to do that. The only complication is that we might have to move the enum next to Config.
1741d4f to
b23f870
Compare
This comment has been minimized.
This comment has been minimized.
b23f870 to
2418d84
Compare
…its RFC Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2418d84 to
5b550dd
Compare
|
Hi! 👋 Thanks for your pull request! 🎉 To help us review it, please make sure to:
If you need help, please check our contributing guidelines. |
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…y limits Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…oint, add table alias - Rename DD_TRACE_STATS_PEER_TAG_CARDINALITY_LIMIT -> DD_TRACE_STATS_PEER_TAGS_CARDINALITY_LIMIT to match .NET naming (plural) - Raise DD_TRACE_STATS_HTTP_ENDPOINT_CARDINALITY_LIMIT default 64 -> 512 to match .NET - Add DD_TRACE_STATS_CARDINALITY_LIMIT as the canonical name for the aggregate table cap, aliasing the older DD_TRACE_TRACER_METRICS_MAX_AGGREGATES - Add explicit string constants for all 10 per-field cardinality limit keys in GeneralConfig so the config registry validator can find them Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
SERVICE, OPERATION, SERVICE_SOURCE, TYPE, SPAN_KIND, HTTP_METHOD, and GRPC_STATUS_CODE have naturally low cardinality -- the aggregate table cap (DD_TRACE_STATS_CARDINALITY_LIMIT) is sufficient backstop. Aligns the public config surface with .NET (resource, http_endpoint, peer_tags, table cap). Hardcoded defaults in MetricCardinalityLimits remain; config knobs can be added later if a customer needs to tune them. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…config key detection Fields with hardcoded limits (service, operation, type, span_kind, http_method, grpc_status_code, service_source) now pass their MetricCardinalityLimits constant directly to PropertyCardinalityHandler instead of going through Config.getTraceStatsCardinalityLimit. This prevents the test harness from flagging DD_TRACE_STATS_SERVICE_CARDINALITY_LIMIT etc. as unsupported config keys. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
The central registry has no alias for this key; the local entry must match. The code-level alias (Config.java reads DD_TRACE_TRACER_METRICS_MAX_AGGREGATES as a fallback) is unaffected. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Version A must match the central registry exactly (no aliases). The DD_TRACE_TRACER_METRICS_MAX_AGGREGATES alias is Java-specific, so it belongs in version B — matching the same pattern as DD_TRACE_STATS_COMPUTATION_ENABLED aliasing DD_TRACE_TRACER_METRICS_ENABLED. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
What Does This Do
Wires per-component cardinality limits from
Configinto the client-side stats handlers, aligning with the Cardinality Limits RFC and the .NET implementation.Motivation
Follows #11387, which shipped the handler infrastructure. This PR connects the config layer so operators can tune limits and the sentinel substitution is active by default.
Limit surface
Configurable limits (env var exposed)
DD_TRACE_STATS_CARDINALITY_LIMITresource.nameDD_TRACE_STATS_RESOURCE_CARDINALITY_LIMIThttp.endpointDD_TRACE_STATS_HTTP_ENDPOINT_CARDINALITY_LIMITDD_TRACE_STATS_PEER_TAGS_CARDINALITY_LIMITDD_TRACE_STATS_CARDINALITY_LIMITis the new canonical name for the table cap;DD_TRACE_TRACER_METRICS_MAX_AGGREGATESis preserved as a backwards-compatible alias.Fixed limits (hardcoded, no env var)
Fields with inherently low natural cardinality are enforced at their
MetricCardinalityLimitsdefaults but are not user-configurable. The table cap above is the backstop for any unexpected growth.serviceoperation.namespan.typespan.kindhttp.methodgrpc.status_code_dd.base_serviceImplementation notes
Config.getTraceStatsCardinalityLimit(tagName, defaultLimit)method; configurable fields also have explicit string constants inGeneralConfigfor the config registry validatorPropertyCardinalityHandlerinstances useuseBlockedSentinel=true(the default 2-arg constructor); sentinel substitution is activeStacked on #11387 (merged).
Test plan
CardinalityHandlerTestandAggregateEntryTestcover sentinel substitution behaviorMetricCardinalityLimitsconstantsDD_TRACE_STATS_RESOURCE_CARDINALITY_LIMITetc. are picked up at startup via Configtag: no release notetag: ai generated🤖 Generated with Claude Code