Skip to content

Extract Datadog.AutoInstrumentation.Generator.Core shared library#8312

Draft
bouwkast wants to merge 1 commit intomasterfrom
steven/auto-instrumentation-gen-core
Draft

Extract Datadog.AutoInstrumentation.Generator.Core shared library#8312
bouwkast wants to merge 1 commit intomasterfrom
steven/auto-instrumentation-gen-core

Conversation

@bouwkast
Copy link
Copy Markdown
Collaborator

Summary of changes

This extracts the instrumentation code generation core from the GUI Datadog.AutoInstrumentation.Generator into a Core library that can be re-used in an upcoming CLI (mainly for LLM consumption).

Reason for change

We'd like to try and automate some of our validation logic that determines if our auto instrumentations still function with newer NuGet versions of the underlying libraries. Currently we rely upon just re-running CI against those tests, but this would allow us to build in the ability to in the future deterministically generate the code from one version to the next which will help with validating whether we are still functional.

Additionally, we'd like to help some ongoing initiatives to aid in the generation / support of auto-instrumentations via LLMs and this will set us up to be able to create a CLI that can be used by LLMs.

Implementation details

New Datadog.AutoInstrumentation.Generator.Core, you will see the "File renamed without changes." are the extracted files.

Main important changes:

  • AssemblyBrowser - assembly / method resolution logic that was in the MainViewModel
  • GenerationConfiguration takes all of the previous checkbox bool flags into a single object. Used by CreateForMethod() that handles the various async/static/void logic.
  • GenerationResult contains all the generated code stuff
  • InstrumentMethodMetadata - [InstrumentMethod] attribute values.

The GUI project now depends on Core and delegates all generation logic to it.

Test coverage

I re-ran the GUI and it seems all functional.

Other details

This is the base PR for another

Claude Code generated

@bouwkast bouwkast added the AI Generated Largely based on code generated by an AI or LLM. This label is the same across all dd-trace-* repos label Mar 16, 2026
@dd-trace-dotnet-ci-bot
Copy link
Copy Markdown

dd-trace-dotnet-ci-bot bot commented Mar 16, 2026

Execution-Time Benchmarks Report ⏱️

Execution-time results for samples comparing This PR (8312) and master.

✅ No regressions detected - check the details below

Full Metrics Comparison

FakeDbCommand

