Conversation
Snapshots difference summaryThe following differences have been observed in committed snapshots. It is meant to help the reviewer. 3 occurrences of : + _dd.svc_src: m
1 occurrences of : + _dd.svc_src: m,
|
BenchmarksBenchmark execution time: 2026-03-18 15:20:41 Comparing candidate commit 5b1d13b in PR branch Found 9 performance improvements and 5 performance regressions! Performance is the same for 160 metrics, 18 unstable metrics. scenario:Benchmarks.Trace.Asm.AppSecBodyBenchmark.AllCycleMoreComplexBody netcoreapp3.1
scenario:Benchmarks.Trace.Asm.AppSecBodyBenchmark.ObjectExtractorSimpleBody netcoreapp3.1
scenario:Benchmarks.Trace.Asm.AppSecEncoderBenchmark.EncodeLegacyArgs netcoreapp3.1
scenario:Benchmarks.Trace.CIVisibilityProtocolWriterBenchmark.WriteAndFlushEnrichedTraces net6.0
scenario:Benchmarks.Trace.CIVisibilityProtocolWriterBenchmark.WriteAndFlushEnrichedTraces netcoreapp3.1
scenario:Benchmarks.Trace.CharSliceBenchmark.OptimizedCharSlice net6.0
scenario:Benchmarks.Trace.Log4netBenchmark.EnrichedLog netcoreapp3.1
scenario:Benchmarks.Trace.SerilogBenchmark.EnrichedLog netcoreapp3.1
scenario:Benchmarks.Trace.SingleSpanAspNetCoreBenchmark.SingleSpanAspNetCore netcoreapp3.1
scenario:Benchmarks.Trace.SpanBenchmark.StartFinishScope net6.0
scenario:Benchmarks.Trace.TraceAnnotationsBenchmark.RunOnMethodBegin net6.0
|
Execution-Time Benchmarks Report ⏱️Execution-time results for samples comparing This PR (8302) and master. ✅ No regressions detected - check the details below Full Metrics ComparisonFakeDbCommand
HttpMessageHandler
Comparison explanationExecution-time benchmarks measure the whole time it takes to execute a program, and are intended to measure the one-off costs. Cases where the execution time results for the PR are worse than latest master results are highlighted in **red**. The following thresholds were used for comparing the execution times:
Note that these results are based on a single point-in-time result for each branch. For full results, see the dashboard. Graphs show the p99 interval based on the mean and StdDev of the test run, as well as the mean value of the run (shown as a diamond below the graph). Duration chartsFakeDbCommand (.NET Framework 4.8)gantt
title Execution time (ms) FakeDbCommand (.NET Framework 4.8)
dateFormat x
axisFormat %Q
todayMarker off
section Baseline
This PR (8302) - mean (71ms) : 69, 73
master - mean (71ms) : 70, 73
section Bailout
This PR (8302) - mean (75ms) : 73, 76
master - mean (76ms) : 75, 77
section CallTarget+Inlining+NGEN
This PR (8302) - mean (1,060ms) : 1003, 1117
master - mean (1,061ms) : 1023, 1099
FakeDbCommand (.NET Core 3.1)gantt
title Execution time (ms) FakeDbCommand (.NET Core 3.1)
dateFormat x
axisFormat %Q
todayMarker off
section Baseline
This PR (8302) - mean (109ms) : 106, 112
master - mean (111ms) : 109, 114
section Bailout
This PR (8302) - mean (112ms) : 110, 114
master - mean (113ms) : 111, 114
section CallTarget+Inlining+NGEN
This PR (8302) - mean (735ms) : 718, 751
master - mean (744ms) : 724, 764
FakeDbCommand (.NET 6)gantt
title Execution time (ms) FakeDbCommand (.NET 6)
dateFormat x
axisFormat %Q
todayMarker off
section Baseline
This PR (8302) - mean (97ms) : 94, 100
master - mean (99ms) : 96, 102
section Bailout
This PR (8302) - mean (99ms) : 97, 101
master - mean (99ms) : 97, 101
section CallTarget+Inlining+NGEN
This PR (8302) - mean (719ms) : 675, 763
master - mean (723ms) : 676, 769
FakeDbCommand (.NET 8)gantt
title Execution time (ms) FakeDbCommand (.NET 8)
dateFormat x
axisFormat %Q
todayMarker off
section Baseline
This PR (8302) - mean (97ms) : 94, 99
master - mean (98ms) : 95, 100
section Bailout
This PR (8302) - mean (97ms) : 96, 98
master - mean (99ms) : 98, 101
section CallTarget+Inlining+NGEN
This PR (8302) - mean (656ms) : 633, 678
master - mean (657ms) : 634, 681
HttpMessageHandler (.NET Framework 4.8)gantt
title Execution time (ms) HttpMessageHandler (.NET Framework 4.8)
dateFormat x
axisFormat %Q
todayMarker off
section Baseline
This PR (8302) - mean (199ms) : 193, 205
master - mean (194ms) : 189, 200
section Bailout
This PR (8302) - mean (200ms) : 196, 204
master - mean (197ms) : 193, 201
section CallTarget+Inlining+NGEN
This PR (8302) - mean (1,169ms) : 1116, 1221
master - mean (1,162ms) : 1090, 1233
HttpMessageHandler (.NET Core 3.1)gantt
title Execution time (ms) HttpMessageHandler (.NET Core 3.1)
dateFormat x
axisFormat %Q
todayMarker off
section Baseline
This PR (8302) - mean (282ms) : 273, 290
master - mean (277ms) : 273, 282
section Bailout
This PR (8302) - mean (282ms) : 276, 288
master - mean (279ms) : 273, 285
section CallTarget+Inlining+NGEN
This PR (8302) - mean (912ms) : 885, 940
master - mean (904ms) : 873, 936
HttpMessageHandler (.NET 6)gantt
title Execution time (ms) HttpMessageHandler (.NET 6)
dateFormat x
axisFormat %Q
todayMarker off
section Baseline
This PR (8302) - mean (274ms) : 267, 282
master - mean (271ms) : 265, 277
section Bailout
This PR (8302) - mean (274ms) : 267, 282
master - mean (271ms) : 268, 274
section CallTarget+Inlining+NGEN
This PR (8302) - mean (949ms) : 915, 984
master - mean (938ms) : 903, 973
HttpMessageHandler (.NET 8)gantt
title Execution time (ms) HttpMessageHandler (.NET 8)
dateFormat x
axisFormat %Q
todayMarker off
section Baseline
This PR (8302) - mean (275ms) : 265, 284
master - mean (271ms) : 264, 278
section Bailout
This PR (8302) - mean (277ms) : 265, 288
master - mean (271ms) : 265, 276
section CallTarget+Inlining+NGEN
This PR (8302) - mean (859ms) : 822, 896
master - mean (840ms) : 810, 870
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (span.ServiceName is null) | ||
| { | ||
| span.ServiceName = span.GetTag("peer.service") switch | ||
| span.Context.ServiceName = span.GetTag("peer.service") switch |
There was a problem hiding this comment.
I think we going to need to do something to avoid "accidentally" calling these in general, as this is going to be a source of bugs otherwise 🤔
I think we should avoid calling Span.Service entirely 🤔 and do something like the following:
- Add a new method to
Spanthat requires you provide a source at the same timeSetService(string serviceName, string? source) - Mark it as
[Obsolete("This should not be called directly, instead callSetService() and provide a source"]` - Update all our usages to explicitly set the source
- Keep the
Span.Serviceimplementation you have, so that manual instrumentation still works correctly - Potentially "fix"
SpanContext.ServiceNamein the same way, so that you can't "accidentally" not set the source?
WDYT?
There was a problem hiding this comment.
Yes, that would help avoiding errors in the future, thanks!
I have changed the code. Left SpanContext.ServiceName for now, but I can add it here or in a sugsequent PR. WDYT?
| { | ||
| get => ServiceName; | ||
| set => ServiceName = value; | ||
| set => SetService(value, Configuration.Schema.ServiceNameMetadata.Manual); |
There was a problem hiding this comment.
nit: this code path should probably be the same as the on in Span.cs, though I'm not sure which one is correct 😄
There was a problem hiding this comment.
Nice catch!
| @@ -262,7 +262,7 @@ public void StartActive_NoServiceName_DefaultServiceName() | |||
| public void StartActive_SetServiceName_ServiceNameIsSet() | |||
There was a problem hiding this comment.
Should we extend these tests to test the source behaviour too?
There was a problem hiding this comment.
Sure! Done!
Co-authored-by: Andrew Lock <andrew.lock@datadoghq.com>
…ataDog/dd-trace-dotnet into nacho/TrackServiceSourceManual
|
@codex review |
| [Obsolete("Use SetService(serviceName, source) instead to explicitly provide a source.")] | ||
| set | ||
| { | ||
| Context.ServiceName = value; |
There was a problem hiding this comment.
(Note related to this PR, but why is the service name on SpanContext?! 😓)
|
Codex Review: Didn't find any major issues. Chef's kiss. ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
If Codex has suggestions, it will comment; otherwise it will react with 👍. Codex can also answer questions or update the PR. Try commenting "@codex address that feedback". |
|
Thank you for your feedback and reviews! |
## Summary of changes Add `srv_src` field to the client stats payload, propagating the service name source alongside trace stats. ## Reason for change Per the [service name source RFC](https://docs.google.com/document/d/11OnbVYMDK-c5D-_V4QfOvL0Pc0z5oFQFGY3xSI-W7xk/edit?tab=t.0#heading=h.uoivahvmuvbg), the source must be propagated in both trace and stats payloads. The trace payload (`_dd.svc_src` span meta) was added in PR #8302. This completes the implementation by adding `srv_src` at the stats bucket level. ## Implementation details - **`StatsAggregationKey.cs`**: Added `ServiceSource` field. It participates in equality and hash code, so stats with different sources aggregate into distinct buckets. - **`StatsAggregator.cs`**: `BuildKey()` now reads `span.Context.ServiceNameSource` and passes it to the aggregation key. - **`StatsBuffer.cs`**: `SerializeBucket()` conditionally serializes `srv_src` when `ServiceSource` is non-null (dynamic map size: 13 with source, 12 without). ## Test coverage - `KeyEquality_WithServiceSource`: Verifies that keys with different sources are not equal. - `Serialization_WithServiceSource`: Verifies `srv_src` is serialized when present and absent when null. - Existing `StatsBufferTests` and `StatsAggregatorTests` updated and passing. ## Other details [APMLP-1015](https://datadoghq.atlassian.net/browse/APMLP-1015) Related agent PR: DataDog/datadog-agent#45982 Reference Java implementation: DataDog/dd-trace-java#10653 [APMLP-1015]: https://datadoghq.atlassian.net/browse/APMLP-1015?atlOrigin=eyJpIjoiNWRkNTljNzYxNjVmNDY3MDlhMDU5Y2ZhYzA5YTRkZjUiLCJwIjoiZ2l0aHViLWNvbS1KU1cifQ
Summary of changes
Add
_dd.svc_src: mtracking for manually set service names — via the manual API, OpenTracing, and post-creationSpan.ServiceNameassignments. OTelservice.namefrom resource attributes and Activity tags is treated as configuration (analogous toDD_SERVICE), not manual instrumentation.Reason for change
Per the service name source RFC, when a service name is explicitly set by manual instrumentation (API or interceptors),
_dd.svc_srcmust be set to"m". This complements the existing auto-instrumentation sources (e.g.,"redis","http-client") and configuration-driven sources ("opt.service_mapping").Implementation details
Span.cs: SettingServiceNameafter span creation now marks source as"m"(or clears it when set to null). The setter is the duck-typed entry point thatDatadog.Trace.Manual.dllusers call (span.ServiceName = "myService"), making it the natural and correct boundary to tag manual sources. This covers OpenTracing and all manual API paths.StartActiveImplementationIntegration.cs: Manual API bridge passesserviceNameSource: "m"when a service name is provided at span creation.NormalizerTraceProcessor.cs: Bypasses the setter viaspan.Context.ServiceNameto avoid overwriting the source during normalization.OtlpHelpers.cs: Bypasses the setter for both thepeer.service/OTLPResourceNoServiceNamefallback andservice.nametag processing. These are not manual instrumentation.ResourceAttributeProcessorHelper.cs: Bypasses the setter forservice.nameresource attributes —OTEL_SERVICE_NAMEis configuration (analogous toDD_SERVICE), not per-span manual instrumentation..IsOptional("_dd.svc_src")to all V1SpanMetadataRules. While V1 integrations don't override service names (so integration-driven sources don't appear), the tag can still be present from manual instrumentation.Test coverage
Other details