diff --git a/src/TraceEvent/Computers/StartStopActivityComputer.cs b/src/TraceEvent/Computers/StartStopActivityComputer.cs
index b6b17bd..88358e1 100644
--- a/src/TraceEvent/Computers/StartStopActivityComputer.cs
+++ b/src/TraceEvent/Computers/StartStopActivityComputer.cs
@@ -17,6 +17,7 @@ using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Text;
+using static Microsoft.Diagnostics.Tracing.Parsers.DynamicTraceEventData;
using Address = System.UInt64;
using StartStopKey = System.Guid; // The start-stop key is unique in the trace. We incorperate the process as well as activity ID to achieve this.
@@ -167,7 +168,7 @@ namespace Microsoft.Diagnostics.Tracing
return;
}
- // OK so now we only have EventSources with start and stop opcodes. THere are a few that don't follow
+ // OK so now we only have EventSources with start and stop opcodes. There are a few that don't follow
// conventions completely, and then we handle the 'normal' case
if (data.ProviderGuid == FrameworkEventSourceTraceEventParser.ProviderGuid)
FixAndProcessFrameworkEvents(data);
@@ -182,6 +183,16 @@ namespace Microsoft.Diagnostics.Tracing
{
if (data.Opcode == TraceEventOpcode.Start)
{
+ if (data.ProviderGuid == MicrosoftDiagnosticsDiagnosticSourceProvider)
+ {
+ // Inside the function, it will filter the events by 'EventName'.
+ // It will only process "Microsoft.EntityFrameworkCore.BeforeExecuteCommand" and "Microsoft.AspNetCore.Hosting.BeginRequest".
+ if (TryProcessDiagnosticSourceStartEvents(data))
+ {
+ return;
+ }
+ }
+
string extraStartInfo = null;
// Include the first argument in extraInfo if it is a string (e.g. a URL or other identifier).
if (0 < data.PayloadNames.Length)
@@ -712,6 +723,7 @@ namespace Microsoft.Diagnostics.Tracing
private static readonly Guid MicrosoftWindowsIISProvider = new Guid("de4649c9-15e8-4fea-9d85-1cdda520c334");
private static readonly Guid AdoNetProvider = new Guid("6a4dfe53-eb50-5332-8473-7b7e10a94fd1");
private static readonly Guid MicrosoftWindowsHttpService = new Guid("dd5ef90a-6398-47a4-ad34-4dcecdef795f");
+ private static readonly Guid MicrosoftDiagnosticsDiagnosticSourceProvider = new Guid("ADB401E1-5296-51F8-C125-5FDA75826144");
// The main start and stop logic.
@@ -913,6 +925,71 @@ namespace Microsoft.Diagnostics.Tracing
}
}
}
+
+ ///
+ /// Try to process some predefined DiagnosticSource ("Microsoft.EntityFrameworkCore.BeforeExecuteCommand" and "Microsoft.AspNetCore.Hosting.BeginRequest") start events.
+ /// This will try to filter the events by "EventName", if failed it will return false without any further processing.
+ ///
+ /// Whether or not succeeded in processing the event
+ bool TryProcessDiagnosticSourceStartEvents(TraceEvent data)
+ {
+ Debug.Assert(data.ProviderGuid == MicrosoftDiagnosticsDiagnosticSourceProvider);
+ bool result = false;
+ try
+ {
+ var eventName = data.PayloadByName("EventName") as string;
+ switch (eventName)
+ {
+ case "Microsoft.EntityFrameworkCore.BeforeExecuteCommand":
+ {
+ // In the converter from 'DiagnosticSource' to ETW, we have some default configurations.
+ // By default, SQL (EntityFramework) DiagnosticSource event will be converted to 'Activity2Start' and 'Activity2Stop' events
+ // of provider 'Microsoft-Diagnostics-DiagnosticSource'. Meanwhile, the sql command will be in the payload.
+ // The following code is used to make the call stack looks better (converting 'Activity2Start' to 'SQLCommand')
+ // and showing the SQL command.
+ // Details:
+ //https://github.com/dotnet/corefx/blob/master/src/System.Diagnostics.DiagnosticSource/src/System/Diagnostics/DiagnosticSourceEventSource.cs
+ if (0 < data.PayloadNames.Length)
+ {
+ var arguments = data.PayloadByName("Arguments") as StructValue[];
+ if (arguments != null)
+ {
+ // Try to extract SQL command of the EntityFramework event.
+ foreach (var payload in arguments)
+ {
+ object tmp;
+ if (payload.TryGetValue("Key", out tmp)
+ && tmp.ToString() == "CommandText")
+ {
+ if (payload.TryGetValue("Value", out tmp))
+ {
+ OnStart(data, tmp.ToString(), null, null, null, "SQLCommand");
+ result = true;
+ break;
+ }
+ }
+ }
+ }
+ }
+ }
+ break;
+ case "Microsoft.AspNetCore.Hosting.BeginRequest":
+ {
+ // Just change the name from "Activity1Start" to "AspNetCoreHosting".
+ OnStart(data, null, null, null, null, "AspNetCoreHosting");
+ result = true;
+ }
+ break;
+ }
+ }
+ catch (Exception ex)
+ {
+ Trace.WriteLine("Threw exception while processing DiagnosticSource start events: " + ex.Message);
+ }
+
+ return result;
+ }
+
void FixAndProcessFrameworkEvents(TraceEvent data)
{
Debug.Assert(data.ProviderGuid == FrameworkEventSourceTraceEventParser.ProviderGuid);