Add EventBridge DSM producer injection#8639
Conversation
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 5634ae9a25
ℹ️ About Codex in GitHub
Your team has set up Codex to 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 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
BenchmarksBenchmark execution time: 2026-06-30 14:27:17 Comparing candidate commit 91b3e2e in PR branch Found 0 performance improvements and 2 performance regressions! Performance is the same for 70 metrics, 0 unstable metrics, 61 known flaky benchmarks, 65 flaky benchmarks without significant changes.
|
Execution-Time Benchmarks Report ⏱️Execution-time results for samples comparing This PR (8639) 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 (8639) - mean (72ms) : 68, 77
master - mean (69ms) : 67, 71
section Bailout
This PR (8639) - mean (76ms) : 72, 80
master - mean (73ms) : 72, 75
section CallTarget+Inlining+NGEN
This PR (8639) - mean (1,084ms) : 1040, 1128
master - mean (1,080ms) : 1036, 1125
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 (8639) - mean (113ms) : 107, 120
master - mean (109ms) : 106, 111
section Bailout
This PR (8639) - mean (111ms) : 106, 115
master - mean (110ms) : 108, 112
section CallTarget+Inlining+NGEN
This PR (8639) - mean (773ms) : 755, 791
master - mean (777ms) : 755, 799
FakeDbCommand (.NET 6)gantt
title Execution time (ms) FakeDbCommand (.NET 6)
dateFormat x
axisFormat %Q
todayMarker off
section Baseline
This PR (8639) - mean (100ms) : 95, 105
master - mean (97ms) : 94, 99
section Bailout
This PR (8639) - mean (98ms) : 95, 101
master - mean (97ms) : 95, 99
section CallTarget+Inlining+NGEN
This PR (8639) - mean (938ms) : 889, 986
master - mean (937ms) : 899, 975
FakeDbCommand (.NET 8)gantt
title Execution time (ms) FakeDbCommand (.NET 8)
dateFormat x
axisFormat %Q
todayMarker off
section Baseline
This PR (8639) - mean (95ms) : 92, 97
master - mean (98ms) : 93, 104
section Bailout
This PR (8639) - mean (100ms) : 95, 104
master - mean (99ms) : 95, 103
section CallTarget+Inlining+NGEN
This PR (8639) - mean (812ms) : 771, 853
master - mean (812ms) : 770, 855
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 (8639) - mean (205ms) : 199, 211
master - mean (204ms) : 199, 209
section Bailout
This PR (8639) - mean (210ms) : 204, 216
master - mean (207ms) : 203, 212
section CallTarget+Inlining+NGEN
This PR (8639) - mean (1,224ms) : 1188, 1260
master - mean (1,211ms) : 1168, 1254
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 (8639) - mean (295ms) : 288, 303
master - mean (291ms) : 286, 296
section Bailout
This PR (8639) - mean (294ms) : 288, 300
master - mean (290ms) : 285, 296
section CallTarget+Inlining+NGEN
This PR (8639) - mean (984ms) : 960, 1009
master - mean (974ms) : 954, 993
HttpMessageHandler (.NET 6)gantt
title Execution time (ms) HttpMessageHandler (.NET 6)
dateFormat x
axisFormat %Q
todayMarker off
section Baseline
This PR (8639) - mean (290ms) : 283, 297
master - mean (286ms) : 281, 291
section Bailout
This PR (8639) - mean (290ms) : 283, 297
master - mean (285ms) : 278, 291
section CallTarget+Inlining+NGEN
This PR (8639) - mean (1,177ms) : 1128, 1227
master - mean (1,173ms) : 1130, 1216
HttpMessageHandler (.NET 8)gantt
title Execution time (ms) HttpMessageHandler (.NET 8)
dateFormat x
axisFormat %Q
todayMarker off
section Baseline
This PR (8639) - mean (286ms) : 280, 292
master - mean (285ms) : 280, 289
section Bailout
This PR (8639) - mean (286ms) : 282, 290
master - mean (287ms) : 280, 294
section CallTarget+Inlining+NGEN
This PR (8639) - mean (1,058ms) : 1016, 1099
master - mean (1,054ms) : 1007, 1102
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||
| var edgeTags = dataStreamsManager.GetOrCreateEdgeTags( | ||
| new EventBridgeEdgeTagCacheKey(detailType ?? string.Empty, eventBusName!), | ||
| static k => ["direction:out", $"topic:{k.DetailType}", $"type:eventbridge:{k.EventBusName}"]); |
There was a problem hiding this comment.
I'm not too familiar with EventBridge, is DetailType the right choice for topic here?
There was a problem hiding this comment.
@robcarlan-datadog DetailType would typically be "orderCreated" or "productUpdated" or whatever the type of event is that's being published. So I would say yes?
There was a problem hiding this comment.
If I'm reading the dd-trace-java implementation they opted to go with a static type:bus with no topic/DetailType tag.
(Just taking a cursory glance at it on GitHub)
I think we should align on one standard - I don't know who is right though 😛 or if both are right
There was a problem hiding this comment.
@bouwkast A PR to Java is next on my agenda 😊 Ideally I want to include the bus name in the type, with the way EventBridge works, and how I think folks using EB will debug, is they'll want to see all message channels for a specific bus. Not just all message channels that are of type 'bus' if that makes sense.
Going to ask the DSM team to do some analysis before we finally commit
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 3651fdda90
ℹ️ About Codex in GitHub
Your team has set up Codex to 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 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
|
|
||
| private static PathwayContext? SetDataStreamsCheckpoint(Tracer tracer, Scope? scope, string? detailType, string? eventBusName, long payloadSizeBytes) | ||
| { | ||
| if (scope is null || StringUtil.IsNullOrEmpty(eventBusName)) |
There was a problem hiding this comment.
Preserve DSM on default EventBridge bus
When PutEventsRequestEntry.EventBusName is omitted, AWS sends the event to the default EventBridge bus, but this guard returns before creating the DSM checkpoint or injecting dd-pathway-ctx-base64. That means applications using the default bus still get trace context injected below, but DSM propagation is silently absent for those events; use the default bus name as the topic instead of treating the missing property as “no destination.”
Useful? React with 👍 / 👎.
bouwkast
left a comment
There was a problem hiding this comment.
There are (what appears) to be some deviations from the dd-trace-java implementation, but I don't know who is right.
Could we confirm before we merge?
|
|
||
| var edgeTags = dataStreamsManager.GetOrCreateEdgeTags( | ||
| new EventBridgeEdgeTagCacheKey(detailType ?? string.Empty, eventBusName!), | ||
| static k => ["direction:out", $"topic:{k.DetailType}", $"type:eventbridge:{k.EventBusName}"]); |
There was a problem hiding this comment.
If I'm reading the dd-trace-java implementation they opted to go with a static type:bus with no topic/DetailType tag.
(Just taking a cursory glance at it on GitHub)
I think we should align on one standard - I don't know who is right though 😛 or if both are right
|
|
||
| private static PathwayContext? SetDataStreamsCheckpoint(Tracer tracer, Scope? scope, string? detailType, string? eventBusName, long payloadSizeBytes) | ||
| { | ||
| if (scope is null || StringUtil.IsNullOrEmpty(eventBusName)) |
There was a problem hiding this comment.
The codex comment seems relevant here, if the default bus is used the name is empty so I'd imagine we'd want to checkpoint.
Looking again at the dd-trace-java implementation they just grab the bus name and inject a pathway regardless of its value.
Again no clue who's right here 😛
There was a problem hiding this comment.
@bouwkast A PR to Java is next on my agenda 😊 Ideally I want to include the bus name in the type, with the way EventBridge works, and how I think folks using EB will debug, is they'll want to see all message channels for a specific bus. Not just all message channels that are of type 'bus' if that makes sense.
Going to ask the DSM team to do some analysis before we finally commit
| } | ||
|
|
||
| var edgeTags = dataStreamsManager.GetOrCreateEdgeTags( | ||
| new EventBridgeEdgeTagCacheKey(detailType ?? string.Empty, eventBusName!), |
There was a problem hiding this comment.
Just looking on GitHub, but do we need ! on eventBusName!? I think StringUtil.IsNullOrEmpty(eventBusName) should correctly mark it as not null
# Conflicts: # tracer/src/Datadog.Trace/ClrProfiler/AutoInstrumentation/AWS/EventBridge/ContextPropagation.cs # tracer/test/Datadog.Trace.ClrProfiler.Managed.Tests/AutoInstrumentation/AWS/EventBridge/ContextPropagationTests.cs
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: f8a258e409
ℹ️ About Codex in GitHub
Your team has set up Codex to 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 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| var payloadSizeBytes = GetPayloadSizeBytes(detail); | ||
| var pathwayContext = SetDataStreamsCheckpoint(tracer, scope, entry.DetailType, entry.EventBusName, payloadSizeBytes); |
There was a problem hiding this comment.
Move DSM checkpoint after the size guard
When DSM is enabled and adding _datadog would push an EventBridge detail over the 256 KB limit, this call creates a produce checkpoint before the later size check returns without assigning entry.Detail. In that case the event is sent without dd-pathway-ctx-base64, but the span still gets a pathway.hash and DSM stats point for a pathway that was never propagated; create the checkpoint only after confirming the updated payload will be injected.
Useful? React with 👍 / 👎.
robcarlan-datadog
left a comment
There was a problem hiding this comment.
(req DSM changes pending some internal discussion on data model)
This comment has been minimized.
This comment has been minimized.
Any clarification on this? |
@bouwkast I've updated the implementation now based on Rob's suggestion. Just waiting on his approval 😊 |
robcarlan-datadog
left a comment
There was a problem hiding this comment.
Main open question is just about the changes with AppendEscapedJsonString, and some small changes to tests
Summary of changes
Update the Amazon EventBridge context propagation to support data streams monitoring injection.
Reason for change
Other AWS messaging technologies (SNS/SQS/Kinesis) support DSM, extending support into the full suite of AWS services.
Implementation details
The core change is in ContextPropagation.cs (line 28): each PutEvents entry now creates a produce checkpoint when an EventBusName is available, then injects dd-pathway-ctx-base64 into the existing _datadog JSON alongside the trace headers.
Test coverage
Tests added to ContextPropagationTests.cs to verify the header is injected and is base-64 decodable.
Other details