feat(stats): emit canonical gRPC status name for OTLP rpc.response.status_code#2183
Conversation
…atus_code The OTLP trace-metrics path emitted the numeric gRPC status code as a string for rpc.response.status_code, but the OTel gRPC semantic conventions require the canonical status NAME (e.g. OK, NOT_FOUND, UNAVAILABLE). Add grpc_status_code_to_name in libdd-trace-stats (the inverse of the existing name->code normalization) and use it at OTLP emission. The /v0.6/stats agent payload, the aggregation key, and the SHM path are unchanged. Co-authored-by: Cursor <cursoragent@cursor.com>
🎉 All green!🧪 All tests passed 🎯 Code Coverage (details) 🔗 Commit SHA: debec9d | Docs | Datadog PR Page | Give us feedback! |
Clippy Allow Annotation ReportComparing clippy allow annotations between branches:
Summary by Rule
Annotation Counts by File
Annotation Stats by Crate
About This ReportThis report tracks Clippy allow annotations for specific rules, showing how they've changed in this PR. Decreasing the number of these annotations generally improves code quality. |
Artifact Size Benchmark Reportaarch64-alpine-linux-musl
aarch64-unknown-linux-gnu
libdatadog-x64-windows
libdatadog-x86-windows
x86_64-alpine-linux-musl
x86_64-unknown-linux-gnu
|
End-to-end validation (dd-trace-py + system-tests)Validated this change end-to-end through the Python tracer and the system-tests OTLP trace-metrics parametric suite. Result: all green
The round-trip works as designed: dd-trace-py sets Note on how it was built
To isolate only this commit for validation, it was cherry-picked onto |
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…_name Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Summary
The OTLP trace-metrics path emits the numeric gRPC status code as a string (e.g.
"0","14") for therpc.response.status_codedata-point attribute. The OTel gRPC semantic conventions require the canonical status NAME (e.g.OK,NOT_FOUND,UNAVAILABLE).This PR maps the numeric code back to the canonical name at OTLP emission only:
grpc_status_code_to_nameinlibdd-trace-stats(span_concentrator), the inverse of the existinggrpc_status_str_to_int_valuename->code normalization, with the canonical list kept next to the forward table as a single source of truth.libdd-data-pipelineOTLPbuild_attributesnow emits the name (omitting the attribute for empty/unmapped codes).Why map instead of pass through the raw string?
By the time stats reach the OTLP/agent boundary,
grpc.status.codehas already been normalized to a numericu8in the aggregation key, so the raw name is gone. Mapping the numeric code back to the name reuses that existing normalization and yields the canonical name for every input form ("OK","ok","StatusCode.OK","0", and numeric metrics) without changing the aggregation data model.Unchanged
/v0.6/statsagent payload (encode_grouped_statsstill emits the numeric code).grpc_status_code: Option<u8>) and grouping/cardinality behavior.datadog-ipc) path.Test plan
cargo test -p libdd-trace-stats(incl.test_grpc_status_code_to_name)cargo test -p libdd-data-pipeline --lib otlp::metrics(incl.emits_canonical_grpc_status_name_for_rpc_response_status_code)Test_FR06...::test_fr06_7_rpc_status_codefor python once this ships and the python OTLP suite is enabledNotes
Draft: depends on coordinating the system-tests
fr06_7enablement for python (currently skipped via file-levelmissing_feature) and a libdatadog bump in dd-trace-py.Made with Cursor