Skip to content

[tracing] add MassTransit integration#8055

Draft
chojomok wants to merge 94 commits intomasterfrom
mohammad/mass_transit_intg
Draft

[tracing] add MassTransit integration#8055
chojomok wants to merge 94 commits intomasterfrom
mohammad/mass_transit_intg

Conversation

@chojomok
Copy link
Collaborator

@chojomok chojomok commented Jan 14, 2026

Summary of changes

Adds automatic instrumentation for MassTransit 7.x and 8.x, a popular distributed application framework for .NET. The integration captures distributed traces across message
producers and consumers, propagates trace context across transport boundaries (RabbitMQ, Amazon SQS, In-Memory), and supports both DiagnosticSource (MT7) and
OpenTelemetry Activity (MT8) instrumentation patterns.

Reason for change

MassTransit is a widely-used message bus framework in the .NET ecosystem. This integration provides customers with end-to-end visibility into distributed message-driven
architectures, allowing them to track message flow across services, identify performance bottlenecks, and correlate traces across synchronous HTTP and asynchronous messaging
operations.

Implementation details

MassTransit 7.x:

  • Instruments via DiagnosticSource listeners (MassTransit.ReceivePipe, MassTransit.ConsumeContext)
  • Hooks into ConsumeContext, SendContext, and PublishContext for context propagation
  • Creates RECEIVE and PROCESS spans for incoming messages, SEND spans for outgoing messages

MassTransit 8.x:

  • Leverages MassTransit's built-in OpenTelemetry ActivitySource instrumentation
  • Enhances Activity tags with Datadog-specific metadata
  • Injects/extracts trace context via message headers (x-datadog-*, _datadog)

Key technical decisions:

  • Uses duck typing over reflection for ~30% performance improvement in header access
  • Transport-agnostic design handles RabbitMQ, SQS, and In-Memory
  • For MT8, enriches existing Activities rather than creating new spans to avoid duplication
  • Optimized Activity.Tags iteration (single foreach with switch vs multiple LINQ calls)

Test coverage

  • MassTransit7Tests.cs - DiagnosticSource instrumentation across multiple transports
  • MassTransit8Tests.cs - OpenTelemetry Activity enhancement across multiple transports
  • Package version testing: MT7 (7.0.0 - 7.3.1), MT8 (8.0.2 - 8.5.8)
  • Sample applications for both versions with multi-transport scenarios, saga state machines, and error handling

Other details

Compatibility:

  • MassTransit 7.x: .NET Core 2.1+ (.NET 5, 6, 7, 8, 9, 10)
  • MassTransit 8.x: .NET Framework 4.8 / .NET Core 2.1+ (.NET 5, 6, 7, 8, 9, 10)
  • Tested with RabbitMQ 3.x, LocalStack (SQS),

NEED TO TEST WITH Azure Service Bus !!!

@chojomok chojomok changed the title Mohammad/mass transit intg [tracing] add MassTransit integration Jan 14, 2026
@pr-commenter
Copy link

pr-commenter bot commented Jan 14, 2026

Benchmarks

Benchmark execution time: 2026-03-24 20:21:08

Comparing candidate commit cb18df6 in PR branch mohammad/mass_transit_intg with baseline commit 1bb5b79 in branch master.

Found 3 performance improvements and 10 performance regressions! Performance is the same for 258 metrics, 17 unstable metrics.

Explanation

This is an A/B test comparing a candidate commit's performance against that of a baseline commit. Performance changes are noted in the tables below as:

  • 🟩 = significantly better candidate vs. baseline
  • 🟥 = significantly worse candidate vs. baseline

We compute a confidence interval (CI) over the relative difference of means between metrics from the candidate and baseline commits, considering the baseline as the reference.

If the CI is entirely outside the configured SIGNIFICANT_IMPACT_THRESHOLD (or the deprecated UNCONFIDENCE_THRESHOLD), the change is considered significant.

Feel free to reach out to #apm-benchmarking-platform on Slack if you have any questions.

More details about the CI and significant changes