Metric Master (Mean ± 95% CI) Current (Mean ± 95% CI) Change Status
.NET Framework 4.8 - Baseline
duration72.41 ± (72.36 - 72.68) ms71.40 ± (71.49 - 71.79) ms-1.4%
.NET Framework 4.8 - Bailout
duration76.00 ± (76.01 - 76.39) ms76.46 ± (76.42 - 76.80) ms+0.6%✅⬆️
.NET Framework 4.8 - CallTarget+Inlining+NGEN
duration1072.13 ± (1072.53 - 1077.96) ms1081.29 ± (1081.55 - 1088.90) ms+0.9%✅⬆️
.NET Core 3.1 - Baseline
process.internal_duration_ms22.36 ± (22.32 - 22.40) ms22.32 ± (22.28 - 22.36) ms-0.2%
process.time_to_main_ms83.60 ± (83.40 - 83.80) ms84.34 ± (84.16 - 84.52) ms+0.9%✅⬆️
runtime.dotnet.exceptions.count0 ± (0 - 0)0 ± (0 - 0)+0.0%
runtime.dotnet.mem.committed10.91 ± (10.91 - 10.92) MB10.93 ± (10.93 - 10.93) MB+0.2%✅⬆️
runtime.dotnet.threads.count12 ± (12 - 12)12 ± (12 - 12)+0.0%
.NET Core 3.1 - Bailout
process.internal_duration_ms22.32 ± (22.28 - 22.36) ms22.19 ± (22.14 - 22.24) ms-0.6%
process.time_to_main_ms84.43 ± (84.23 - 84.63) ms84.93 ± (84.75 - 85.12) ms+0.6%✅⬆️
runtime.dotnet.exceptions.count0 ± (0 - 0)0 ± (0 - 0)+0.0%
runtime.dotnet.mem.committed10.94 ± (10.94 - 10.95) MB10.96 ± (10.95 - 10.96) MB+0.1%✅⬆️
runtime.dotnet.threads.count13 ± (13 - 13)13 ± (13 - 13)+0.0%
.NET Core 3.1 - CallTarget+Inlining+NGEN
process.internal_duration_ms224.27 ± (223.08 - 225.46) ms224.31 ± (223.31 - 225.31) ms+0.0%✅⬆️
process.time_to_main_ms537.55 ± (536.40 - 538.70) ms532.83 ± (531.68 - 533.98) ms-0.9%
runtime.dotnet.exceptions.count0 ± (0 - 0)0 ± (0 - 0)+0.0%
runtime.dotnet.mem.committed48.22 ± (48.19 - 48.26) MB48.23 ± (48.20 - 48.27) MB+0.0%✅⬆️
runtime.dotnet.threads.count28 ± (28 - 28)28 ± (28 - 28)-0.1%
.NET 6 - Baseline
process.internal_duration_ms21.02 ± (20.98 - 21.05) ms20.95 ± (20.91 - 20.99) ms-0.3%
process.time_to_main_ms71.89 ± (71.73 - 72.05) ms72.55 ± (72.37 - 72.73) ms+0.9%✅⬆️
runtime.dotnet.exceptions.count0 ± (0 - 0)0 ± (0 - 0)+0.0%
runtime.dotnet.mem.committed10.62 ± (10.62 - 10.62) MB10.65 ± (10.65 - 10.65) MB+0.3%✅⬆️
runtime.dotnet.threads.count10 ± (10 - 10)10 ± (10 - 10)+0.0%
.NET 6 - Bailout
process.internal_duration_ms20.82 ± (20.79 - 20.85) ms21.06 ± (21.03 - 21.10) ms+1.1%✅⬆️
process.time_to_main_ms72.87 ± (72.71 - 73.04) ms73.73 ± (73.58 - 73.87) ms+1.2%✅⬆️
runtime.dotnet.exceptions.count0 ± (0 - 0)0 ± (0 - 0)+0.0%
runtime.dotnet.mem.committed10.72 ± (10.72 - 10.72) MB10.76 ± (10.75 - 10.76) MB+0.3%✅⬆️
runtime.dotnet.threads.count11 ± (11 - 11)11 ± (11 - 11)+0.0%
.NET 6 - CallTarget+Inlining+NGEN
process.internal_duration_ms387.08 ± (384.68 - 389.47) ms388.44 ± (385.98 - 390.89) ms+0.4%✅⬆️
process.time_to_main_ms528.76 ± (527.85 - 529.67) ms534.66 ± (533.73 - 535.58) ms+1.1%✅⬆️
runtime.dotnet.exceptions.count0 ± (0 - 0)0 ± (0 - 0)+0.0%
runtime.dotnet.mem.committed50.32 ± (50.29 - 50.34) MB50.36 ± (50.33 - 50.39) MB+0.1%✅⬆️
runtime.dotnet.threads.count28 ± (28 - 28)28 ± (28 - 28)-0.0%
.NET 8 - Baseline
process.internal_duration_ms19.10 ± (19.07 - 19.13) ms19.30 ± (19.26 - 19.33) ms+1.0%✅⬆️
process.time_to_main_ms71.49 ± (71.32 - 71.65) ms71.93 ± (71.77 - 72.08) ms+0.6%✅⬆️
runtime.dotnet.exceptions.count0 ± (0 - 0)0 ± (0 - 0)+0.0%
runtime.dotnet.mem.committed7.69 ± (7.68 - 7.70) MB7.71 ± (7.70 - 7.72) MB+0.3%✅⬆️
runtime.dotnet.threads.count10 ± (10 - 10)10 ± (10 - 10)+0.0%
.NET 8 - Bailout
process.internal_duration_ms19.25 ± (19.20 - 19.29) ms19.34 ± (19.30 - 19.38) ms+0.5%✅⬆️
process.time_to_main_ms72.93 ± (72.77 - 73.08) ms73.19 ± (73.03 - 73.36) ms+0.4%✅⬆️
runtime.dotnet.exceptions.count0 ± (0 - 0)0 ± (0 - 0)+0.0%
runtime.dotnet.mem.committed7.77 ± (7.75 - 7.78) MB7.75 ± (7.74 - 7.76) MB-0.2%
runtime.dotnet.threads.count11 ± (11 - 11)11 ± (11 - 11)+0.0%
.NET 8 - CallTarget+Inlining+NGEN
process.internal_duration_ms307.01 ± (304.48 - 309.53) ms307.06 ± (304.81 - 309.30) ms+0.0%✅⬆️
process.time_to_main_ms491.34 ± (490.49 - 492.19) ms491.96 ± (491.05 - 492.88) ms+0.1%✅⬆️
runtime.dotnet.exceptions.count0 ± (0 - 0)0 ± (0 - 0)+0.0%
runtime.dotnet.mem.committed37.21 ± (37.19 - 37.23) MB37.32 ± (37.29 - 37.34) MB+0.3%✅⬆️
runtime.dotnet.threads.count27 ± (27 - 27)27 ± (27 - 27)+0.2%✅⬆️

HttpMessageHandler

Metric Master (Mean ± 95% CI) Current (Mean ± 95% CI) Change Status
.NET Framework 4.8 - Baseline
duration216.19 ± (215.90 - 216.92) ms215.87 ± (215.40 - 216.37) ms-0.1%
.NET Framework 4.8 - Bailout
duration221.29 ± (221.03 - 222.12) ms218.99 ± (218.61 - 219.47) ms-1.0%
.NET Framework 4.8 - CallTarget+Inlining+NGEN
duration1264.28 ± (1264.37 - 1272.79) ms1253.59 ± (1254.79 - 1262.78) ms-0.8%
.NET Core 3.1 - Baseline
process.internal_duration_ms212.56 ± (212.02 - 213.10) ms210.20 ± (209.71 - 210.69) ms-1.1%
process.time_to_main_ms92.50 ± (92.13 - 92.88) ms91.59 ± (91.29 - 91.88) ms-1.0%
runtime.dotnet.exceptions.count3 ± (3 - 3)3 ± (3 - 3)+0.0%
runtime.dotnet.mem.committed15.87 ± (15.84 - 15.89) MB15.87 ± (15.85 - 15.90) MB+0.1%✅⬆️
runtime.dotnet.threads.count20 ± (20 - 20)20 ± (20 - 20)+0.6%✅⬆️
.NET Core 3.1 - Bailout
process.internal_duration_ms213.46 ± (212.91 - 214.01) ms209.54 ± (209.07 - 210.01) ms-1.8%
process.time_to_main_ms94.27 ± (93.93 - 94.61) ms92.75 ± (92.48 - 93.02) ms-1.6%
runtime.dotnet.exceptions.count3 ± (3 - 3)3 ± (3 - 3)+0.0%
runtime.dotnet.mem.committed15.85 ± (15.82 - 15.87) MB15.95 ± (15.93 - 15.97) MB+0.6%✅⬆️
runtime.dotnet.threads.count21 ± (21 - 21)21 ± (21 - 21)-1.3%
.NET Core 3.1 - CallTarget+Inlining+NGEN
process.internal_duration_ms424.35 ± (422.90 - 425.81) ms420.65 ± (419.30 - 422.01) ms-0.9%
process.time_to_main_ms574.45 ± (572.90 - 576.01) ms570.15 ± (568.63 - 571.67) ms-0.7%
runtime.dotnet.exceptions.count3 ± (3 - 3)3 ± (3 - 3)+0.0%
runtime.dotnet.mem.committed59.16 ± (59.12 - 59.20) MB59.18 ± (59.12 - 59.25) MB+0.0%✅⬆️
runtime.dotnet.threads.count30 ± (30 - 30)30 ± (30 - 30)-0.4%
.NET 6 - Baseline
process.internal_duration_ms218.62 ± (218.04 - 219.19) ms215.13 ± (214.61 - 215.66) ms-1.6%
process.time_to_main_ms81.01 ± (80.72 - 81.31) ms79.49 ± (79.24 - 79.74) ms-1.9%
runtime.dotnet.exceptions.count4 ± (4 - 4)4 ± (4 - 4)+0.0%
runtime.dotnet.mem.committed16.17 ± (16.15 - 16.19) MB16.17 ± (16.15 - 16.20) MB+0.0%✅⬆️
runtime.dotnet.threads.count20 ± (19 - 20)20 ± (19 - 20)+0.0%✅⬆️
.NET 6 - Bailout
process.internal_duration_ms216.76 ± (216.24 - 217.29) ms214.16 ± (213.62 - 214.71) ms-1.2%
process.time_to_main_ms81.17 ± (80.88 - 81.45) ms80.73 ± (80.47 - 80.99) ms-0.5%
runtime.dotnet.exceptions.count4 ± (4 - 4)4 ± (4 - 4)+0.0%
runtime.dotnet.mem.committed16.18 ± (16.15 - 16.20) MB16.24 ± (16.22 - 16.26) MB+0.4%✅⬆️
runtime.dotnet.threads.count20 ± (20 - 21)21 ± (20 - 21)+0.1%✅⬆️
.NET 6 - CallTarget+Inlining+NGEN
process.internal_duration_ms596.20 ± (593.96 - 598.43) ms597.77 ± (595.17 - 600.37) ms+0.3%✅⬆️
process.time_to_main_ms579.57 ± (578.24 - 580.89) ms572.96 ± (571.56 - 574.36) ms-1.1%
runtime.dotnet.exceptions.count4 ± (4 - 4)4 ± (4 - 4)+0.0%
runtime.dotnet.mem.committed61.61 ± (61.51 - 61.71) MB61.62 ± (61.50 - 61.73) MB+0.0%✅⬆️
runtime.dotnet.threads.count31 ± (31 - 31)31 ± (31 - 31)+0.1%✅⬆️
.NET 8 - Baseline
process.internal_duration_ms216.80 ± (216.24 - 217.36) ms213.71 ± (213.17 - 214.25) ms-1.4%
process.time_to_main_ms80.34 ± (80.07 - 80.62) ms79.02 ± (78.79 - 79.25) ms-1.7%
runtime.dotnet.exceptions.count4 ± (4 - 4)4 ± (4 - 4)+0.0%
runtime.dotnet.mem.committed11.53 ± (11.51 - 11.56) MB11.59 ± (11.57 - 11.62) MB+0.5%✅⬆️
runtime.dotnet.threads.count19 ± (19 - 19)19 ± (19 - 19)-0.2%
.NET 8 - Bailout
process.internal_duration_ms217.02 ± (216.46 - 217.58) ms212.92 ± (212.42 - 213.41) ms-1.9%
process.time_to_main_ms81.25 ± (81.00 - 81.49) ms80.05 ± (79.82 - 80.29) ms-1.5%
runtime.dotnet.exceptions.count4 ± (4 - 4)4 ± (4 - 4)+0.0%
runtime.dotnet.mem.committed11.55 ± (11.53 - 11.57) MB11.61 ± (11.58 - 11.63) MB+0.5%✅⬆️
runtime.dotnet.threads.count20 ± (20 - 20)20 ± (20 - 20)-0.4%
.NET 8 - CallTarget+Inlining+NGEN
process.internal_duration_ms596.06 ± (588.53 - 603.60) ms576.59 ± (568.49 - 584.69) ms-3.3%
process.time_to_main_ms539.44 ± (537.87 - 541.01) ms532.68 ± (531.59 - 533.77) ms-1.3%
runtime.dotnet.exceptions.count4 ± (4 - 4)4 ± (4 - 4)+0.0%
runtime.dotnet.mem.committed51.76 ± (51.67 - 51.85) MB51.45 ± (51.35 - 51.55) MB-0.6%
runtime.dotnet.threads.count30 ± (30 - 30)30 ± (30 - 30)+0.1%✅⬆️
Comparison explanation

Execution-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:

  • Welch test with statistical test for significance of 5%
  • Only results indicating a difference greater than 5% and 5 ms are considered.

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 charts
FakeDbCommand (.NET Framework 4.8)
gantt
    title Execution time (ms) FakeDbCommand (.NET Framework 4.8)
    dateFormat  x
    axisFormat %Q
    todayMarker off
    section Baseline
    This PR (8312) - mean (72ms)  : 69, 74
    master - mean (73ms)  : 70, 75

    section Bailout
    This PR (8312) - mean (77ms)  : 74, 79
    master - mean (76ms)  : 74, 78

    section CallTarget+Inlining+NGEN
    This PR (8312) - mean (1,085ms)  : 1033, 1138
    master - mean (1,075ms)  : 1036, 1115

Loading
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 (8312) - mean (114ms)  : 109, 118
    master - mean (113ms)  : 109, 116

    section Bailout
    This PR (8312) - mean (114ms)  : 111, 117
    master - mean (113ms)  : 111, 116

    section CallTarget+Inlining+NGEN
    This PR (8312) - mean (794ms)  : 779, 809
    master - mean (798ms)  : 781, 816

Loading
FakeDbCommand (.NET 6)
gantt
    title Execution time (ms) FakeDbCommand (.NET 6)
    dateFormat  x
    axisFormat %Q
    todayMarker off
    section Baseline
    This PR (8312) - mean (100ms)  : 97, 103
    master - mean (99ms)  : 96, 102

    section Bailout
    This PR (8312) - mean (101ms)  : 99, 103
    master - mean (100ms)  : 97, 103

    section CallTarget+Inlining+NGEN
    This PR (8312) - mean (950ms)  : 914, 986
    master - mean (946ms)  : 911, 980

Loading
FakeDbCommand (.NET 8)
gantt
    title Execution time (ms) FakeDbCommand (.NET 8)
    dateFormat  x
    axisFormat %Q
    todayMarker off
    section Baseline
    This PR (8312) - mean (99ms)  : 95, 103
    master - mean (98ms)  : 95, 101

    section Bailout
    This PR (8312) - mean (100ms)  : 98, 103
    master - mean (100ms)  : 97, 102

    section CallTarget+Inlining+NGEN
    This PR (8312) - mean (830ms)  : 793, 866
    master - mean (833ms)  : 786, 880

Loading
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 (8312) - mean (216ms)  : 210, 221
    master - mean (216ms)  : 211, 222

    section Bailout
    This PR (8312) - mean (219ms)  : 215, 223
    master - mean (222ms)  : 215, 228

    section CallTarget+Inlining+NGEN
    This PR (8312) - mean (1,259ms)  : 1198, 1319
    master - mean (1,269ms)  : 1205, 1332

Loading
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 (8312) - mean (311ms)  : 303, 319
    master - mean (315ms)  : 308, 322

    section Bailout
    This PR (8312) - mean (312ms)  : 305, 318
    master - mean (317ms)  : 310, 325

    section CallTarget+Inlining+NGEN
    This PR (8312) - mean (1,032ms)  : 1007, 1057
    master - mean (1,039ms)  : 1004, 1073

Loading
HttpMessageHandler (.NET 6)
gantt
    title Execution time (ms) HttpMessageHandler (.NET 6)
    dateFormat  x
    axisFormat %Q
    todayMarker off
    section Baseline
    This PR (8312) - mean (304ms)  : 296, 311
    master - mean (309ms)  : 301, 316

    section Bailout
    This PR (8312) - mean (304ms)  : 297, 311
    master - mean (307ms)  : 299, 315

    section CallTarget+Inlining+NGEN
    This PR (8312) - mean (1,202ms)  : 1171, 1233
    master - mean (1,208ms)  : 1170, 1246

Loading
HttpMessageHandler (.NET 8)
gantt
    title Execution time (ms) HttpMessageHandler (.NET 8)
    dateFormat  x
    axisFormat %Q
    todayMarker off
    section Baseline
    This PR (8312) - mean (303ms)  : 295, 312
    master - mean (308ms)  : 301, 315

    section Bailout
    This PR (8312) - mean (303ms)  : 297, 310
    master - mean (309ms)  : 298, 320

    section CallTarget+Inlining+NGEN
    This PR (8312) - mean (1,145ms)  : 1032, 1259
    master - mean (1,160ms)  : 1036, 1285

Loading

Extract the generation engine, configuration models, and resource templates
from the GUI into a standalone Core library. The GUI now delegates to Core,
reducing MainViewModel.Editor.cs from ~300 lines of inline logic to ~109 lines.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@bouwkast bouwkast force-pushed the steven/auto-instrumentation-gen-core branch from 7af054a to 72b14d2 Compare March 31, 2026 15:22
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

AI Generated Largely based on code generated by an AI or LLM. This label is the same across all dd-trace-* repos

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant