Fix SQL Dependeny parentid to match w3ctracecontext

This commit is contained in:
Cijo Thomas 2019-10-01 10:33:50 -07:00
Родитель 655b716964
Коммит 99b57bfbc2
3 изменённых файлов: 76 добавлений и 9 удалений

Просмотреть файл

@ -1,5 +1,8 @@
# Changelog # Changelog
## Version 2.11.1
- [Fix Sql dependency parent id to match W3CTraceContext format](https://github.com/Microsoft/ApplicationInsights-dotnet-server/issues/1277)
## Version 2.11.0 ## Version 2.11.0
- [Fix Sql dependency tracking in .NET Core 3.0 which uses Microsoft.Data.SqlClient instead of System.Data.SqlClient](https://github.com/Microsoft/ApplicationInsights-dotnet-server/issues/1263) - [Fix Sql dependency tracking in .NET Core 3.0 which uses Microsoft.Data.SqlClient instead of System.Data.SqlClient](https://github.com/Microsoft/ApplicationInsights-dotnet-server/issues/1263)
- Updated Base SDK to 2.11.0 - Updated Base SDK to 2.11.0

Просмотреть файл

@ -13,6 +13,7 @@ namespace Microsoft.ApplicationInsights.Tests
using Microsoft.ApplicationInsights.DependencyCollector.Implementation.SqlClientDiagnostics; using Microsoft.ApplicationInsights.DependencyCollector.Implementation.SqlClientDiagnostics;
using Microsoft.ApplicationInsights.Extensibility; using Microsoft.ApplicationInsights.Extensibility;
using Microsoft.ApplicationInsights.Extensibility.Implementation.Tracing; using Microsoft.ApplicationInsights.Extensibility.Implementation.Tracing;
using Microsoft.ApplicationInsights.W3C.Internal;
using Microsoft.ApplicationInsights.Web.TestFramework; using Microsoft.ApplicationInsights.Web.TestFramework;
using Xunit; using Xunit;
@ -59,7 +60,60 @@ namespace Microsoft.ApplicationInsights.Tests
[Theory] [Theory]
[InlineData(SqlClientDiagnosticSourceListener.SqlBeforeExecuteCommand, SqlClientDiagnosticSourceListener.SqlAfterExecuteCommand)] [InlineData(SqlClientDiagnosticSourceListener.SqlBeforeExecuteCommand, SqlClientDiagnosticSourceListener.SqlAfterExecuteCommand)]
[InlineData(SqlClientDiagnosticSourceListener.SqlMicrosoftBeforeExecuteCommand, SqlClientDiagnosticSourceListener.SqlMicrosoftAfterExecuteCommand)] [InlineData(SqlClientDiagnosticSourceListener.SqlMicrosoftBeforeExecuteCommand, SqlClientDiagnosticSourceListener.SqlMicrosoftAfterExecuteCommand)]
public void InitializesTelemetryFromParentActivity(string beforeEventName, string afterEventName) public void InitializesTelemetryFromParentActivityNonW3C(string beforeEventName, string afterEventName)
{
try
{
// Disable W3C
Activity.DefaultIdFormat = ActivityIdFormat.Hierarchical;
Activity.ForceDefaultIdFormat = true;
var activity = new Activity("Current").AddBaggage("Stuff", "123");
activity.Start();
var operationId = Guid.NewGuid();
var sqlConnection = new SqlConnection(TestConnectionString);
var sqlCommand = sqlConnection.CreateCommand();
sqlCommand.CommandText = "select * from orders";
var beforeExecuteEventData = new
{
OperationId = operationId,
Command = sqlCommand,
Timestamp = (long?)1000000L
};
this.fakeSqlClientDiagnosticSource.Write(
beforeEventName,
beforeExecuteEventData);
var afterExecuteEventData = new
{
OperationId = operationId,
Command = sqlCommand,
Timestamp = 2000000L
};
this.fakeSqlClientDiagnosticSource.Write(
afterEventName,
afterExecuteEventData);
var dependencyTelemetry = (DependencyTelemetry)this.sendItems.Single();
Assert.Equal(activity.RootId, dependencyTelemetry.Context.Operation.Id);
Assert.Equal(activity.Id, dependencyTelemetry.Context.Operation.ParentId);
Assert.Equal("123", dependencyTelemetry.Properties["Stuff"]);
}
finally
{
Activity.DefaultIdFormat = ActivityIdFormat.W3C;
}
}
[Theory]
[InlineData(SqlClientDiagnosticSourceListener.SqlBeforeExecuteCommand, SqlClientDiagnosticSourceListener.SqlAfterExecuteCommand)]
[InlineData(SqlClientDiagnosticSourceListener.SqlMicrosoftBeforeExecuteCommand, SqlClientDiagnosticSourceListener.SqlMicrosoftAfterExecuteCommand)]
public void InitializesTelemetryFromParentActivityW3C(string beforeEventName, string afterEventName)
{ {
var activity = new Activity("Current").AddBaggage("Stuff", "123"); var activity = new Activity("Current").AddBaggage("Stuff", "123");
activity.Start(); activity.Start();
@ -93,8 +147,8 @@ namespace Microsoft.ApplicationInsights.Tests
var dependencyTelemetry = (DependencyTelemetry)this.sendItems.Single(); var dependencyTelemetry = (DependencyTelemetry)this.sendItems.Single();
Assert.Equal(activity.RootId, dependencyTelemetry.Context.Operation.Id); Assert.Equal(activity.TraceId.ToHexString(), dependencyTelemetry.Context.Operation.Id);
Assert.Equal(activity.Id, dependencyTelemetry.Context.Operation.ParentId); Assert.Equal(W3CUtilities.FormatTelemetryId(activity.TraceId.ToHexString(), activity.SpanId.ToHexString()), dependencyTelemetry.Context.Operation.ParentId);
Assert.Equal("123", dependencyTelemetry.Properties["Stuff"]); Assert.Equal("123", dependencyTelemetry.Properties["Stuff"]);
} }

Просмотреть файл

@ -13,6 +13,7 @@ namespace Microsoft.ApplicationInsights.DependencyCollector.Implementation.SqlCl
using Microsoft.ApplicationInsights.Extensibility; using Microsoft.ApplicationInsights.Extensibility;
using Microsoft.ApplicationInsights.Extensibility.Implementation; using Microsoft.ApplicationInsights.Extensibility.Implementation;
using Microsoft.ApplicationInsights.Extensibility.Implementation.Tracing; using Microsoft.ApplicationInsights.Extensibility.Implementation.Tracing;
using Microsoft.ApplicationInsights.W3C.Internal;
using static Microsoft.ApplicationInsights.DependencyCollector.Implementation.SqlClientDiagnostics.SqlClientDiagnosticFetcherTypes; using static Microsoft.ApplicationInsights.DependencyCollector.Implementation.SqlClientDiagnostics.SqlClientDiagnosticFetcherTypes;
internal class SqlClientDiagnosticSourceListener : IObserver<KeyValuePair<string, object>>, IDisposable internal class SqlClientDiagnosticSourceListener : IObserver<KeyValuePair<string, object>>, IDisposable
@ -342,13 +343,22 @@ namespace Microsoft.ApplicationInsights.DependencyCollector.Implementation.SqlCl
if (activity != null) if (activity != null)
{ {
telemetry.Context.Operation.Id = activity.RootId; // SQL Client does NOT create Activity.
// We initialize SQL dependency using Activity from incoming Request
// SQL Client does NOT create and Activity, i.e. // and it is the parent of the SQL dependency
// we initialize SQL dependency using request Activity
// and it is a parent of the SQL dependency
telemetry.Context.Operation.ParentId = activity.Id;
if (activity.IdFormat == ActivityIdFormat.W3C)
{
var traceId = activity.TraceId.ToHexString();
telemetry.Context.Operation.Id = traceId;
telemetry.Context.Operation.ParentId = W3CUtilities.FormatTelemetryId(traceId, activity.SpanId.ToHexString());
}
else
{
telemetry.Context.Operation.Id = activity.RootId;
telemetry.Context.Operation.ParentId = activity.Id;
}
foreach (var item in activity.Baggage) foreach (var item in activity.Baggage)
{ {
if (!telemetry.Properties.ContainsKey(item.Key)) if (!telemetry.Properties.ContainsKey(item.Key))