You can imagine this CI as a range of values that is likely to contain the true difference of means between the candidate and baseline commits.

CIs of the difference of means are often centered around 0%, because often changes are not that big:

---------------------------------(------|---^--------)-------------------------------->
                              -0.6%    0%  0.3%     +1.2%
                                 |          |        |
         lower bound of the CI --'          |        |
sample mean (center of the CI) -------------'        |
         upper bound of the CI ----------------------'

As described above, a change is considered significant if the CI is entirely outside the configured SIGNIFICANT_IMPACT_THRESHOLD (or the deprecated UNCONFIDENCE_THRESHOLD).

For instance, for an execution time metric, this confidence interval indicates a significantly worse performance:

----------------------------------------|---------|---(---------^---------)---------->
                                       0%        1%  1.3%      2.2%      3.1%
                                                  |   |         |         |
       significant impact threshold --------------'   |         |         |
                      lower bound of CI --------------'         |         |
       sample mean (center of the CI) --------------------------'         |
                      upper bound of CI ----------------------------------'

scenario:Benchmarks.Trace.AgentWriterBenchmark.WriteAndFlushEnrichedTraces net6.0

  • 🟥 execution_time [+80.607ms; +80.923ms] or [+64.849%; +65.104%]

scenario:Benchmarks.Trace.Asm.AppSecBodyBenchmark.AllCycleSimpleBody netcoreapp3.1

  • 🟥 execution_time [+22.498ms; +28.511ms] or [+11.896%; +15.075%]

scenario:Benchmarks.Trace.Asm.AppSecBodyBenchmark.ObjectExtractorSimpleBody net472

  • 🟩 throughput [+164650.231op/s; +233101.173op/s] or [+5.248%; +7.430%]

scenario:Benchmarks.Trace.CIVisibilityProtocolWriterBenchmark.WriteAndFlushEnrichedTraces netcoreapp3.1

  • 🟥 execution_time [+15.842ms; +19.279ms] or [+10.054%; +12.234%]

scenario:Benchmarks.Trace.CharSliceBenchmark.OptimizedCharSlice netcoreapp3.1

  • 🟩 execution_time [-886.131µs; -634.819µs] or [-32.007%; -22.930%]

scenario:Benchmarks.Trace.ElasticsearchBenchmark.CallElasticsearchAsync net6.0

  • 🟥 throughput [-45303.210op/s; -33239.950op/s] or [-7.239%; -5.311%]

scenario:Benchmarks.Trace.GraphQLBenchmark.ExecuteAsync netcoreapp3.1

  • 🟥 execution_time [+9.915ms; +14.299ms] or [+5.075%; +7.319%]

scenario:Benchmarks.Trace.Iast.StringAspectsBenchmark.StringConcatAspectBenchmark net6.0

  • 🟥 allocated_mem [+18.200KB; +18.229KB] or [+7.070%; +7.082%]

scenario:Benchmarks.Trace.Iast.StringAspectsBenchmark.StringConcatAspectBenchmark netcoreapp3.1

  • 🟥 allocated_mem [+19.723KB; +19.751KB] or [+7.706%; +7.717%]

scenario:Benchmarks.Trace.Iast.StringAspectsBenchmark.StringConcatBenchmark net6.0

  • 🟥 throughput [-3522.707op/s; -1663.650op/s] or [-14.770%; -6.975%]

scenario:Benchmarks.Trace.SingleSpanAspNetCoreBenchmark.SingleSpanAspNetCore netcoreapp3.1

  • 🟥 throughput [-16901140.785op/s; -15929321.547op/s] or [-7.002%; -6.600%]

scenario:Benchmarks.Trace.SpanBenchmark.StartFinishScope net6.0

  • 🟥 execution_time [+12.206ms; +16.262ms] or [+6.184%; +8.239%]

scenario:Benchmarks.Trace.SpanBenchmark.StartFinishSpan net6.0

  • 🟩 execution_time [-23.754ms; -20.107ms] or [-10.858%; -9.191%]

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant