Skip to content

Propagate context for some stored procedures #6799

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 23 commits into from
Apr 1, 2025

Conversation

bouwkast
Copy link
Collaborator

@bouwkast bouwkast commented Mar 24, 2025

Summary of changes

Added some support for DBM propagation for Stored Procedures for Microsoft SQL Server (System.Data.SqlClient and Microsoft.Data.SqlClient).

  • Feature is disabled by default, controlled by new DD_TRACE_INJECT_CONTEXT_INTO_STORED_PROCEDURES_ENABLED flag
  • Only supports Microsoft SQL Server (System.Data.SqlClient and Microsoft.Data.SqlClient)
  • Only works for stored procedures without parameters or only with Input parameters (not Output, InputOutput, or ReturnValue)
  • Call set context_info for all stored procedures to propagate some context always

For technical details surrounding these limitations please refer to the docs/development/StoredProcedureInjection.md document added.

Reason for change

Stored Procedures need special handling to work with DBM propagation because:

  1. We can't directly modify the StoredProcedure CommandText as it represents the procedure name itself
  2. The RPC protocol for stored procedures differs significantly from regular SQL batch commands

Implementation details

  • Converts the Stored Procedure call to an equivalent EXEC command with:
EXEC procedureName @param1=@param1, @param2=@param2 /*dddbs='service'...*/
  • This uses the same quoting mechanism that is used in SqlCommand.cs
  • Changes CommandType from StoredProcedure to Text to enable the injection
  • Implements safety check to prevent applying the transformation to procedures with non-Input parameters
  • Call set context_info for stored procedures as this is a separate DB call and works fine

Technical Limitations

Output, InputOutput, and ReturnValue parameters aren't supported because:

  • When converting to Text commands, the automatic parameter value updating provided by ADO.NET is lost
  • The TDS protocol handling for RPC vs SQL batch execution differs significantly
  • Converting these would silently break applications that rely on output parameter values

Test coverage

Added various stored procedures to test it out, kept them in their own file for quicker implementation (and it isn't something that is supported across various DB types, just Microsoft SQL Server.

Other details

This implementation provides a balance between enabling monitoring capabilities while ensuring application reliability and correctness.

Only for Microsoft SQL Server and Full mode
@datadog-datadog-prod-us1
Copy link

datadog-datadog-prod-us1 bot commented Mar 24, 2025

Datadog Report

All test runs 436c29c 🔗

2 Total Test Services: 0 Failed, 2 Passed

Test Services
Service Name Failed Known Flaky New Flaky Passed Skipped Total Time Test Service View
dd-trace-dotnet 0 0 0 567413 4482 37h 27m 2.28s Link
exploration_tests 0 0 0 22085 3 2m 10.94s Link

@andrewlock
Copy link
Member

andrewlock commented Mar 24, 2025

Execution-Time Benchmarks Report ⏱️

Execution-time results for samples comparing the following branches/commits:

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 shown 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).

gantt
    title Execution time (ms) FakeDbCommand (.NET Framework 4.6.2) 
    dateFormat  X
    axisFormat %s
    todayMarker off
    section Baseline
    This PR (6799) - mean (70ms)  : 66, 73
     .   : milestone, 70,
    master - mean (70ms)  : 67, 73
     .   : milestone, 70,

    section CallTarget+Inlining+NGEN
    This PR (6799) - mean (1,009ms)  : 989, 1028
     .   : milestone, 1009,
    master - mean (1,008ms)  : 977, 1038
     .   : milestone, 1008,

Loading
gantt
    title Execution time (ms) FakeDbCommand (.NET Core 3.1) 
    dateFormat  X
    axisFormat %s
    todayMarker off
    section Baseline
    This PR (6799) - mean (104ms)  : 101, 107
     .   : milestone, 104,
    master - mean (103ms)  : 100, 105
     .   : milestone, 103,

    section CallTarget+Inlining+NGEN
    This PR (6799) - mean (693ms)  : 673, 713
     .   : milestone, 693,
    master - mean (688ms)  : 666, 710
     .   : milestone, 688,

Loading
gantt
    title Execution time (ms) FakeDbCommand (.NET 6) 
    dateFormat  X
    axisFormat %s
    todayMarker off
    section Baseline
    This PR (6799) - mean (90ms)  : 88, 92
     .   : milestone, 90,
    master - mean (90ms)  : 87, 92
     .   : milestone, 90,

    section CallTarget+Inlining+NGEN
    This PR (6799) - mean (642ms)  : 623, 661
     .   : milestone, 642,
    master - mean (643ms)  : 627, 658
     .   : milestone, 643,

Loading
gantt
    title Execution time (ms) HttpMessageHandler (.NET Framework 4.6.2) 
    dateFormat  X
    axisFormat %s
    todayMarker off
    section Baseline
    This PR (6799) - mean (190ms)  : 186, 193
     .   : milestone, 190,
    master - mean (190ms)  : 182, 199
     .   : milestone, 190,

    section CallTarget+Inlining+NGEN
    This PR (6799) - mean (1,102ms)  : 1078, 1127
     .   : milestone, 1102,
    master - mean (1,111ms)  : 1087, 1136
     .   : milestone, 1111,

Loading
gantt
    title Execution time (ms) HttpMessageHandler (.NET Core 3.1) 
    dateFormat  X
    axisFormat %s
    todayMarker off
    section Baseline
    This PR (6799) - mean (269ms)  : 265, 273
     .   : milestone, 269,
    master - mean (268ms)  : 264, 273
     .   : milestone, 268,

    section CallTarget+Inlining+NGEN
    This PR (6799) - mean (873ms)  : 841, 904
     .   : milestone, 873,
    master - mean (873ms)  : 847, 898
     .   : milestone, 873,

Loading
gantt
    title Execution time (ms) HttpMessageHandler (.NET 6) 
    dateFormat  X
    axisFormat %s
    todayMarker off
    section Baseline
    This PR (6799) - mean (262ms)  : 258, 265
     .   : milestone, 262,
    master - mean (261ms)  : 257, 264
     .   : milestone, 261,

    section CallTarget+Inlining+NGEN
    This PR (6799) - mean (852ms)  : 821, 882
     .   : milestone, 852,
    master - mean (854ms)  : 824, 885
     .   : milestone, 854,

Loading

@andrewlock
Copy link
Member

andrewlock commented Mar 24, 2025

Benchmarks Report for tracer 🐌

Benchmarks for #6799 compared to master:

  • 2 benchmarks are faster, with geometric mean 1.134
  • All benchmarks have the same allocations

The following thresholds were used for comparing the benchmark speeds:

  • Mann–Whitney U test with statistical test for significance of 5%
  • Only results indicating a difference greater than 10% and 0.3 ns are considered.

Allocation changes below 0.5% are ignored.

Benchmark details

Benchmarks.Trace.ActivityBenchmark - Same speed ✔️ Same allocations ✔️

Raw results

Branch Method Toolchain Mean StdError StdDev Gen 0 Gen 1 Gen 2 Allocated
master StartStopWithChild net6.0 8.05μs 46.4ns 359ns 0.0159 0.00796 0 5.61 KB
master StartStopWithChild netcoreapp3.1 9.98μs 54.5ns 327ns 0.0201 0.01 0 5.8 KB
master StartStopWithChild net472 16.2μs 46.5ns 180ns 1.06 0.321 0.104 6.21 KB
#6799 StartStopWithChild net6.0 7.94μs 44.5ns 288ns 0.0191 0.00762 0 5.61 KB
#6799 StartStopWithChild netcoreapp3.1 10.3μs 57.7ns 383ns 0.0256 0.0102 0 5.8 KB
#6799 StartStopWithChild net472 16.4μs 60.4ns 234ns 1.05 0.317 0.0895 6.21 KB
Benchmarks.Trace.AgentWriterBenchmark - Same speed ✔️ Same allocations ✔️

Raw results

Branch Method Toolchain Mean StdError StdDev Gen 0 Gen 1 Gen 2 Allocated
master WriteAndFlushEnrichedTraces net6.0 517μs 757ns 2.93μs 0 0 0 2.7 KB
master WriteAndFlushEnrichedTraces netcoreapp3.1 655μs 822ns 3.18μs 0 0 0 2.7 KB
master WriteAndFlushEnrichedTraces net472 847μs 705ns 2.73μs 0.422 0 0 3.3 KB
#6799 WriteAndFlushEnrichedTraces net6.0 486μs 585ns 2.27μs 0 0 0 2.7 KB
#6799 WriteAndFlushEnrichedTraces netcoreapp3.1 663μs 486ns 1.82μs 0 0 0 2.7 KB
#6799 WriteAndFlushEnrichedTraces net472 853μs 1.13μs 4.39μs 0.428 0 0 3.3 KB
Benchmarks.Trace.AspNetCoreBenchmark - Same speed ✔️ Same allocations ✔️

Raw results

Branch Method Toolchain Mean StdError StdDev Gen 0 Gen 1 Gen 2 Allocated
master SendRequest net6.0 133μs 246ns 955ns 0.133 0 0 14.47 KB
master SendRequest netcoreapp3.1 144μs 419ns 1.62μs 0.216 0 0 17.27 KB
master SendRequest net472 0.000227ns 0.000126ns 0.000454ns 0 0 0 0 b
#6799 SendRequest net6.0 131μs 347ns 1.3μs 0.19 0 0 14.47 KB
#6799 SendRequest netcoreapp3.1 145μs 322ns 1.25μs 0.214 0 0 17.27 KB
#6799 SendRequest net472 0ns 0ns 0ns 0 0 0 0 b
Benchmarks.Trace.CIVisibilityProtocolWriterBenchmark - Same speed ✔️ Same allocations ✔️

Raw results

Branch Method Toolchain Mean StdError StdDev Gen 0 Gen 1 Gen 2 Allocated
master WriteAndFlushEnrichedTraces net6.0 589μs 3.4μs 27.2μs 0.568 0 0 41.72 KB
master WriteAndFlushEnrichedTraces netcoreapp3.1 713μs 4.13μs 35μs 0.359 0 0 41.77 KB
master WriteAndFlushEnrichedTraces net472 841μs 4.1μs 17.4μs 8.45 2.53 0.422 53.29 KB
#6799 WriteAndFlushEnrichedTraces net6.0 574μs 2.93μs 18.3μs 0.556 0 0 41.64 KB
#6799 WriteAndFlushEnrichedTraces netcoreapp3.1 748μs 4.06μs 28.1μs 0.34 0 0 41.85 KB
#6799 WriteAndFlushEnrichedTraces net472 856μs 3.45μs 12.9μs 8.19 2.59 0.431 53.3 KB
Benchmarks.Trace.DbCommandBenchmark - Same speed ✔️ Same allocations ✔️

Raw results

Branch Method Toolchain Mean StdError StdDev Gen 0 Gen 1 Gen 2 Allocated
master ExecuteNonQuery net6.0 1.3μs 1.27ns 4.76ns 0.0145 0 0 1.02 KB
master ExecuteNonQuery netcoreapp3.1 1.72μs 2.42ns 9.38ns 0.0138 0 0 1.02 KB
master ExecuteNonQuery net472 2.13μs 3.99ns 15.4ns 0.156 0.00106 0 987 B
#6799 ExecuteNonQuery net6.0 1.33μs 0.89ns 3.33ns 0.0144 0 0 1.02 KB
#6799 ExecuteNonQuery netcoreapp3.1 1.81μs 2.9ns 11.2ns 0.0134 0 0 1.02 KB
#6799 ExecuteNonQuery net472 2.16μs 3.06ns 11.9ns 0.156 0.00108 0 987 B
Benchmarks.Trace.ElasticsearchBenchmark - Faster 🎉 Same allocations ✔️

Faster 🎉 in #6799

Benchmark base/diff Base Median (ns) Diff Median (ns) Modality
Benchmarks.Trace.ElasticsearchBenchmark.CallElasticsearchAsync‑net6.0 1.153 1,441.07 1,250.37

Raw results

Branch Method Toolchain Mean StdError StdDev Gen 0 Gen 1 Gen 2 Allocated
master CallElasticsearch net6.0 1.15μs 0.443ns 1.66ns 0.0138 0 0 976 B
master CallElasticsearch netcoreapp3.1 1.6μs 0.602ns 2.33ns 0.0132 0 0 976 B
master CallElasticsearch net472 2.69μs 1.43ns 5.55ns 0.157 0 0 995 B
master CallElasticsearchAsync net6.0 1.44μs 0.59ns 2.21ns 0.0129 0 0 952 B
master CallElasticsearchAsync netcoreapp3.1 1.72μs 1.33ns 4.6ns 0.0137 0 0 1.02 KB
master CallElasticsearchAsync net472 2.58μs 1.55ns 5.99ns 0.167 0 0 1.05 KB
#6799 CallElasticsearch net6.0 1.08μs 0.345ns 1.34ns 0.0136 0 0 976 B
#6799 CallElasticsearch netcoreapp3.1 1.54μs 1.11ns 4.15ns 0.013 0 0 976 B
#6799 CallElasticsearch net472 2.65μs 1.73ns 6.71ns 0.157 0 0 995 B
#6799 CallElasticsearchAsync net6.0 1.25μs 0.368ns 1.38ns 0.0131 0 0 952 B
#6799 CallElasticsearchAsync netcoreapp3.1 1.59μs 0.852ns 3.19ns 0.0135 0 0 1.02 KB
#6799 CallElasticsearchAsync net472 2.71μs 1.6ns 6.18ns 0.167 0 0 1.05 KB
Benchmarks.Trace.GraphQLBenchmark - Faster 🎉 Same allocations ✔️

Faster 🎉 in #6799

Benchmark base/diff Base Median (ns) Diff Median (ns) Modality
Benchmarks.Trace.GraphQLBenchmark.ExecuteAsync‑net6.0 1.116 1,301.65 1,166.27

Raw results

Branch Method Toolchain Mean StdError StdDev Gen 0 Gen 1 Gen 2 Allocated
master ExecuteAsync net6.0 1.3μs 0.549ns 2.05ns 0.013 0 0 952 B
master ExecuteAsync netcoreapp3.1 1.69μs 0.981ns 3.8ns 0.0126 0 0 952 B
master ExecuteAsync net472 1.75μs 0.447ns 1.73ns 0.145 0 0 915 B
#6799 ExecuteAsync net6.0 1.17μs 1.14ns 4.41ns 0.0134 0 0 952 B
#6799 ExecuteAsync netcoreapp3.1 1.62μs 0.663ns 2.39ns 0.0131 0 0 952 B
#6799 ExecuteAsync net472 1.75μs 0.372ns 1.39ns 0.145 0 0 915 B
Benchmarks.Trace.HttpClientBenchmark - Same speed ✔️ Same allocations ✔️

Raw results

Branch Method Toolchain Mean StdError StdDev Gen 0 Gen 1 Gen 2 Allocated
master SendAsync net6.0 4.29μs 1.83ns 6.61ns 0.0323 0 0 2.31 KB
master SendAsync netcoreapp3.1 5.3μs 2.41ns 9.34ns 0.0371 0 0 2.85 KB
master SendAsync net472 7.53μs 1.4ns 5.43ns 0.493 0 0 3.12 KB
#6799 SendAsync net6.0 4.36μs 1.45ns 5.61ns 0.0308 0 0 2.31 KB
#6799 SendAsync netcoreapp3.1 5.32μs 1.39ns 4.82ns 0.0375 0 0 2.85 KB
#6799 SendAsync net472 7.43μs 2.04ns 7.9ns 0.493 0 0 3.12 KB
Benchmarks.Trace.ILoggerBenchmark - Same speed ✔️ Same allocations ✔️

Raw results

Branch Method Toolchain Mean StdError StdDev Gen 0 Gen 1 Gen 2 Allocated
master EnrichedLog net6.0 1.58μs 0.958ns 3.71ns 0.0237 0 0 1.69 KB
master EnrichedLog netcoreapp3.1 2.37μs 0.96ns 3.59ns 0.0225 0 0 1.69 KB
master EnrichedLog net472 2.44μs 1.31ns 5.07ns 0.258 0 0 1.62 KB
#6799 EnrichedLog net6.0 1.5μs 0.798ns 2.99ns 0.0237 0 0 1.69 KB
#6799 EnrichedLog netcoreapp3.1 2.35μs 6.01ns 22.5ns 0.0231 0 0 1.69 KB
#6799 EnrichedLog net472 2.64μs 1.66ns 6.44ns 0.257 0 0 1.62 KB
Benchmarks.Trace.Log4netBenchmark - Same speed ✔️ Same allocations ✔️

Raw results

Branch Method Toolchain Mean StdError StdDev Gen 0 Gen 1 Gen 2 Allocated
master EnrichedLog net6.0 113μs 108ns 417ns 0.0561 0 0 4.3 KB
master EnrichedLog netcoreapp3.1 119μs 214ns 800ns 0.0589 0 0 4.3 KB
master EnrichedLog net472 151μs 110ns 428ns 0.678 0.226 0 4.49 KB
#6799 EnrichedLog net6.0 112μs 159ns 615ns 0.0558 0 0 4.3 KB
#6799 EnrichedLog netcoreapp3.1 118μs 235ns 909ns 0.0597 0 0 4.3 KB
#6799 EnrichedLog net472 150μs 91.8ns 356ns 0.673 0.224 0 4.49 KB
Benchmarks.Trace.NLogBenchmark - Same speed ✔️ Same allocations ✔️

Raw results

Branch Method Toolchain Mean StdError StdDev Gen 0 Gen 1 Gen 2 Allocated
master EnrichedLog net6.0 3.13μs 1ns 3.88ns 0.0312 0 0 2.25 KB
master EnrichedLog netcoreapp3.1 4.06μs 0.887ns 3.32ns 0.0305 0 0 2.25 KB
master EnrichedLog net472 4.72μs 1.46ns 5.65ns 0.327 0 0 2.07 KB
#6799 EnrichedLog net6.0 3.03μs 1.02ns 3.95ns 0.0319 0 0 2.25 KB
#6799 EnrichedLog netcoreapp3.1 4.04μs 4.15ns 16.1ns 0.0305 0 0 2.25 KB
#6799 EnrichedLog net472 4.84μs 1.75ns 6.78ns 0.328 0 0 2.07 KB
Benchmarks.Trace.RedisBenchmark - Same speed ✔️ Same allocations ✔️

Raw results

Branch Method Toolchain Mean StdError StdDev Gen 0 Gen 1 Gen 2 Allocated
master SendReceive net6.0 1.31μs 0.843ns 3.26ns 0.0157 0 0 1.14 KB
master SendReceive netcoreapp3.1 1.78μs 2.45ns 9.5ns 0.0151 0 0 1.14 KB
master SendReceive net472 2.04μs 1.38ns 5.36ns 0.184 0 0 1.16 KB
#6799 SendReceive net6.0 1.35μs 0.735ns 2.84ns 0.0162 0 0 1.14 KB
#6799 SendReceive netcoreapp3.1 1.8μs 1.02ns 3.94ns 0.0154 0 0 1.14 KB
#6799 SendReceive net472 2.08μs 1.05ns 4.08ns 0.183 0 0 1.16 KB
Benchmarks.Trace.SerilogBenchmark - Same speed ✔️ Same allocations ✔️

Raw results

Branch Method Toolchain Mean StdError StdDev Gen 0 Gen 1 Gen 2 Allocated
master EnrichedLog net6.0 2.75μs 0.697ns 2.61ns 0.022 0 0 1.62 KB
master EnrichedLog netcoreapp3.1 4.26μs 1.42ns 5.49ns 0.0212 0 0 1.67 KB
master EnrichedLog net472 4.53μs 2.58ns 10ns 0.328 0 0 2.07 KB
#6799 EnrichedLog net6.0 2.68μs 1.34ns 4.64ns 0.0228 0 0 1.62 KB
#6799 EnrichedLog netcoreapp3.1 3.95μs 1.3ns 5.02ns 0.0218 0 0 1.67 KB
#6799 EnrichedLog net472 4.42μs 1.54ns 5.74ns 0.327 0 0 2.07 KB
Benchmarks.Trace.SpanBenchmark - Same speed ✔️ Same allocations ✔️

Raw results

Branch Method Toolchain Mean StdError StdDev Gen 0 Gen 1 Gen 2 Allocated
master StartFinishSpan net6.0 413ns 0.575ns 2.23ns 0.0081 0 0 576 B
master StartFinishSpan netcoreapp3.1 612ns 0.345ns 1.33ns 0.0079 0 0 576 B
master StartFinishSpan net472 635ns 0.137ns 0.514ns 0.0917 0 0 578 B
master StartFinishScope net6.0 520ns 0.146ns 0.565ns 0.00966 0 0 696 B
master StartFinishScope netcoreapp3.1 741ns 0.493ns 1.91ns 0.00923 0 0 696 B
master StartFinishScope net472 873ns 0.208ns 0.807ns 0.104 0 0 658 B
#6799 StartFinishSpan net6.0 409ns 0.15ns 0.561ns 0.00808 0 0 576 B
#6799 StartFinishSpan netcoreapp3.1 566ns 1.41ns 5.47ns 0.00795 0 0 576 B
#6799 StartFinishSpan net472 596ns 0.455ns 1.7ns 0.0918 0 0 578 B
#6799 StartFinishScope net6.0 494ns 0.177ns 0.663ns 0.0097 0 0 696 B
#6799 StartFinishScope netcoreapp3.1 748ns 0.693ns 2.69ns 0.00954 0 0 696 B
#6799 StartFinishScope net472 867ns 0.203ns 0.784ns 0.105 0 0 658 B
Benchmarks.Trace.TraceAnnotationsBenchmark - Same speed ✔️ Same allocations ✔️

Raw results

Branch Method Toolchain Mean StdError StdDev Gen 0 Gen 1 Gen 2 Allocated
master RunOnMethodBegin net6.0 656ns 0.14ns 0.504ns 0.00983 0 0 696 B
master RunOnMethodBegin netcoreapp3.1 987ns 1.16ns 4.18ns 0.00934 0 0 696 B
master RunOnMethodBegin net472 1.05μs 0.348ns 1.35ns 0.104 0 0 658 B
#6799 RunOnMethodBegin net6.0 602ns 0.246ns 0.953ns 0.00968 0 0 696 B
#6799 RunOnMethodBegin netcoreapp3.1 990ns 1.46ns 5.66ns 0.00951 0 0 696 B
#6799 RunOnMethodBegin net472 1.12μs 0.333ns 1.25ns 0.104 0 0 658 B


// Build parameter list for EXEC statement
StringBuilder paramList = new StringBuilder();
foreach (DbParameter? param in command.Parameters)
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

DbParameter

Needed to add System.Data.Common as a using I think it is fine?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

According to the apisof.net entry for DbParameter this is built-in on all versions of .NET Framework as well as .NET Core 2.0+ and .NET Standard 2.0, so this is fine. What would be a red flag is if this added a new AssemblyReference, in which case our unit tests would start failing

}
else
{
command.CommandText = $"EXEC {procName} {propagationComment}";
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

EXEC dbo.ProcedureName /* comment */

// Create EXEC statement with parameters
if (paramList.Length > 0)
{
command.CommandText = $"EXEC {procName} {paramList} {propagationComment}";
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Basic case with 1 param

EXEC dbo.sp_GetTestRow @Id=@Id /*dddbs='Samples.SqlServer-sql-server',dde='steven.bouwkamp',ddps='Samples.SqlServer',ddh='(localdb)%5CMSSQLLocalDB',ddpv='1.0.0'*/

if (param.Direction == ParameterDirection.InputOutput || param.Direction == ParameterDirection.Output)
{
// For OUTPUT parameters, we need to add the OUTPUT keyword
paramList.Append(" OUTPUT");
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Special case

EXEC dbo.TestOutputParams @Input=@Input, @Output1=@Output1 OUTPUT, @Output2=@Output2 OUTPUT /*dddbs='Samples.SqlServer-sql-server',dde='steven.bouwkamp',ddps='Samples.SqlServer',ddh='(localdb)%5CMSSQLLocalDB',ddpv='1.0.0'*/ 


if (paramList.Length > 0)
{
paramList.Append(", ");
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Many params need the , (comma)

EXEC dbo.TestOutputParams @Input=@Input, @Output1=@Output1 OUTPUT, @Output2=@Output2 OUTPUT /*dddbs='Samples.SqlServer-sql-server',dde='steven.bouwkamp',ddps='Samples.SqlServer',ddh='(localdb)%5CMSSQLLocalDB',ddpv='1.0.0'*/ 

paramList.Append(", ");
}

paramList.Append(param.ParameterName).Append('=').Append(param.ParameterName);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not really educated on SQL, but do we need it to be inserted as @PARAM_NAME1=@PARAM_NAME1,@PARAM_NAME2=@PARAM_NAME2 or can it simply be inserted as @PARAM_NAME1, @PARAM_NAME2 ?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So you can do that, but it then requires them all to be in the same position as defined. This = way means that the order of the parameters isn't important

So I think that then risks something like the Parameter.Add order to be critical for users

command.Parameter.Add(Param2)
command.Parameter.Add(Param1)

I'm not 100% sure on this though, so I could test it out.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That sounds safer, so if your proposed approach works then I don't see a need to test my suggestion

Copy link
Contributor

Snapshots difference summary

The following differences have been observed in committed snapshots. It is meant to help the reviewer.
The diff is simplistic, so please check some files anyway while we improve it.

4 occurrences of :

-    Resource: DELETE FROM [System-Data-SqlClient-Test-GUID] WHERE Id=@Id;,
+    Resource:
[...]
+    @Id int,
+    @NewName varchar(100)
[...]
+    -- Update the specified row
+    UPDATE [Stored-Proc-System-Data-SqlClient-Test-GUID] SET Name = @NewName WHERE Id = @Id;
+    -- Return affected rows
+    RETURN @@ROWCOUNT;
[...]
-    ParentId: Id_3,

2 occurrences of :

-      _dd.top_level: 1.0
+      process_id: 0,
+      _dd.top_level: 1.0,
+      _dd.tracer_kr: 1.0,
+      _sampling_priority_v1: 1.0
[...]
-    TraceId: Id_1,
+    TraceId: Id_3,
[...]
-    Resource: DELETE FROM [System-Data-SqlClient-Test-GUID] WHERE Id=@Id;,
+    Resource:
[...]
+    @Id int
[...]
+    SELECT * FROM [Stored-Proc-System-Data-SqlClient-Test-GUID] WHERE Id = @Id;
[...]
-    ParentId: Id_5,

2 occurrences of :

-      _dd.top_level: 1.0
+      process_id: 0,
+      _dd.top_level: 1.0,
+      _dd.tracer_kr: 1.0,
+      _sampling_priority_v1: 1.0
[...]
-    TraceId: Id_1,
+    TraceId: Id_5,
[...]
-    Resource: DELETE FROM [System-Data-SqlClient-Test-GUID] WHERE Id=@Id;,
+    Resource:
[...]
+    @Id int,
+    @NewName varchar(100),
+    @OldName varchar(100) OUTPUT
[...]
+    -- Store the old name before updating
+    SELECT @OldName = Name FROM [Stored-Proc-System-Data-SqlClient-Test-GUID] WHERE Id = @Id;
+    -- Update the row
+    UPDATE [Stored-Proc-System-Data-SqlClient-Test-GUID] SET Name = @NewName WHERE Id = @Id;
+    -- Return number of rows affected
+    RETURN @@ROWCOUNT;
[...]
-    ParentId: Id_7,

2 occurrences of :

-      _dd.top_level: 1.0
+      process_id: 0,
+      _dd.top_level: 1.0,
+      _dd.tracer_kr: 1.0,
+      _sampling_priority_v1: 1.0
[...]
-    TraceId: Id_1,
+    TraceId: Id_7,
[...]
-    Resource: DELETE FROM [System-Data-SqlClient-Test-GUID] WHERE Id=@Id;,
+    Resource:
[...]
-    ParentId: Id_9,

2 occurrences of :

-      _dd.top_level: 1.0
+      process_id: 0,
+      _dd.top_level: 1.0,
+      _dd.tracer_kr: 1.0,
+      _sampling_priority_v1: 1.0
[...]
-    TraceId: Id_1,
+    TraceId: Id_9,
[...]
-    Resource: DELETE FROM [System-Data-SqlClient-Test-GUID] WHERE Id=@Id;,
+    Resource: CREATE TABLE [Stored-Proc-System-Data-SqlClient-Test-GUID] (Id int PRIMARY KEY, Name varchar(100));,
[...]
-    ParentId: Id_11,

2 occurrences of :

-      _dd.top_level: 1.0
+      process_id: 0,
+      _dd.top_level: 1.0,
+      _dd.tracer_kr: 1.0,
+      _sampling_priority_v1: 1.0
[...]
-    TraceId: Id_1,
+    TraceId: Id_11,
[...]
-    Resource: DELETE FROM [System-Data-SqlClient-Test-GUID] WHERE Id=@Id;,
+    Resource: dbo.sp_BatchUpdate,
[...]
-    ParentId: Id_13,

2 occurrences of :

-      _dd.top_level: 1.0
+      process_id: 0,
+      _dd.top_level: 1.0,
+      _dd.tracer_kr: 1.0,
+      _sampling_priority_v1: 1.0
[...]
-    TraceId: Id_1,
+    TraceId: Id_13,
[...]
-    Resource: DELETE FROM [System-Data-SqlClient-Test-GUID] WHERE Id=@Id;,
+    Resource: dbo.sp_BatchUpdate,
[...]
-    ParentId: Id_15,

2 occurrences of :

-      _dd.top_level: 1.0
+      process_id: 0,
+      _dd.top_level: 1.0,
+      _dd.tracer_kr: 1.0,
+      _sampling_priority_v1: 1.0
[...]
-    TraceId: Id_1,
+    TraceId: Id_15,
[...]
-    Resource: DELETE FROM [System-Data-SqlClient-Test-GUID] WHERE Id=@Id;,
+    Resource: dbo.sp_GetTableRow,
[...]
-    ParentId: Id_17,

2 occurrences of :

-      _dd.top_level: 1.0
+      process_id: 0,
+      _dd.top_level: 1.0,
+      _dd.tracer_kr: 1.0,
+      _sampling_priority_v1: 1.0
[...]
-    TraceId: Id_1,
+    TraceId: Id_17,
[...]
-    Resource: DELETE FROM [System-Data-SqlClient-Test-GUID] WHERE Id=@Id;,
+    Resource: dbo.sp_UpdateRowWithOutput,
[...]
-    ParentId: Id_19,

2 occurrences of :

-      _dd.top_level: 1.0
+      process_id: 0,
+      _dd.top_level: 1.0,
+      _dd.tracer_kr: 1.0,
+      _sampling_priority_v1: 1.0
[...]
-    TraceId: Id_1,
+    TraceId: Id_19,

12 occurrences of :

-    TraceId: Id_1,
+    TraceId: Id_19,

3 occurrences of :

-    TraceId: Id_28,
-    SpanId: Id_29,
+    TraceId: Id_19,
+    SpanId: Id_28,
[...]
-    ParentId: Id_30,
+    ParentId: Id_29,

3 occurrences of :

-    TraceId: Id_28,
-    SpanId: Id_31,
+    TraceId: Id_19,
+    SpanId: Id_30,
[...]
-    ParentId: Id_32,
+    ParentId: Id_31,

3 occurrences of :

-    TraceId: Id_28,
-    SpanId: Id_33,
+    TraceId: Id_19,
+    SpanId: Id_32,
[...]
-    ParentId: Id_34,
+    ParentId: Id_33,

1 occurrences of :

-    TraceId: Id_35,
+    TraceId: Id_19,
+    SpanId: Id_34,
+    Name: sql-server.query,
+    Resource: DELETE FROM [System-Data-SqlClient-Test-GUID] WHERE Id=@Id;,
+    Service: Samples.SqlServer-sql-server,
+    Type: sql,
+    ParentId: Id_35,
+    Tags: {
+      component: SqlClient,
+      db.type: sql-server,
+      env: integration_tests,
+      language: dotnet,
+      out.host: sqlserver,
+      runtime-id: Guid_1,
+      span.kind: client,
+      _dd.base_service: Samples.SqlServer,
+      _dd.dbm_trace_injected: true
+    },
+    Metrics: {
+      dd.instrumentation.time_ms: 123.456,
+      _dd.top_level: 1.0
+    }
+  },
+  {
+    TraceId: Id_19,

17 occurrences of :

-    TraceId: Id_35,
+    TraceId: Id_19,

4 occurrences of :

-    TraceId: Id_35,
-    SpanId: Id_46,
+    TraceId: Id_46,
+    SpanId: Id_47,
[...]
-    ParentId: Id_47,
+    ParentId: Id_48,

4 occurrences of :

-    TraceId: Id_35,
-    SpanId: Id_48,
+    TraceId: Id_46,
+    SpanId: Id_49,
[...]
-    ParentId: Id_49,
+    ParentId: Id_50,

4 occurrences of :

-    TraceId: Id_35,
-    SpanId: Id_50,
+    TraceId: Id_46,
+    SpanId: Id_51,
[...]
-    ParentId: Id_51,
+    ParentId: Id_52,

1 occurrences of :

-    TraceId: Id_1,
-    SpanId: Id_52,
+    TraceId: Id_53,
+    SpanId: Id_54,
+    Name: sql-server.query,
+    Resource: DELETE FROM [System-Data-SqlClient-Test-GUID] WHERE Id=@Id;,
+    Service: Samples.SqlServer-sql-server,
+    Type: sql,
+    ParentId: Id_55,
+    Tags: {
+      component: SqlClient,
+      db.type: sql-server,
+      env: integration_tests,
+      language: dotnet,
+      out.host: sqlserver,
+      runtime-id: Guid_1,
+      span.kind: client,
+      _dd.base_service: Samples.SqlServer,
+      _dd.dbm_trace_injected: true
+    },
+    Metrics: {
+      dd.instrumentation.time_ms: 123.456,
+      _dd.top_level: 1.0
+    }
+  },
+  {
+    TraceId: Id_53,
+    SpanId: Id_56,
+    Name: sql-server.query,
+    Resource: DELETE FROM [System-Data-SqlClient-Test-GUID] WHERE Id=@Id;,
+    Service: Samples.SqlServer-sql-server,
+    Type: sql,
+    ParentId: Id_57,
+    Tags: {
+      component: SqlClient,
+      db.type: sql-server,
+      env: integration_tests,
+      language: dotnet,
+      out.host: sqlserver,
+      runtime-id: Guid_1,
+      span.kind: client,
+      _dd.base_service: Samples.SqlServer,
+      _dd.dbm_trace_injected: true
+    },
+    Metrics: {
+      dd.instrumentation.time_ms: 123.456,
+      _dd.top_level: 1.0
+    }
+  },
+  {
+    TraceId: Id_53,
+    SpanId: Id_58,
+    Name: sql-server.query,
+    Resource: DELETE FROM [System-Data-SqlClient-Test-GUID] WHERE Id=@Id;,
+    Service: Samples.SqlServer-sql-server,
+    Type: sql,
+    ParentId: Id_59,
+    Tags: {
+      component: SqlClient,
+      db.type: sql-server,
+      env: integration_tests,
+      language: dotnet,
+      out.host: sqlserver,
+      runtime-id: Guid_1,
+      span.kind: client,
+      _dd.base_service: Samples.SqlServer,
+      _dd.dbm_trace_injected: true
+    },
+    Metrics: {
+      dd.instrumentation.time_ms: 123.456,
+      _dd.top_level: 1.0
+    }
+  },
+  {
+    TraceId: Id_53,
+    SpanId: Id_60,
+    Name: sql-server.query,
+    Resource: DELETE FROM [System-Data-SqlClient-Test-GUID] WHERE Id=@Id;,
+    Service: Samples.SqlServer-sql-server,
+    Type: sql,
+    ParentId: Id_61,
+    Tags: {
+      component: SqlClient,
+      db.type: sql-server,
+      env: integration_tests,
+      language: dotnet,
+      out.host: sqlserver,
+      runtime-id: Guid_1,
+      span.kind: client,
+      _dd.base_service: Samples.SqlServer,
+      _dd.dbm_trace_injected: true
+    },
+    Metrics: {
+      dd.instrumentation.time_ms: 123.456,
+      _dd.top_level: 1.0
+    }
+  },
+  {
+    TraceId: Id_53,
+    SpanId: Id_62,
+    Name: sql-server.query,
+    Resource: DELETE FROM [System-Data-SqlClient-Test-GUID] WHERE Id=@Id;,
+    Service: Samples.SqlServer-sql-server,
+    Type: sql,
+    ParentId: Id_63,
+    Tags: {
+      component: SqlClient,
+      db.type: sql-server,
+      env: integration_tests,
+      language: dotnet,
+      out.host: sqlserver,
+      runtime-id: Guid_1,
+      span.kind: client,
+      _dd.base_service: Samples.SqlServer,
+      _dd.dbm_trace_injected: true
+    },
+    Metrics: {
+      dd.instrumentation.time_ms: 123.456,
+      _dd.top_level: 1.0
+    }
+  },
+  {
+    TraceId: Id_53,
+    SpanId: Id_64,
+    Name: sql-server.query,
+    Resource: DELETE FROM [System-Data-SqlClient-Test-GUID] WHERE Id=@Id;,
+    Service: Samples.SqlServer-sql-server,
+    Type: sql,
+    ParentId: Id_65,
+    Tags: {
+      component: SqlClient,
+      db.type: sql-server,
+      env: integration_tests,
+      language: dotnet,
+      out.host: sqlserver,
+      runtime-id: Guid_1,
+      span.kind: client,
+      _dd.base_service: Samples.SqlServer,
+      _dd.dbm_trace_injected: true
+    },
+    Metrics: {
+      dd.instrumentation.time_ms: 123.456,
+      _dd.top_level: 1.0
+    }
+  },
+  {
+    TraceId: Id_53,
+    SpanId: Id_66,
+    Name: sql-server.query,
+    Resource: DELETE FROM [System-Data-SqlClient-Test-GUID] WHERE Id=@Id;,
+    Service: Samples.SqlServer-sql-server,
+    Type: sql,
+    ParentId: Id_67,
+    Tags: {
+      component: SqlClient,
+      db.type: sql-server,
+      env: integration_tests,
+      language: dotnet,
+      out.host: sqlserver,
+      runtime-id: Guid_1,
+      span.kind: client,
+      _dd.base_service: Samples.SqlServer,
+      _dd.dbm_trace_injected: true
+    },
+    Metrics: {
+      dd.instrumentation.time_ms: 123.456,
+      _dd.top_level: 1.0
+    }
+  },
+  {
+    TraceId: Id_53,
+    SpanId: Id_68,
+    Name: sql-server.query,
+    Resource: DELETE FROM [System-Data-SqlClient-Test-GUID] WHERE Id=@Id;,
+    Service: Samples.SqlServer-sql-server,
+    Type: sql,
+    ParentId: Id_69,
+    Tags: {
+      component: SqlClient,
+      db.type: sql-server,
+      env: integration_tests,
+      language: dotnet,
+      out.host: sqlserver,
+      runtime-id: Guid_1,
+      span.kind: client,
+      _dd.base_service: Samples.SqlServer,
+      _dd.dbm_trace_injected: true
+    },
+    Metrics: {
+      dd.instrumentation.time_ms: 123.456,
+      _dd.top_level: 1.0
+    }
+  },
+  {
+    TraceId: Id_19,
+    SpanId: Id_70,
[...]
-    ParentId: Id_3,
+    ParentId: Id_21,

4 occurrences of :

-    TraceId: Id_1,
-    SpanId: Id_53,
+    TraceId: Id_19,
+    SpanId: Id_71,
[...]
-    ParentId: Id_5,
+    ParentId: Id_23,

4 occurrences of :

-    TraceId: Id_1,
-    SpanId: Id_54,
+    TraceId: Id_19,
+    SpanId: Id_72,
[...]
-    ParentId: Id_7,
+    ParentId: Id_25,

4 occurrences of :

-    TraceId: Id_1,
-    SpanId: Id_55,
+    TraceId: Id_19,
+    SpanId: Id_73,
[...]
-    ParentId: Id_9,
+    ParentId: Id_27,

4 occurrences of :

-    TraceId: Id_1,
-    SpanId: Id_56,
+    TraceId: Id_19,
+    SpanId: Id_74,
[...]
-    ParentId: Id_11,
+    ParentId: Id_29,

4 occurrences of :

-    TraceId: Id_1,
-    SpanId: Id_57,
+    TraceId: Id_19,
+    SpanId: Id_75,
[...]
-    ParentId: Id_13,
+    ParentId: Id_31,

4 occurrences of :

-    TraceId: Id_1,
-    SpanId: Id_58,
+    TraceId: Id_19,
+    SpanId: Id_76,
[...]
-    ParentId: Id_15,
+    ParentId: Id_33,

4 occurrences of :

-    TraceId: Id_1,
-    SpanId: Id_59,
+    TraceId: Id_19,
+    SpanId: Id_77,
[...]
-    ParentId: Id_17,
+    ParentId: Id_35,

4 occurrences of :

-    TraceId: Id_1,
-    SpanId: Id_60,
+    TraceId: Id_19,
+    SpanId: Id_78,
[...]
-    ParentId: Id_19,
+    ParentId: Id_37,

4 occurrences of :

-    TraceId: Id_1,
-    SpanId: Id_61,
+    TraceId: Id_19,
+    SpanId: Id_79,
[...]
-    ParentId: Id_21,
+    ParentId: Id_39,

4 occurrences of :

-    TraceId: Id_1,
-    SpanId: Id_62,
+    TraceId: Id_19,
+    SpanId: Id_80,
[...]
-    ParentId: Id_23,
+    ParentId: Id_41,

4 occurrences of :

-    TraceId: Id_1,
-    SpanId: Id_63,
+    TraceId: Id_19,
+    SpanId: Id_81,
[...]
-    ParentId: Id_25,
+    ParentId: Id_43,

4 occurrences of :

-    TraceId: Id_1,
-    SpanId: Id_64,
+    TraceId: Id_19,
+    SpanId: Id_82,
[...]
-    ParentId: Id_27,
+    ParentId: Id_45,

4 occurrences of :

-    TraceId: Id_28,
-    SpanId: Id_65,
+    TraceId: Id_46,
+    SpanId: Id_83,
[...]
-    ParentId: Id_30,
+    ParentId: Id_48,

4 occurrences of :

-    TraceId: Id_28,
-    SpanId: Id_66,
+    TraceId: Id_46,
+    SpanId: Id_84,
[...]
-    ParentId: Id_32,
+    ParentId: Id_50,

4 occurrences of :

-    TraceId: Id_28,
-    SpanId: Id_67,
+    TraceId: Id_46,
+    SpanId: Id_85,
[...]
-    ParentId: Id_34,
+    ParentId: Id_52,

4 occurrences of :

-    TraceId: Id_35,
-    SpanId: Id_68,
+    TraceId: Id_53,
+    SpanId: Id_86,
[...]
-    ParentId: Id_37,
+    ParentId: Id_55,

4 occurrences of :

-    TraceId: Id_35,
-    SpanId: Id_69,
+    TraceId: Id_53,
+    SpanId: Id_87,
[...]
-    ParentId: Id_39,
+    ParentId: Id_57,

4 occurrences of :

-    TraceId: Id_35,
-    SpanId: Id_70,
+    TraceId: Id_53,
+    SpanId: Id_88,
[...]
-    ParentId: Id_41,
+    ParentId: Id_59,

4 occurrences of :

-    TraceId: Id_35,
-    SpanId: Id_71,
+    TraceId: Id_53,
+    SpanId: Id_89,
[...]
-    ParentId: Id_43,
+    ParentId: Id_61,

4 occurrences of :

-    TraceId: Id_35,
-    SpanId: Id_72,
+    TraceId: Id_53,
+    SpanId: Id_90,
[...]
-    ParentId: Id_45,
+    ParentId: Id_63,

4 occurrences of :

-    TraceId: Id_35,
-    SpanId: Id_73,
+    TraceId: Id_53,
+    SpanId: Id_91,
[...]
-    ParentId: Id_47,
+    ParentId: Id_65,

4 occurrences of :

-    TraceId: Id_35,
-    SpanId: Id_74,
+    TraceId: Id_53,
+    SpanId: Id_92,
[...]
-    ParentId: Id_49,
+    ParentId: Id_67,

4 occurrences of :

-    TraceId: Id_35,
-    SpanId: Id_75,
+    TraceId: Id_53,
+    SpanId: Id_93,
[...]
-    ParentId: Id_51,
+    ParentId: Id_69,

1 occurrences of :

-    TraceId: Id_1,
-    SpanId: Id_76,
+    TraceId: Id_94,
+    SpanId: Id_95,
+    Name: sql-server.query,
+    Resource: INSERT INTO [Stored-Proc-System-Data-SqlClient-Test-GUID] (Id, Name) VALUES (1, 'Name1'), (2, 'Name2'), (3, 'Name3');,
+    Service: Samples.SqlServer-sql-server,
+    Type: sql,
+    Tags: {
+      component: SqlClient,
+      db.type: sql-server,
+      env: integration_tests,
+      language: dotnet,
+      out.host: sqlserver,
+      runtime-id: Guid_1,
+      span.kind: client,
+      _dd.base_service: Samples.SqlServer,
+      _dd.dbm_trace_injected: true
+    },
+    Metrics: {
+      dd.instrumentation.time_ms: 123.456,
+      process_id: 0,
+      _dd.top_level: 1.0,
+      _dd.tracer_kr: 1.0,
+      _sampling_priority_v1: 1.0
+    }
+  },
+  {
+    TraceId: Id_19,
+    SpanId: Id_96,
[...]
-    ParentId: Id_3,
+    ParentId: Id_21,

4 occurrences of :

-    TraceId: Id_1,
-    SpanId: Id_77,
+    TraceId: Id_19,
+    SpanId: Id_97,
[...]
-    ParentId: Id_5,
+    ParentId: Id_23,

4 occurrences of :

-    TraceId: Id_1,
-    SpanId: Id_78,
+    TraceId: Id_19,
+    SpanId: Id_98,
[...]
-    ParentId: Id_7,
+    ParentId: Id_25,

4 occurrences of :

-    TraceId: Id_1,
-    SpanId: Id_79,
+    TraceId: Id_19,
+    SpanId: Id_99,
[...]
-    ParentId: Id_9,
+    ParentId: Id_27,

4 occurrences of :

-    TraceId: Id_1,
-    SpanId: Id_80,
+    TraceId: Id_19,
+    SpanId: Id_100,
[...]
-    ParentId: Id_11,
+    ParentId: Id_29,

4 occurrences of :

-    TraceId: Id_1,
-    SpanId: Id_81,
+    TraceId: Id_19,
+    SpanId: Id_101,
[...]
-    ParentId: Id_13,
+    ParentId: Id_31,

4 occurrences of :

-    TraceId: Id_1,
-    SpanId: Id_82,
+    TraceId: Id_19,
+    SpanId: Id_102,
[...]
-    ParentId: Id_15,
+    ParentId: Id_33,

4 occurrences of :

-    TraceId: Id_1,
-    SpanId: Id_83,
+    TraceId: Id_19,
+    SpanId: Id_103,
[...]
-    ParentId: Id_17,
+    ParentId: Id_35,

4 occurrences of :

-    TraceId: Id_1,
-    SpanId: Id_84,
+    TraceId: Id_19,
+    SpanId: Id_104,
[...]
-    ParentId: Id_19,
+    ParentId: Id_37,

4 occurrences of :

-    TraceId: Id_1,
-    SpanId: Id_85,
+    TraceId: Id_19,
+    SpanId: Id_105,
[...]
-    ParentId: Id_21,
+    ParentId: Id_39,

4 occurrences of :

-    TraceId: Id_1,
-    SpanId: Id_86,
+    TraceId: Id_19,
+    SpanId: Id_106,
[...]
-    ParentId: Id_23,
+    ParentId: Id_41,

4 occurrences of :

-    TraceId: Id_1,
-    SpanId: Id_87,
+    TraceId: Id_19,
+    SpanId: Id_107,
[...]
-    ParentId: Id_25,
+    ParentId: Id_43,

4 occurrences of :

-    TraceId: Id_1,
-    SpanId: Id_88,
+    TraceId: Id_19,
+    SpanId: Id_108,
[...]
-    ParentId: Id_27,
+    ParentId: Id_45,

4 occurrences of :

-    TraceId: Id_28,
-    SpanId: Id_89,
+    TraceId: Id_46,
+    SpanId: Id_109,
[...]
-    ParentId: Id_30,
+    ParentId: Id_48,

4 occurrences of :

-    TraceId: Id_28,
-    SpanId: Id_90,
+    TraceId: Id_46,
+    SpanId: Id_110,
[...]
-    ParentId: Id_32,
+    ParentId: Id_50,

4 occurrences of :

-    TraceId: Id_28,
-    SpanId: Id_91,
+    TraceId: Id_46,
+    SpanId: Id_111,
[...]
-    ParentId: Id_34,
+    ParentId: Id_52,

4 occurrences of :

-    TraceId: Id_35,
-    SpanId: Id_92,
+    TraceId: Id_53,
+    SpanId: Id_112,
[...]
-    ParentId: Id_37,
+    ParentId: Id_55,

4 occurrences of :

-    TraceId: Id_35,
-    SpanId: Id_93,
+    TraceId: Id_53,
+    SpanId: Id_113,
[...]
-    ParentId: Id_39,
+    ParentId: Id_57,

4 occurrences of :

-    TraceId: Id_35,
-    SpanId: Id_94,
+    TraceId: Id_53,
+    SpanId: Id_114,
[...]
-    ParentId: Id_41,
+    ParentId: Id_59,

4 occurrences of :

-    TraceId: Id_35,
-    SpanId: Id_95,
+    TraceId: Id_53,
+    SpanId: Id_115,
[...]
-    ParentId: Id_43,
+    ParentId: Id_61,

4 occurrences of :

-    TraceId: Id_35,
-    SpanId: Id_96,
+    TraceId: Id_53,
+    SpanId: Id_116,
[...]
-    ParentId: Id_45,
+    ParentId: Id_63,

4 occurrences of :

-    TraceId: Id_35,
-    SpanId: Id_97,
+    TraceId: Id_53,
+    SpanId: Id_117,
[...]
-    ParentId: Id_47,
+    ParentId: Id_65,

4 occurrences of :

-    TraceId: Id_35,
-    SpanId: Id_98,
+    TraceId: Id_53,
+    SpanId: Id_118,
[...]
-    ParentId: Id_49,
+    ParentId: Id_67,

4 occurrences of :

-    TraceId: Id_35,
-    SpanId: Id_99,
+    TraceId: Id_53,
+    SpanId: Id_119,
[...]
-    ParentId: Id_51,
+    ParentId: Id_69,

4 occurrences of :

-    TraceId: Id_1,
-    SpanId: Id_100,
+    TraceId: Id_19,
+    SpanId: Id_120,
[...]
-    ParentId: Id_3,
+    ParentId: Id_21,

4 occurrences of :

-    TraceId: Id_1,
-    SpanId: Id_101,
+    TraceId: Id_19,
+    SpanId: Id_121,
[...]
-    ParentId: Id_3,
+    ParentId: Id_21,

4 occurrences of :

-    TraceId: Id_1,
-    SpanId: Id_102,
+    TraceId: Id_19,
+    SpanId: Id_122,
[...]
-    ParentId: Id_5,
+    ParentId: Id_23,

4 occurrences of :

-    TraceId: Id_1,
-    SpanId: Id_103,
+    TraceId: Id_19,
+    SpanId: Id_123,
[...]
-    ParentId: Id_5,
+    ParentId: Id_23,

4 occurrences of :

-    TraceId: Id_1,
-    SpanId: Id_104,
+    TraceId: Id_19,
+    SpanId: Id_124,
[...]
-    ParentId: Id_7,
+    ParentId: Id_25,

4 occurrences of :

-    TraceId: Id_1,
-    SpanId: Id_105,
+    TraceId: Id_19,
+    SpanId: Id_125,
[...]
-    ParentId: Id_7,
+    ParentId: Id_25,

4 occurrences of :

-    TraceId: Id_1,
-    SpanId: Id_106,
+    TraceId: Id_19,
+    SpanId: Id_126,
[...]
-    ParentId: Id_9,
+    ParentId: Id_27,

4 occurrences of :

-    TraceId: Id_1,
-    SpanId: Id_107,
+    TraceId: Id_19,
+    SpanId: Id_127,
[...]
-    ParentId: Id_9,
+    ParentId: Id_27,

4 occurrences of :

-    TraceId: Id_1,
-    SpanId: Id_108,
+    TraceId: Id_19,
+    SpanId: Id_128,
[...]
-    ParentId: Id_11,
+    ParentId: Id_29,

4 occurrences of :

-    TraceId: Id_1,
-    SpanId: Id_109,
+    TraceId: Id_19,
+    SpanId: Id_129,
[...]
-    ParentId: Id_11,
+    ParentId: Id_29,

4 occurrences of :

-    TraceId: Id_1,
-    SpanId: Id_110,
+    TraceId: Id_19,
+    SpanId: Id_130,
[...]
-    ParentId: Id_13,
+    ParentId: Id_31,

4 occurrences of :

-    TraceId: Id_1,
-    SpanId: Id_111,
+    TraceId: Id_19,
+    SpanId: Id_131,
[...]
-    ParentId: Id_13,
+    ParentId: Id_31,

4 occurrences of :

-    TraceId: Id_1,
-    SpanId: Id_112,
+    TraceId: Id_19,
+    SpanId: Id_132,
[...]
-    ParentId: Id_15,
+    ParentId: Id_33,

4 occurrences of :

-    TraceId: Id_1,
-    SpanId: Id_113,
+    TraceId: Id_19,
+    SpanId: Id_133,
[...]
-    ParentId: Id_15,
+    ParentId: Id_33,

4 occurrences of :

-    TraceId: Id_1,
-    SpanId: Id_114,
+    TraceId: Id_19,
+    SpanId: Id_134,
[...]
-    ParentId: Id_17,
+    ParentId: Id_35,

4 occurrences of :

-    TraceId: Id_1,
-    SpanId: Id_115,
+    TraceId: Id_19,
+    SpanId: Id_135,
[...]
-    ParentId: Id_17,
+    ParentId: Id_35,

4 occurrences of :

-    TraceId: Id_1,
-    SpanId: Id_116,
+    TraceId: Id_19,
+    SpanId: Id_136,
[...]
-    ParentId: Id_19,
+    ParentId: Id_37,

4 occurrences of :

-    TraceId: Id_1,
-    SpanId: Id_117,
+    TraceId: Id_19,
+    SpanId: Id_137,
[...]
-    ParentId: Id_19,
+    ParentId: Id_37,

4 occurrences of :

-    TraceId: Id_1,
-    SpanId: Id_118,
+    TraceId: Id_19,
+    SpanId: Id_138,
[...]
-    ParentId: Id_21,
+    ParentId: Id_39,

4 occurrences of :

-    TraceId: Id_1,
-    SpanId: Id_119,
+    TraceId: Id_19,
+    SpanId: Id_139,
[...]
-    ParentId: Id_21,
+    ParentId: Id_39,

4 occurrences of :

-    TraceId: Id_1,
-    SpanId: Id_120,
+    TraceId: Id_19,
+    SpanId: Id_140,
[...]
-    ParentId: Id_23,
+    ParentId: Id_41,

4 occurrences of :

-    TraceId: Id_1,
-    SpanId: Id_121,
+    TraceId: Id_19,
+    SpanId: Id_141,
[...]
-    ParentId: Id_23,
+    ParentId: Id_41,

4 occurrences of :

-    TraceId: Id_1,
-    SpanId: Id_122,
+    TraceId: Id_19,
+    SpanId: Id_142,
[...]
-    ParentId: Id_25,
+    ParentId: Id_43,

4 occurrences of :

-    TraceId: Id_1,
-    SpanId: Id_123,
+    TraceId: Id_19,
+    SpanId: Id_143,
[...]
-    ParentId: Id_25,
+    ParentId: Id_43,

4 occurrences of :

-    TraceId: Id_1,
-    SpanId: Id_124,
+    TraceId: Id_19,
+    SpanId: Id_144,
[...]
-    ParentId: Id_27,
+    ParentId: Id_45,

4 occurrences of :

-    TraceId: Id_1,
-    SpanId: Id_125,
+    TraceId: Id_19,
+    SpanId: Id_145,
[...]
-    ParentId: Id_27,
+    ParentId: Id_45,

4 occurrences of :

-    TraceId: Id_28,
-    SpanId: Id_126,
+    TraceId: Id_46,
+    SpanId: Id_146,
[...]
-    ParentId: Id_30,
+    ParentId: Id_48,

4 occurrences of :

-    TraceId: Id_28,
-    SpanId: Id_127,
+    TraceId: Id_46,
+    SpanId: Id_147,
[...]
-    ParentId: Id_30,
+    ParentId: Id_48,

4 occurrences of :

-    TraceId: Id_28,
-    SpanId: Id_128,
+    TraceId: Id_46,
+    SpanId: Id_148,
[...]
-    ParentId: Id_32,
+    ParentId: Id_50,

4 occurrences of :

-    TraceId: Id_28,
-    SpanId: Id_129,
+    TraceId: Id_46,
+    SpanId: Id_149,
[...]
-    ParentId: Id_32,
+    ParentId: Id_50,

4 occurrences of :

-    TraceId: Id_28,
-    SpanId: Id_130,
+    TraceId: Id_46,
+    SpanId: Id_150,
[...]
-    ParentId: Id_34,
+    ParentId: Id_52,

4 occurrences of :

-    TraceId: Id_28,
-    SpanId: Id_131,
+    TraceId: Id_46,
+    SpanId: Id_151,
[...]
-    ParentId: Id_34,
+    ParentId: Id_52,

4 occurrences of :

-    TraceId: Id_35,
-    SpanId: Id_132,
+    TraceId: Id_53,
+    SpanId: Id_152,
[...]
-    ParentId: Id_37,
+    ParentId: Id_55,

4 occurrences of :

-    TraceId: Id_35,
-    SpanId: Id_133,
+    TraceId: Id_53,
+    SpanId: Id_153,
[...]
-    ParentId: Id_37,
+    ParentId: Id_55,

4 occurrences of :

-    TraceId: Id_35,
-    SpanId: Id_134,
+    TraceId: Id_53,
+    SpanId: Id_154,
[...]
-    ParentId: Id_39,
+    ParentId: Id_57,

4 occurrences of :

-    TraceId: Id_35,
-    SpanId: Id_135,
+    TraceId: Id_53,
+    SpanId: Id_155,
[...]
-    ParentId: Id_39,
+    ParentId: Id_57,

4 occurrences of :

-    TraceId: Id_35,
-    SpanId: Id_136,
+    TraceId: Id_53,
+    SpanId: Id_156,
[...]
-    ParentId: Id_41,
+    ParentId: Id_59,

4 occurrences of :

-    TraceId: Id_35,
-    SpanId: Id_137,
+    TraceId: Id_53,
+    SpanId: Id_157,
[...]
-    ParentId: Id_41,
+    ParentId: Id_59,

4 occurrences of :

-    TraceId: Id_35,
-    SpanId: Id_138,
+    TraceId: Id_53,
+    SpanId: Id_158,
[...]
-    ParentId: Id_43,
+    ParentId: Id_61,

4 occurrences of :

-    TraceId: Id_35,
-    SpanId: Id_139,
+    TraceId: Id_53,
+    SpanId: Id_159,
[...]
-    ParentId: Id_43,
+    ParentId: Id_61,

4 occurrences of :

-    TraceId: Id_35,
-    SpanId: Id_140,
+    TraceId: Id_53,
+    SpanId: Id_160,
[...]
-    ParentId: Id_45,
+    ParentId: Id_63,

4 occurrences of :

-    TraceId: Id_35,
-    SpanId: Id_141,
+    TraceId: Id_53,
+    SpanId: Id_161,
[...]
-    ParentId: Id_45,
+    ParentId: Id_63,

4 occurrences of :

-    TraceId: Id_35,
-    SpanId: Id_142,
+    TraceId: Id_53,
+    SpanId: Id_162,
[...]
-    ParentId: Id_47,
+    ParentId: Id_65,

4 occurrences of :

-    TraceId: Id_35,
-    SpanId: Id_143,
+    TraceId: Id_53,
+    SpanId: Id_163,
[...]
-    ParentId: Id_47,
+    ParentId: Id_65,

4 occurrences of :

-    TraceId: Id_35,
-    SpanId: Id_144,
+    TraceId: Id_53,
+    SpanId: Id_164,
[...]
-    ParentId: Id_49,
+    ParentId: Id_67,

4 occurrences of :

-    TraceId: Id_35,
-    SpanId: Id_145,
+    TraceId: Id_53,
+    SpanId: Id_165,
[...]
-    ParentId: Id_49,
+    ParentId: Id_67,

4 occurrences of :

-    TraceId: Id_35,
-    SpanId: Id_146,
+    TraceId: Id_53,
+    SpanId: Id_166,
[...]
-    ParentId: Id_51,
+    ParentId: Id_69,

4 occurrences of :

-    TraceId: Id_35,
-    SpanId: Id_147,
+    TraceId: Id_53,
+    SpanId: Id_167,
[...]
-    ParentId: Id_51,
+    ParentId: Id_69,

4 occurrences of :

-    TraceId: Id_1,
-    SpanId: Id_148,
+    TraceId: Id_19,
+    SpanId: Id_168,
[...]
-    ParentId: Id_3,
+    ParentId: Id_21,

4 occurrences of :

-    TraceId: Id_1,
-    SpanId: Id_149,
+    TraceId: Id_19,
+    SpanId: Id_169,
[...]
-    ParentId: Id_5,
+    ParentId: Id_23,

4 occurrences of :

-    TraceId: Id_1,
-    SpanId: Id_150,
+    TraceId: Id_19,
+    SpanId: Id_170,
[...]
-    ParentId: Id_7,
+    ParentId: Id_25,

4 occurrences of :

-    TraceId: Id_1,
-    SpanId: Id_151,
+    TraceId: Id_19,
+    SpanId: Id_171,
[...]
-    ParentId: Id_9,
+    ParentId: Id_27,

4 occurrences of :

-    TraceId: Id_1,
-    SpanId: Id_152,
+    TraceId: Id_19,
+    SpanId: Id_172,
[...]
-    ParentId: Id_11,
+    ParentId: Id_29,

4 occurrences of :

-    TraceId: Id_1,
-    SpanId: Id_153,
+    TraceId: Id_19,
+    SpanId: Id_173,
[...]
-    ParentId: Id_13,
+    ParentId: Id_31,

4 occurrences of :

-    TraceId: Id_1,
-    SpanId: Id_154,
+    TraceId: Id_19,
+    SpanId: Id_174,
[...]
-    ParentId: Id_15,
+    ParentId: Id_33,

4 occurrences of :

-    TraceId: Id_1,
-    SpanId: Id_155,
+    TraceId: Id_19,
+    SpanId: Id_175,
[...]
-    ParentId: Id_17,
+    ParentId: Id_35,

4 occurrences of :

-    TraceId: Id_1,
-    SpanId: Id_156,
+    TraceId: Id_19,
+    SpanId: Id_176,
[...]
-    ParentId: Id_19,
+    ParentId: Id_37,

4 occurrences of :

-    TraceId: Id_1,
-    SpanId: Id_157,
+    TraceId: Id_19,
+    SpanId: Id_177,
[...]
-    ParentId: Id_21,
+    ParentId: Id_39,

4 occurrences of :

-    TraceId: Id_1,
-    SpanId: Id_158,
+    TraceId: Id_19,
+    SpanId: Id_178,
[...]
-    ParentId: Id_23,
+    ParentId: Id_41,

4 occurrences of :

-    TraceId: Id_1,
-    SpanId: Id_159,
+    TraceId: Id_19,
+    SpanId: Id_179,
[...]
-    ParentId: Id_25,
+    ParentId: Id_43,

4 occurrences of :

-    TraceId: Id_1,
-    SpanId: Id_160,
+    TraceId: Id_19,
+    SpanId: Id_180,
[...]
-    ParentId: Id_27,
+    ParentId: Id_45,

4 occurrences of :

-    TraceId: Id_28,
-    SpanId: Id_161,
+    TraceId: Id_46,
+    SpanId: Id_181,
[...]
-    ParentId: Id_30,
+    ParentId: Id_48,

4 occurrences of :

-    TraceId: Id_28,
-    SpanId: Id_162,
+    TraceId: Id_46,
+    SpanId: Id_182,
[...]
-    ParentId: Id_32,
+    ParentId: Id_50,

4 occurrences of :

-    TraceId: Id_28,
-    SpanId: Id_163,
+    TraceId: Id_46,
+    SpanId: Id_183,
[...]
-    ParentId: Id_34,
+    ParentId: Id_52,

4 occurrences of :

-    TraceId: Id_35,
-    SpanId: Id_164,
+    TraceId: Id_53,
+    SpanId: Id_184,
[...]
-    ParentId: Id_37,
+    ParentId: Id_55,

4 occurrences of :

-    TraceId: Id_35,
-    SpanId: Id_165,
+    TraceId: Id_53,
+    SpanId: Id_185,
[...]
-    ParentId: Id_39,
+    ParentId: Id_57,

4 occurrences of :

-    TraceId: Id_35,
-    SpanId: Id_166,
+    TraceId: Id_53,
+    SpanId: Id_186,
[...]
-    ParentId: Id_41,
+    ParentId: Id_59,

4 occurrences of :

-    TraceId: Id_35,
-    SpanId: Id_167,
+    TraceId: Id_53,
+    SpanId: Id_187,
[...]
-    ParentId: Id_43,
+    ParentId: Id_61,

4 occurrences of :

-    TraceId: Id_35,
-    SpanId: Id_168,
+    TraceId: Id_53,
+    SpanId: Id_188,
[...]
-    ParentId: Id_45,
+    ParentId: Id_63,

4 occurrences of :

-    TraceId: Id_35,
-    SpanId: Id_169,
+    TraceId: Id_53,
+    SpanId: Id_189,
[...]
-    ParentId: Id_47,
+    ParentId: Id_65,

4 occurrences of :

-    TraceId: Id_35,
-    SpanId: Id_170,
+    TraceId: Id_53,
+    SpanId: Id_190,
[...]
-    ParentId: Id_49,
+    ParentId: Id_67,

4 occurrences of :

-    TraceId: Id_35,
-    SpanId: Id_171,
+    TraceId: Id_53,
+    SpanId: Id_191,
[...]
-    ParentId: Id_51,
+    ParentId: Id_69,

4 occurrences of :

-    TraceId: Id_1,
-    SpanId: Id_172,
+    TraceId: Id_19,
+    SpanId: Id_192,
[...]
-    ParentId: Id_3,
+    ParentId: Id_21,

4 occurrences of :

-    TraceId: Id_1,
-    SpanId: Id_173,
+    TraceId: Id_19,
+    SpanId: Id_193,
[...]
-    ParentId: Id_5,
+    ParentId: Id_23,

4 occurrences of :

-    TraceId: Id_1,
-    SpanId: Id_174,
+    TraceId: Id_19,
+    SpanId: Id_194,
[...]
-    ParentId: Id_7,
+    ParentId: Id_25,

4 occurrences of :

-    TraceId: Id_1,
-    SpanId: Id_175,
+    TraceId: Id_19,
+    SpanId: Id_195,
[...]
-    ParentId: Id_9,
+    ParentId: Id_27,

4 occurrences of :

-    TraceId: Id_1,
-    SpanId: Id_176,
+    TraceId: Id_19,
+    SpanId: Id_196,
[...]
-    ParentId: Id_11,
+    ParentId: Id_29,

4 occurrences of :

-    TraceId: Id_1,
-    SpanId: Id_177,
+    TraceId: Id_19,
+    SpanId: Id_197,
[...]
-    ParentId: Id_13,
+    ParentId: Id_31,

4 occurrences of :

-    TraceId: Id_1,
-    SpanId: Id_178,
+    TraceId: Id_19,
+    SpanId: Id_198,
[...]
-    ParentId: Id_15,
+    ParentId: Id_33,

4 occurrences of :

-    TraceId: Id_1,
-    SpanId: Id_179,
+    TraceId: Id_19,
+    SpanId: Id_199,
[...]
-    ParentId: Id_17,
+    ParentId: Id_35,

4 occurrences of :

-    TraceId: Id_1,
-    SpanId: Id_180,
+    TraceId: Id_19,
+    SpanId: Id_200,
[...]
-    ParentId: Id_19,
+    ParentId: Id_37,

4 occurrences of :

-    TraceId: Id_1,
-    SpanId: Id_181,
+    TraceId: Id_19,
+    SpanId: Id_201,
[...]
-    ParentId: Id_21,
+    ParentId: Id_39,

4 occurrences of :

-    TraceId: Id_1,
-    SpanId: Id_182,
+    TraceId: Id_19,
+    SpanId: Id_202,
[...]
-    ParentId: Id_23,
+    ParentId: Id_41,

4 occurrences of :

-    TraceId: Id_1,
-    SpanId: Id_183,
+    TraceId: Id_19,
+    SpanId: Id_203,
[...]
-    ParentId: Id_25,
+    ParentId: Id_43,

4 occurrences of :

-    TraceId: Id_1,
-    SpanId: Id_184,
+    TraceId: Id_19,
+    SpanId: Id_204,
[...]
-    ParentId: Id_27,
+    ParentId: Id_45,

4 occurrences of :

-    TraceId: Id_28,
-    SpanId: Id_185,
+    TraceId: Id_46,
+    SpanId: Id_205,
[...]
-    ParentId: Id_30,
+    ParentId: Id_48,

4 occurrences of :

-    TraceId: Id_28,
-    SpanId: Id_186,
+    TraceId: Id_46,
+    SpanId: Id_206,
[...]
-    ParentId: Id_32,
+    ParentId: Id_50,

4 occurrences of :

-    TraceId: Id_28,
-    SpanId: Id_187,
+    TraceId: Id_46,
+    SpanId: Id_207,
[...]
-    ParentId: Id_34,
+    ParentId: Id_52,

4 occurrences of :

-    TraceId: Id_35,
-    SpanId: Id_188,
+    TraceId: Id_53,
+    SpanId: Id_208,
[...]
-    ParentId: Id_37,
+    ParentId: Id_55,

4 occurrences of :

-    TraceId: Id_35,
-    SpanId: Id_189,
+    TraceId: Id_53,
+    SpanId: Id_209,
[...]
-    ParentId: Id_39,
+    ParentId: Id_57,

4 occurrences of :

-    TraceId: Id_35,
-    SpanId: Id_190,
+    TraceId: Id_53,
+    SpanId: Id_210,
[...]
-    ParentId: Id_41,
+    ParentId: Id_59,

4 occurrences of :

-    TraceId: Id_35,
-    SpanId: Id_191,
+    TraceId: Id_53,
+    SpanId: Id_211,
[...]
-    ParentId: Id_43,
+    ParentId: Id_61,

4 occurrences of :

-    TraceId: Id_35,
-    SpanId: Id_192,
+    TraceId: Id_53,
+    SpanId: Id_212,
[...]
-    ParentId: Id_45,
+    ParentId: Id_63,

4 occurrences of :

-    TraceId: Id_35,
-    SpanId: Id_193,
+    TraceId: Id_53,
+    SpanId: Id_213,
[...]
-    ParentId: Id_47,
+    ParentId: Id_65,

4 occurrences of :

-    TraceId: Id_35,
-    SpanId: Id_194,
+    TraceId: Id_53,
+    SpanId: Id_214,
[...]
-    ParentId: Id_49,
+    ParentId: Id_67,

4 occurrences of :

-    TraceId: Id_35,
-    SpanId: Id_195,
+    TraceId: Id_53,
+    SpanId: Id_215,
[...]
-    ParentId: Id_51,
+    ParentId: Id_69,

1 occurrences of :

+      runtime-id: Guid_1,
[...]
+      process_id: 0,
+      _dd.top_level: 1.0,
+      _dd.tracer_kr: 1.0,
+      _sampling_priority_v1: 1.0
[...]
-    TraceId: Id_1,
+    TraceId: Id_3,
[...]
-    Resource: DELETE FROM [System-Data-SqlClient-Test-GUID] WHERE Id=@Id;,
+    Resource:
[...]
+    @Id int
[...]
+    SELECT * FROM [Stored-Proc-System-Data-SqlClient-Test-GUID] WHERE Id = @Id;
[...]
-    ParentId: Id_5,

1 occurrences of :

+      runtime-id: Guid_1,
[...]
+      process_id: 0,
+      _dd.top_level: 1.0,
+      _dd.tracer_kr: 1.0,
+      _sampling_priority_v1: 1.0
[...]
-    TraceId: Id_1,
+    TraceId: Id_5,
[...]
-    Resource: DELETE FROM [System-Data-SqlClient-Test-GUID] WHERE Id=@Id;,
+    Resource:
[...]
+    @Id int,
+    @NewName varchar(100),
+    @OldName varchar(100) OUTPUT
[...]
+    -- Store the old name before updating
+    SELECT @OldName = Name FROM [Stored-Proc-System-Data-SqlClient-Test-GUID] WHERE Id = @Id;
+    -- Update the row
+    UPDATE [Stored-Proc-System-Data-SqlClient-Test-GUID] SET Name = @NewName WHERE Id = @Id;
+    -- Return number of rows affected
+    RETURN @@ROWCOUNT;
[...]
-    ParentId: Id_7,

1 occurrences of :

+      runtime-id: Guid_1,
[...]
+      process_id: 0,
+      _dd.top_level: 1.0,
+      _dd.tracer_kr: 1.0,
+      _sampling_priority_v1: 1.0
[...]
-    TraceId: Id_1,
+    TraceId: Id_7,
[...]
-    Resource: DELETE FROM [System-Data-SqlClient-Test-GUID] WHERE Id=@Id;,
+    Resource:
[...]
-    ParentId: Id_9,

1 occurrences of :

+      runtime-id: Guid_1,
[...]
+      process_id: 0,
+      _dd.top_level: 1.0,
+      _dd.tracer_kr: 1.0,
+      _sampling_priority_v1: 1.0
[...]
-    TraceId: Id_1,
+    TraceId: Id_9,
[...]
-    Resource: DELETE FROM [System-Data-SqlClient-Test-GUID] WHERE Id=@Id;,
+    Resource: CREATE TABLE [Stored-Proc-System-Data-SqlClient-Test-GUID] (Id int PRIMARY KEY, Name varchar(100));,
[...]
-    ParentId: Id_11,

1 occurrences of :

+      runtime-id: Guid_1,
[...]
+      process_id: 0,
+      _dd.top_level: 1.0,
+      _dd.tracer_kr: 1.0,
+      _sampling_priority_v1: 1.0
[...]
-    TraceId: Id_1,
+    TraceId: Id_11,
[...]
-    Resource: DELETE FROM [System-Data-SqlClient-Test-GUID] WHERE Id=@Id;,
+    Resource: dbo.sp_BatchUpdate,
[...]
-    ParentId: Id_13,

1 occurrences of :

+      runtime-id: Guid_1,
[...]
+      process_id: 0,
+      _dd.top_level: 1.0,
+      _dd.tracer_kr: 1.0,
+      _sampling_priority_v1: 1.0
[...]
-    TraceId: Id_1,
+    TraceId: Id_13,
[...]
-    Resource: DELETE FROM [System-Data-SqlClient-Test-GUID] WHERE Id=@Id;,
+    Resource: dbo.sp_BatchUpdate,
[...]
-    ParentId: Id_15,

1 occurrences of :

+      runtime-id: Guid_1,
[...]
+      process_id: 0,
+      _dd.top_level: 1.0,
+      _dd.tracer_kr: 1.0,
+      _sampling_priority_v1: 1.0
[...]
-    TraceId: Id_1,
+    TraceId: Id_15,
[...]
-    Resource: DELETE FROM [System-Data-SqlClient-Test-GUID] WHERE Id=@Id;,
+    Resource: dbo.sp_GetTableRow,
[...]
-    ParentId: Id_17,

1 occurrences of :

+      runtime-id: Guid_1,
[...]
+      process_id: 0,
+      _dd.top_level: 1.0,
+      _dd.tracer_kr: 1.0,
+      _sampling_priority_v1: 1.0
[...]
-    TraceId: Id_1,
+    TraceId: Id_17,
[...]
-    Resource: DELETE FROM [System-Data-SqlClient-Test-GUID] WHERE Id=@Id;,
+    Resource: dbo.sp_UpdateRowWithOutput,
[...]
-    ParentId: Id_19,

1 occurrences of :

+      runtime-id: Guid_1,
[...]
+      process_id: 0,
+      _dd.top_level: 1.0,
+      _dd.tracer_kr: 1.0,
+      _sampling_priority_v1: 1.0
[...]
-    TraceId: Id_1,
+    TraceId: Id_19,

1 occurrences of :

-    TraceId: Id_35,
+    TraceId: Id_19,
+    SpanId: Id_34,
+    Name: sql-server.query,
+    Resource: DELETE FROM [System-Data-SqlClient-Test-GUID] WHERE Id=@Id;,
+    Service: Samples.SqlServer,
+    Type: sql,
+    ParentId: Id_35,
+    Tags: {
+      component: SqlClient,
+      db.type: sql-server,
+      env: integration_tests,
+      language: dotnet,
+      out.host: sqlserver,
+      peer.service: sqlserver,
+      span.kind: client,
+      version: 1.0.0,
+      _dd.dbm_trace_injected: true,
+      _dd.peer.service.source: out.host
+    },
+    Metrics: {
+      dd.instrumentation.time_ms: 123.456
+    }
+  },
+  {
+    TraceId: Id_19,

1 occurrences of :

-    TraceId: Id_1,
-    SpanId: Id_52,
+    TraceId: Id_53,
+    SpanId: Id_54,
+    Name: sql-server.query,
+    Resource: DELETE FROM [System-Data-SqlClient-Test-GUID] WHERE Id=@Id;,
+    Service: Samples.SqlServer,
+    Type: sql,
+    ParentId: Id_55,
+    Tags: {
+      component: SqlClient,
+      db.type: sql-server,
+      env: integration_tests,
+      language: dotnet,
+      out.host: sqlserver,
+      peer.service: sqlserver,
+      span.kind: client,
+      version: 1.0.0,
+      _dd.dbm_trace_injected: true,
+      _dd.peer.service.source: out.host
+    },
+    Metrics: {
+      dd.instrumentation.time_ms: 123.456
+    }
+  },
+  {
+    TraceId: Id_53,
+    SpanId: Id_56,
+    Name: sql-server.query,
+    Resource: DELETE FROM [System-Data-SqlClient-Test-GUID] WHERE Id=@Id;,
+    Service: Samples.SqlServer,
+    Type: sql,
+    ParentId: Id_57,
+    Tags: {
+      component: SqlClient,
+      db.type: sql-server,
+      env: integration_tests,
+      language: dotnet,
+      out.host: sqlserver,
+      peer.service: sqlserver,
+      span.kind: client,
+      version: 1.0.0,
+      _dd.dbm_trace_injected: true,
+      _dd.peer.service.source: out.host
+    },
+    Metrics: {
+      dd.instrumentation.time_ms: 123.456
+    }
+  },
+  {
+    TraceId: Id_53,
+    SpanId: Id_58,
+    Name: sql-server.query,
+    Resource: DELETE FROM [System-Data-SqlClient-Test-GUID] WHERE Id=@Id;,
+    Service: Samples.SqlServer,
+    Type: sql,
+    ParentId: Id_59,
+    Tags: {
+      component: SqlClient,
+      db.type: sql-server,
+      env: integration_tests,
+      language: dotnet,
+      out.host: sqlserver,
+      peer.service: sqlserver,
+      span.kind: client,
+      version: 1.0.0,
+      _dd.dbm_trace_injected: true,
+      _dd.peer.service.source: out.host
+    },
+    Metrics: {
+      dd.instrumentation.time_ms: 123.456
+    }
+  },
+  {
+    TraceId: Id_53,
+    SpanId: Id_60,
+    Name: sql-server.query,
+    Resource: DELETE FROM [System-Data-SqlClient-Test-GUID] WHERE Id=@Id;,
+    Service: Samples.SqlServer,
+    Type: sql,
+    ParentId: Id_61,
+    Tags: {
+      component: SqlClient,
+      db.type: sql-server,
+      env: integration_tests,
+      language: dotnet,
+      out.host: sqlserver,
+      peer.service: sqlserver,
+      span.kind: client,
+      version: 1.0.0,
+      _dd.dbm_trace_injected: true,
+      _dd.peer.service.source: out.host
+    },
+    Metrics: {
+      dd.instrumentation.time_ms: 123.456
+    }
+  },
+  {
+    TraceId: Id_53,
+    SpanId: Id_62,
+    Name: sql-server.query,
+    Resource: DELETE FROM [System-Data-SqlClient-Test-GUID] WHERE Id=@Id;,
+    Service: Samples.SqlServer,
+    Type: sql,
+    ParentId: Id_63,
+    Tags: {
+      component: SqlClient,
+      db.type: sql-server,
+      env: integration_tests,
+      language: dotnet,
+      out.host: sqlserver,
+      peer.service: sqlserver,
+      span.kind: client,
+      version: 1.0.0,
+      _dd.dbm_trace_injected: true,
+      _dd.peer.service.source: out.host
+    },
+    Metrics: {
+      dd.instrumentation.time_ms: 123.456
+    }
+  },
+  {
+    TraceId: Id_53,
+    SpanId: Id_64,
+    Name: sql-server.query,
+    Resource: DELETE FROM [System-Data-SqlClient-Test-GUID] WHERE Id=@Id;,
+    Service: Samples.SqlServer,
+    Type: sql,
+    ParentId: Id_65,
+    Tags: {
+      component: SqlClient,
+      db.type: sql-server,
+      env: integration_tests,
+      language: dotnet,
+      out.host: sqlserver,
+      peer.service: sqlserver,
+      span.kind: client,
+      version: 1.0.0,
+      _dd.dbm_trace_injected: true,
+      _dd.peer.service.source: out.host
+    },
+    Metrics: {
+      dd.instrumentation.time_ms: 123.456
+    }
+  },
+  {
+    TraceId: Id_53,
+    SpanId: Id_66,
+    Name: sql-server.query,
+    Resource: DELETE FROM [System-Data-SqlClient-Test-GUID] WHERE Id=@Id;,
+    Service: Samples.SqlServer,
+    Type: sql,
+    ParentId: Id_67,
+    Tags: {
+      component: SqlClient,
+      db.type: sql-server,
+      env: integration_tests,
+      language: dotnet,
+      out.host: sqlserver,
+      peer.service: sqlserver,
+      span.kind: client,
+      version: 1.0.0,
+      _dd.dbm_trace_injected: true,
+      _dd.peer.service.source: out.host
+    },
+    Metrics: {
+      dd.instrumentation.time_ms: 123.456
+    }
+  },
+  {
+    TraceId: Id_53,
+    SpanId: Id_68,
+    Name: sql-server.query,
+    Resource: DELETE FROM [System-Data-SqlClient-Test-GUID] WHERE Id=@Id;,
+    Service: Samples.SqlServer,
+    Type: sql,
+    ParentId: Id_69,
+    Tags: {
+      component: SqlClient,
+      db.type: sql-server,
+      env: integration_tests,
+      language: dotnet,
+      out.host: sqlserver,
+      peer.service: sqlserver,
+      span.kind: client,
+      version: 1.0.0,
+      _dd.dbm_trace_injected: true,
+      _dd.peer.service.source: out.host
+    },
+    Metrics: {
+      dd.instrumentation.time_ms: 123.456
+    }
+  },
+  {
+    TraceId: Id_19,
+    SpanId: Id_70,
[...]
-    ParentId: Id_3,
+    ParentId: Id_21,

1 occurrences of :

-    TraceId: Id_1,
-    SpanId: Id_76,
+    TraceId: Id_94,
+    SpanId: Id_95,
+    Name: sql-server.query,
+    Resource: INSERT INTO [Stored-Proc-System-Data-SqlClient-Test-GUID] (Id, Name) VALUES (1, 'Name1'), (2, 'Name2'), (3, 'Name3');,
+    Service: Samples.SqlServer,
+    Type: sql,
+    Tags: {
+      component: SqlClient,
+      db.type: sql-server,
+      env: integration_tests,
+      language: dotnet,
+      out.host: sqlserver,
+      peer.service: sqlserver,
+      runtime-id: Guid_1,
+      span.kind: client,
+      version: 1.0.0,
+      _dd.dbm_trace_injected: true,
+      _dd.peer.service.source: out.host
+    },
+    Metrics: {
+      dd.instrumentation.time_ms: 123.456,
+      process_id: 0,
+      _dd.top_level: 1.0,
+      _dd.tracer_kr: 1.0,
+      _sampling_priority_v1: 1.0
+    }
+  },
+  {
+    TraceId: Id_19,
+    SpanId: Id_96,
[...]
-    ParentId: Id_3,
+    ParentId: Id_21,

1 occurrences of :

-    TraceId: Id_28,
-    SpanId: Id_29,
+    TraceId: Id_19,
+    SpanId: Id_28,
+    Name: sql-server.query,
+    Resource: DELETE FROM [System-Data-SqlClient-Test-GUID] WHERE Id=@Id;,
+    Service: Samples.SqlServer-sql-server,
+    Type: sql,
+    ParentId: Id_29,
+    Tags: {
+      component: SqlClient,
+      db.type: sql-server,
+      env: integration_tests,
+      language: dotnet,
+      out.host: sqlserver,
+      runtime-id: Guid_1,
+      span.kind: client,
+      _dd.base_service: Samples.SqlServer
+    },
+    Metrics: {
+      _dd.top_level: 1.0
+    }
+  },
+  {
+    TraceId: Id_19,
+    SpanId: Id_30,
[...]
-    ParentId: Id_30,
+    ParentId: Id_31,

1 occurrences of :

-    TraceId: Id_28,
-    SpanId: Id_31,
+    TraceId: Id_19,
+    SpanId: Id_32,
[...]
-    ParentId: Id_32,
+    ParentId: Id_33,

1 occurrences of :

-    TraceId: Id_28,
-    SpanId: Id_33,
+    TraceId: Id_19,
+    SpanId: Id_34,
[...]
-    ParentId: Id_34,
+    ParentId: Id_35,

1 occurrences of :

-    TraceId: Id_1,
-    SpanId: Id_52,
+    TraceId: Id_53,
+    SpanId: Id_54,
+    Name: sql-server.query,
+    Resource: DELETE FROM [System-Data-SqlClient-Test-GUID] WHERE Id=@Id;,
+    Service: Samples.SqlServer-sql-server,
+    Type: sql,
+    ParentId: Id_55,
+    Tags: {
+      component: SqlClient,
+      db.type: sql-server,
+      env: integration_tests,
+      language: dotnet,
+      out.host: sqlserver,
+      runtime-id: Guid_1,
+      span.kind: client,
+      _dd.base_service: Samples.SqlServer
+    },
+    Metrics: {
+      _dd.top_level: 1.0
+    }
+  },
+  {
+    TraceId: Id_53,
+    SpanId: Id_56,
+    Name: sql-server.query,
+    Resource: DELETE FROM [System-Data-SqlClient-Test-GUID] WHERE Id=@Id;,
+    Service: Samples.SqlServer-sql-server,
+    Type: sql,
+    ParentId: Id_57,
+    Tags: {
+      component: SqlClient,
+      db.type: sql-server,
+      env: integration_tests,
+      language: dotnet,
+      out.host: sqlserver,
+      runtime-id: Guid_1,
+      span.kind: client,
+      _dd.base_service: Samples.SqlServer
+    },
+    Metrics: {
+      _dd.top_level: 1.0
+    }
+  },
+  {
+    TraceId: Id_53,
+    SpanId: Id_58,
+    Name: sql-server.query,
+    Resource: DELETE FROM [System-Data-SqlClient-Test-GUID] WHERE Id=@Id;,
+    Service: Samples.SqlServer-sql-server,
+    Type: sql,
+    ParentId: Id_59,
+    Tags: {
+      component: SqlClient,
+      db.type: sql-server,
+      env: integration_tests,
+      language: dotnet,
+      out.host: sqlserver,
+      runtime-id: Guid_1,
+      span.kind: client,
+      _dd.base_service: Samples.SqlServer
+    },
+    Metrics: {
+      _dd.top_level: 1.0
+    }
+  },
+  {
+    TraceId: Id_53,
+    SpanId: Id_60,
+    Name: sql-server.query,
+    Resource: DELETE FROM [System-Data-SqlClient-Test-GUID] WHERE Id=@Id;,
+    Service: Samples.SqlServer-sql-server,
+    Type: sql,
+    ParentId: Id_61,
+    Tags: {
+      component: SqlClient,
+      db.type: sql-server,
+      env: integration_tests,
+      language: dotnet,
+      out.host: sqlserver,
+      runtime-id: Guid_1,
+      span.kind: client,
+      _dd.base_service: Samples.SqlServer
+    },
+    Metrics: {
+      _dd.top_level: 1.0
+    }
+  },
+  {
+    TraceId: Id_53,
+    SpanId: Id_62,
+    Name: sql-server.query,
+    Resource: DELETE FROM [System-Data-SqlClient-Test-GUID] WHERE Id=@Id;,
+    Service: Samples.SqlServer-sql-server,
+    Type: sql,
+    ParentId: Id_63,
+    Tags: {
+      component: SqlClient,
+      db.type: sql-server,
+      env: integration_tests,
+      language: dotnet,
+      out.host: sqlserver,
+      runtime-id: Guid_1,
+      span.kind: client,
+      _dd.base_service: Samples.SqlServer
+    },
+    Metrics: {
+      _dd.top_level: 1.0
+    }
+  },
+  {
+    TraceId: Id_53,
+    SpanId: Id_64,
+    Name: sql-server.query,
+    Resource: DELETE FROM [System-Data-SqlClient-Test-GUID] WHERE Id=@Id;,
+    Service: Samples.SqlServer-sql-server,
+    Type: sql,
+    ParentId: Id_65,
+    Tags: {
+      component: SqlClient,
+      db.type: sql-server,
+      env: integration_tests,
+      language: dotnet,
+      out.host: sqlserver,
+      runtime-id: Guid_1,
+      span.kind: client,
+      _dd.base_service: Samples.SqlServer
+    },
+    Metrics: {
+      _dd.top_level: 1.0
+    }
+  },
+  {
+    TraceId: Id_53,
+    SpanId: Id_66,
+    Name: sql-server.query,
+    Resource: DELETE FROM [System-Data-SqlClient-Test-GUID] WHERE Id=@Id;,
+    Service: Samples.SqlServer-sql-server,
+    Type: sql,
+    ParentId: Id_67,
+    Tags: {
+      component: SqlClient,
+      db.type: sql-server,
+      env: integration_tests,
+      language: dotnet,
+      out.host: sqlserver,
+      runtime-id: Guid_1,
+      span.kind: client,
+      _dd.base_service: Samples.SqlServer
+    },
+    Metrics: {
+      _dd.top_level: 1.0
+    }
+  },
+  {
+    TraceId: Id_53,
+    SpanId: Id_68,
+    Name: sql-server.query,
+    Resource: DELETE FROM [System-Data-SqlClient-Test-GUID] WHERE Id=@Id;,
+    Service: Samples.SqlServer-sql-server,
+    Type: sql,
+    ParentId: Id_69,
+    Tags: {
+      component: SqlClient,
+      db.type: sql-server,
+      env: integration_tests,
+      language: dotnet,
+      out.host: sqlserver,
+      runtime-id: Guid_1,
+      span.kind: client,
+      _dd.base_service: Samples.SqlServer
+    },
+    Metrics: {
+      _dd.top_level: 1.0
+    }
+  },
+  {
+    TraceId: Id_19,
+    SpanId: Id_70,
[...]
-    ParentId: Id_3,
+    ParentId: Id_21,

1 occurrences of :

-    TraceId: Id_1,
-    SpanId: Id_76,
+    TraceId: Id_94,
+    SpanId: Id_95,
+    Name: sql-server.query,
+    Resource: INSERT INTO [Stored-Proc-System-Data-SqlClient-Test-GUID] (Id, Name) VALUES (1, 'Name1'), (2, 'Name2'), (3, 'Name3');,
+    Service: Samples.SqlServer-sql-server,
+    Type: sql,
+    Tags: {
+      component: SqlClient,
+      db.type: sql-server,
+      env: integration_tests,
+      language: dotnet,
+      out.host: sqlserver,
+      runtime-id: Guid_1,
+      span.kind: client,
+      _dd.base_service: Samples.SqlServer
+    },
+    Metrics: {
+      process_id: 0,
+      _dd.top_level: 1.0,
+      _dd.tracer_kr: 1.0,
+      _sampling_priority_v1: 1.0
+    }
+  },
+  {
+    TraceId: Id_19,
+    SpanId: Id_96,
[...]
-    ParentId: Id_3,
+    ParentId: Id_21,

1 occurrences of :

+      runtime-id: Guid_1,
[...]
+    },
+    Metrics: {
+      process_id: 0,
+      _dd.top_level: 1.0,
+      _dd.tracer_kr: 1.0,
+      _sampling_priority_v1: 1.0
[...]
-    TraceId: Id_1,
+    TraceId: Id_3,
[...]
-    Resource: DELETE FROM [System-Data-SqlClient-Test-GUID] WHERE Id=@Id;,
+    Resource:
[...]
+    @Id int
[...]
+    SELECT * FROM [Stored-Proc-System-Data-SqlClient-Test-GUID] WHERE Id = @Id;
[...]
-    ParentId: Id_5,

1 occurrences of :

+      runtime-id: Guid_1,
[...]
+    },
+    Metrics: {
+      process_id: 0,
+      _dd.top_level: 1.0,
+      _dd.tracer_kr: 1.0,
+      _sampling_priority_v1: 1.0
[...]
-    TraceId: Id_1,
+    TraceId: Id_5,
[...]
-    Resource: DELETE FROM [System-Data-SqlClient-Test-GUID] WHERE Id=@Id;,
+    Resource:
[...]
+    @Id int,
+    @NewName varchar(100),
+    @OldName varchar(100) OUTPUT
[...]
+    -- Store the old name before updating
+    SELECT @OldName = Name FROM [Stored-Proc-System-Data-SqlClient-Test-GUID] WHERE Id = @Id;
+    -- Update the row
+    UPDATE [Stored-Proc-System-Data-SqlClient-Test-GUID] SET Name = @NewName WHERE Id = @Id;
+    -- Return number of rows affected
+    RETURN @@ROWCOUNT;
[...]
-    ParentId: Id_7,

1 occurrences of :

+      runtime-id: Guid_1,
[...]
+    },
+    Metrics: {
+      process_id: 0,
+      _dd.top_level: 1.0,
+      _dd.tracer_kr: 1.0,
+      _sampling_priority_v1: 1.0
[...]
-    TraceId: Id_1,
+    TraceId: Id_7,
[...]
-    Resource: DELETE FROM [System-Data-SqlClient-Test-GUID] WHERE Id=@Id;,
+    Resource:
[...]
-    ParentId: Id_9,

1 occurrences of :

+      runtime-id: Guid_1,
[...]
+    },
+    Metrics: {
+      process_id: 0,
+      _dd.top_level: 1.0,
+      _dd.tracer_kr: 1.0,
+      _sampling_priority_v1: 1.0
[...]
-    TraceId: Id_1,
+    TraceId: Id_9,
[...]
-    Resource: DELETE FROM [System-Data-SqlClient-Test-GUID] WHERE Id=@Id;,
+    Resource: CREATE TABLE [Stored-Proc-System-Data-SqlClient-Test-GUID] (Id int PRIMARY KEY, Name varchar(100));,
[...]
-    ParentId: Id_11,

1 occurrences of :

+      runtime-id: Guid_1,
[...]
+    },
+    Metrics: {
+      process_id: 0,
+      _dd.top_level: 1.0,
+      _dd.tracer_kr: 1.0,
+      _sampling_priority_v1: 1.0
[...]
-    TraceId: Id_1,
+    TraceId: Id_11,
[...]
-    Resource: DELETE FROM [System-Data-SqlClient-Test-GUID] WHERE Id=@Id;,
+    Resource: dbo.sp_BatchUpdate,
[...]
-    ParentId: Id_13,

1 occurrences of :

+      runtime-id: Guid_1,
[...]
+    },
+    Metrics: {
+      process_id: 0,
+      _dd.top_level: 1.0,
+      _dd.tracer_kr: 1.0,
+      _sampling_priority_v1: 1.0
[...]
-    TraceId: Id_1,
+    TraceId: Id_13,
[...]
-    Resource: DELETE FROM [System-Data-SqlClient-Test-GUID] WHERE Id=@Id;,
+    Resource: dbo.sp_BatchUpdate,
[...]
-    ParentId: Id_15,

1 occurrences of :

+      runtime-id: Guid_1,
[...]
+    },
+    Metrics: {
+      process_id: 0,
+      _dd.top_level: 1.0,
+      _dd.tracer_kr: 1.0,
+      _sampling_priority_v1: 1.0
[...]
-    TraceId: Id_1,
+    TraceId: Id_15,
[...]
-    Resource: DELETE FROM [System-Data-SqlClient-Test-GUID] WHERE Id=@Id;,
+    Resource: dbo.sp_GetTableRow,
[...]
-    ParentId: Id_17,

1 occurrences of :

+      runtime-id: Guid_1,
[...]
+    },
+    Metrics: {
+      process_id: 0,
+      _dd.top_level: 1.0,
+      _dd.tracer_kr: 1.0,
+      _sampling_priority_v1: 1.0
[...]
-    TraceId: Id_1,
+    TraceId: Id_17,
[...]
-    Resource: DELETE FROM [System-Data-SqlClient-Test-GUID] WHERE Id=@Id;,
+    Resource: dbo.sp_UpdateRowWithOutput,
[...]
-    ParentId: Id_19,

1 occurrences of :

+      runtime-id: Guid_1,
[...]
+    },
+    Metrics: {
+      process_id: 0,
+      _dd.top_level: 1.0,
+      _dd.tracer_kr: 1.0,
+      _sampling_priority_v1: 1.0
[...]
-    TraceId: Id_1,
+    TraceId: Id_19,

1 occurrences of :

-    TraceId: Id_35,
+    TraceId: Id_19,
+    SpanId: Id_34,
+    Name: sql-server.query,
+    Resource: DELETE FROM [System-Data-SqlClient-Test-GUID] WHERE Id=@Id;,
+    Service: Samples.SqlServer,
+    Type: sql,
+    ParentId: Id_35,
+    Tags: {
+      component: SqlClient,
+      db.type: sql-server,
+      env: integration_tests,
+      language: dotnet,
+      out.host: sqlserver,
+      peer.service: sqlserver,
+      span.kind: client,
+      version: 1.0.0,
+      _dd.peer.service.source: out.host
+    }
+  },
+  {
+    TraceId: Id_19,

1 occurrences of :

-    TraceId: Id_1,
-    SpanId: Id_52,
+    TraceId: Id_53,
+    SpanId: Id_54,
+    Name: sql-server.query,
+    Resource: DELETE FROM [System-Data-SqlClient-Test-GUID] WHERE Id=@Id;,
+    Service: Samples.SqlServer,
+    Type: sql,
+    ParentId: Id_55,
+    Tags: {
+      component: SqlClient,
+      db.type: sql-server,
+      env: integration_tests,
+      language: dotnet,
+      out.host: sqlserver,
+      peer.service: sqlserver,
+      span.kind: client,
+      version: 1.0.0,
+      _dd.peer.service.source: out.host
+    }
+  },
+  {
+    TraceId: Id_53,
+    SpanId: Id_56,
+    Name: sql-server.query,
+    Resource: DELETE FROM [System-Data-SqlClient-Test-GUID] WHERE Id=@Id;,
+    Service: Samples.SqlServer,
+    Type: sql,
+    ParentId: Id_57,
+    Tags: {
+      component: SqlClient,
+      db.type: sql-server,
+      env: integration_tests,
+      language: dotnet,
+      out.host: sqlserver,
+      peer.service: sqlserver,
+      span.kind: client,
+      version: 1.0.0,
+      _dd.peer.service.source: out.host
+    }
+  },
+  {
+    TraceId: Id_53,
+    SpanId: Id_58,
+    Name: sql-server.query,
+    Resource: DELETE FROM [System-Data-SqlClient-Test-GUID] WHERE Id=@Id;,
+    Service: Samples.SqlServer,
+    Type: sql,
+    ParentId: Id_59,
+    Tags: {
+      component: SqlClient,
+      db.type: sql-server,
+      env: integration_tests,
+      language: dotnet,
+      out.host: sqlserver,
+      peer.service: sqlserver,
+      span.kind: client,
+      version: 1.0.0,
+      _dd.peer.service.source: out.host
+    }
+  },
+  {
+    TraceId: Id_53,
+    SpanId: Id_60,
+    Name: sql-server.query,
+    Resource: DELETE FROM [System-Data-SqlClient-Test-GUID] WHERE Id=@Id;,
+    Service: Samples.SqlServer,
+    Type: sql,
+    ParentId: Id_61,
+    Tags: {
+      component: SqlClient,
+      db.type: sql-server,
+      env: integration_tests,
+      language: dotnet,
+      out.host: sqlserver,
+      peer.service: sqlserver,
+      span.kind: client,
+      version: 1.0.0,
+      _dd.peer.service.source: out.host
+    }
+  },
+  {
+    TraceId: Id_53,
+    SpanId: Id_62,
+    Name: sql-server.query,
+    Resource: DELETE FROM [System-Data-SqlClient-Test-GUID] WHERE Id=@Id;,
+    Service: Samples.SqlServer,
+    Type: sql,
+    ParentId: Id_63,
+    Tags: {
+      component: SqlClient,
+      db.type: sql-server,
+      env: integration_tests,
+      language: dotnet,
+      out.host: sqlserver,
+      peer.service: sqlserver,
+      span.kind: client,
+      version: 1.0.0,
+      _dd.peer.service.source: out.host
+    }
+  },
+  {
+    TraceId: Id_53,
+    SpanId: Id_64,
+    Name: sql-server.query,
+    Resource: DELETE FROM [System-Data-SqlClient-Test-GUID] WHERE Id=@Id;,
+    Service: Samples.SqlServer,
+    Type: sql,
+    ParentId: Id_65,
+    Tags: {
+      component: SqlClient,
+      db.type: sql-server,
+      env: integration_tests,
+      language: dotnet,
+      out.host: sqlserver,
+      peer.service: sqlserver,
+      span.kind: client,
+      version: 1.0.0,
+      _dd.peer.service.source: out.host
+    }
+  },
+  {
+    TraceId: Id_53,
+    SpanId: Id_66,
+    Name: sql-server.query,
+    Resource: DELETE FROM [System-Data-SqlClient-Test-GUID] WHERE Id=@Id;,
+    Service: Samples.SqlServer,
+    Type: sql,
+    ParentId: Id_67,
+    Tags: {
+      component: SqlClient,
+      db.type: sql-server,
+      env: integration_tests,
+      language: dotnet,
+      out.host: sqlserver,
+      peer.service: sqlserver,
+      span.kind: client,
+      version: 1.0.0,
+      _dd.peer.service.source: out.host
+    }
+  },
+  {
+    TraceId: Id_53,
+    SpanId: Id_68,
+    Name: sql-server.query,
+    Resource: DELETE FROM [System-Data-SqlClient-Test-GUID] WHERE Id=@Id;,
+    Service: Samples.SqlServer,
+    Type: sql,
+    ParentId: Id_69,
+    Tags: {
+      component: SqlClient,
+      db.type: sql-server,
+      env: integration_tests,
+      language: dotnet,
+      out.host: sqlserver,
+      peer.service: sqlserver,
+      span.kind: client,
+      version: 1.0.0,
+      _dd.peer.service.source: out.host
+    }
+  },
+  {
+    TraceId: Id_19,
+    SpanId: Id_70,
[...]
-    ParentId: Id_3,
+    ParentId: Id_21,

1 occurrences of :

-    TraceId: Id_1,
-    SpanId: Id_76,
+    TraceId: Id_94,
+    SpanId: Id_95,
+    Name: sql-server.query,
+    Resource: INSERT INTO [Stored-Proc-System-Data-SqlClient-Test-GUID] (Id, Name) VALUES (1, 'Name1'), (2, 'Name2'), (3, 'Name3');,
+    Service: Samples.SqlServer,
+    Type: sql,
+    Tags: {
+      component: SqlClient,
+      db.type: sql-server,
+      env: integration_tests,
+      language: dotnet,
+      out.host: sqlserver,
+      peer.service: sqlserver,
+      runtime-id: Guid_1,
+      span.kind: client,
+      version: 1.0.0,
+      _dd.peer.service.source: out.host
+    },
+    Metrics: {
+      process_id: 0,
+      _dd.top_level: 1.0,
+      _dd.tracer_kr: 1.0,
+      _sampling_priority_v1: 1.0
+    }
+  },
+  {
+    TraceId: Id_19,
+    SpanId: Id_96,
[...]
-    ParentId: Id_3,
+    ParentId: Id_21,

@bouwkast bouwkast marked this pull request as ready for review March 26, 2025 15:54
@bouwkast bouwkast requested review from a team as code owners March 26, 2025 15:54
// Output parameter - shoudl be added to EXEC command
var oldNameParam = command.Parameters.AddWithValue("@OldName", DBNull.Value);
oldNameParam.Direction = ParameterDirection.Output;
oldNameParam.Size = 100;
Copy link
Contributor

@zacharycmontoya zacharycmontoya Mar 26, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there any validation we can do here to make sure that the OUTPUT parameter and the return value are unaffected? For example, could we get the values somehow and add it as a tag somewhere so that this info is asserted with our snapshots?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What I'm wondering in general is how we validate that the stored procedure ran as expected. I see that we now have spans for those operations, but since we're doing some rewriting, can we either validate the output from the stored procedure call or should we rely on our unit tests to assert what the rewritten query looks like?

Separately, we'll need to validate that the DBM correlation looks correct in the UI, but that should be able to be done quickly and separately from the PR review.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Separately, we'll need to validate that the DBM correlation looks correct in the UI, but that should be able to be done quickly and separately from the PR review.

Yes I need to figure out how to do that still

{
if (integrationId is not (IntegrationId.MySql or IntegrationId.Npgsql or IntegrationId.SqlClient or IntegrationId.Oracle) ||
propagationLevel is not (DbmPropagationLevel.Service or DbmPropagationLevel.Full))
{
return false;
}

if ((!injectStoredProcedure && command.CommandType == CommandType.StoredProcedure)
|| (command.CommandType == CommandType.StoredProcedure && integrationId != IntegrationId.SqlClient))
Copy link
Contributor

@bricefriha bricefriha Mar 27, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry for being annoying again 😄

I like it like that, I think we could simplify this by replacing it with something like:

if (command.CommandType == CommandType.StoredProcedure && (!injectStoredProcedure || integrationId != IntegrationId.SqlClient))

Feel free to add your own flavour to it, I'm just giving ideas to make it more readable 😉

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks! Applied :)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: The files between the storedproc and nostoredproc are identical (which I guess makes sense since we're only updating the command sent to the DB and not the spans themselves) so I recommend unifying these

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we don't want to delay CI further, we can defer this to a small follow-up PR, it's not blocking

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll note it down to do in a follow up

Comment on lines 828 to 829
/// This only applies to StoredProcedures for Microsoft SQL Server when <see cref="DbmPropagationMode"/> is set to <c>service</c> or <c>full</c>.
/// This changes stored procedures that do not have <c>Output</c>/<c>InputOutput</c>/<c>Return</c> ADO.NET command parameters to their <c>EXEC</c> counterparts to inject context as a comment.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just a suggested rewording 😄

Suggested change
/// This only applies to StoredProcedures for Microsoft SQL Server when <see cref="DbmPropagationMode"/> is set to <c>service</c> or <c>full</c>.
/// This changes stored procedures that do not have <c>Output</c>/<c>InputOutput</c>/<c>Return</c> ADO.NET command parameters to their <c>EXEC</c> counterparts to inject context as a comment.
/// When enabled, Datadog trace context will be injected into individual stored procedure calls when the following requirements are met:
/// <ul>
/// <li>The database is Microsoft SQL Server and <see cref="DbmPropagationMode"/> is set to <c>service</c> or <c>full</c>.</li>
/// <li>The stored procedure call does not have <c>Output</c>, <c>InputOutput</c>, or <c>Return</c> ADO.NET command parameters.
/// </ul>

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe my details are not accurate, but I was thinking a slightly revised structure could help with clarity

Copy link
Contributor

@zacharycmontoya zacharycmontoya left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, thanks for diving into this. Let's make sure to track the work so we can investigate how to work around the limitations we have today.

Copy link
Member

@andrewlock andrewlock left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great work, really solid on the testing too, thanks 👍

Minor suggestions, nothing blocking, so feel free to ignore, and we can address later if necessary.

Comment on lines +105 to +106
src/Datadog.Trace/DatabaseMonitoring/MultiPartIdentifier.cs
src/Datadog.Trace/DatabaseMonitoring/VendoredSqlHelpers.cs
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These should be marked as nullable

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, my bad, it's vendored and they didn't mark it nullable. grmbl

/// <li>The stored procedure call does not have <c>Output</c>, <c>InputOutput</c>, or <c>Return</c> ADO.NET command parameters.</li>
/// </ul>
/// </summary>
public const string InjectContextIntoStoredProceduresEnabled = "DD_TRACE_INJECT_CONTEXT_INTO_STORED_PROCEDURES_ENABLED";
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't forget to add this to the config_norm file in go

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

* reference text SQL (no params): https://github.com/microsoft/referencesource/blob/51cf7850defa8a17d815b4700b67116e3fa283c2/System.Data/System/Data/SqlClient/SqlCommand.cs#L4437
*/

// check to see if we have any Return/InputOutput/Output parameters
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it worth logging a warning here, so that customers know why they aren't getting propagation for some stored procedures 🤔 If so, we might need to do some kind of rate limiting around it, so I'm unsure...

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I copy/pasted the "rate limiting" done in this file here as well
Probably could do with some cleanup

}
catch (Exception ex)
{
Log.Error(ex, "Failed to parse/quote stored procedure, no DBM data will be propagated");
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just flagging that if this errors, it will probably always error, which could lead to a flood of error logs... Maybe we should be safe and rate limit it (e.g. put the procName in a ConcurrentDictionary<> and see if it's already set? 🤷‍♂️)

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I copy/pasted the "rate limiting" done in this file here as well
Probably could do with some cleanup

}

// Build parameter list for EXEC statement
var paramList = new StringBuilder();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: No reason not to use the StringBuilderCache I think, especially given if there's no parameters, this just stays empty?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll get it in a follow up 😬


namespace Datadog.Trace.DatabaseMonitoring
{
internal static class VendoredSqlHelpers
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder if we should try to vendor any unit tests for these methods (and for MultiPartIdentifier)?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sounds like a good idea, I'll put that on the list of things to follow up on :)


public override int Size { get; set; }

// TODO no clue what this is
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

😂

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah I need to come back through there and clean stuff up later

command.CommandText.Should().Be(DbmCommandText);
}

// TODO; can probably clean these Stored Procedures up at some point, I just copy pasted
// TODO: can't get [InlineData(typeof(System.Data.SqlClient.SqlCommand))] to work with the MockParameters
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Aren't you doing that in the next method?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This one "works" because there aren't any parameters
Comment is supposed to be for all of the other ones that have parameters as it'd throw an exception expecting only the actual SqlParameter object, but I couldn't seem to create those objects without a valid Sql connection

Console.WriteLine("Test dbo.sp_GetTableRow");
using (var command = connection.CreateCommand())
{
command.CommandText = $@"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

tiny tiny tiny nit: """ is awesome and should be your go-to 😄

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep totally forgot that was a thing thanks!

@bouwkast bouwkast changed the title Propagate context for stored procedures Propagate context for some stored procedures Apr 1, 2025
@bouwkast bouwkast merged commit 32e9252 into master Apr 1, 2025
138 of 141 checks passed
@bouwkast bouwkast deleted the steven/dbm-prop-stored-proc-msft-sql-server branch April 1, 2025 19:16
@github-actions github-actions bot added this to the vNext-v3 milestone Apr 1, 2025
@NachoEchevarria NachoEchevarria added type:enhancement Improvement to an existing feature area:tracer The core tracer library (Datadog.Trace, does not include OpenTracing, native code, or integrations) labels Apr 2, 2025
@andrewlock andrewlock added area:database-monitoring and removed area:tracer The core tracer library (Datadog.Trace, does not include OpenTracing, native code, or integrations) labels Apr 2, 2025
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.

5 participants