/// <summary> /// Start the CLR provider and start listening to the provider for the ILStub Generated Event /// and ILStub Cache Hit Event. /// Both two kinds of events will be recorded in ILStubDiagnosticSessionController as an /// ILStubGeneratedEvent instance or an ILStubCacheHitEvent instance. /// </summary> public void EnableILStubSession() { if (m_isEnabled) { return; } TraceEventLevel providerLevel = TraceEventLevel.Informational; // create ETW trace session and monitor in real time m_ILStubSession = new TraceEventSession(ILStubDiagnosticSessionName, null); // start ETW trace session try { m_ILStubSession.EnableProvider(ClrProviderGuid, providerLevel, 0, 0, null); } catch (UnauthorizedAccessException) { MessageBox.Show(Resource.ResourceManager.GetString("Err_UnauthorizedAccess")); Environment.Exit(0); } // Register handlers for ILStubStubGenerated and ILStubStubCacheHit events m_ILStubSource = new ETWTraceEventSource(ILStubDiagnosticSessionName, TraceEventSourceType.Session); ClrTraceEventParser clrEventParser = new ClrTraceEventParser(m_ILStubSource); clrEventParser.ILStubStubGenerated += AcceptILStubEvent; clrEventParser.ILStubStubCacheHit += AcceptILStubEvent; // Start the clr ETW trace m_ILStubProcessTraceThread = new Thread(ILStubProcessTraceMethod); m_ILStubProcessTraceThread.Start(); m_isEnabled = true; }
public StackSource GetStackSource(TraceEvents events) { if (events == null) { ThrowHelper.ThrowArgumentNullException(nameof(events)); } var stackSource = new MutableTraceEventStackSource(events.Log); var eventSource = events.GetSource(); var sample = new StackSourceSample(stackSource); var clrTraceEventParser = new ClrTraceEventParser(eventSource); clrTraceEventParser.GCAllocationTick += delegate(GCAllocationTickTraceData data) { var size = data.AllocationAmount64; sample.Metric = size; sample.Count = 1; sample.TimeRelativeMSec = data.TimeStampRelativeMSec; sample.StackIndex = stackSource.Interner.CallStackIntern(stackSource.Interner.FrameIntern("Type " + data.TypeName), stackSource.GetCallStack(data.CallStackIndex(), data)); if (data.AllocationKind == GCAllocationKind.Large) { sample.StackIndex = stackSource.Interner.CallStackIntern(stackSource.Interner.FrameIntern("LargeObject"), sample.StackIndex); } stackSource.AddSample(sample); }; eventSource.Process(); return(stackSource); }
public StackSource GetStackSource(TraceEvents events) { if (events == null) { ThrowHelper.ThrowArgumentNullException(nameof(events)); } var stackSource = new MutableTraceEventStackSource(events.Log) { ShowUnknownAddresses = true }; var eventSource = events.GetSource(); var sample = new StackSourceSample(stackSource); var clrTraceEventParser = new ClrTraceEventParser(eventSource); clrTraceEventParser.ContentionStart += delegate(ContentionTraceData data) { sample.Metric = 1; sample.TimeRelativeMSec = data.TimeStampRelativeMSec; string nodeName = data.ContentionFlags == ContentionFlags.Native ? "Native Contention" : "Managed Contention"; var nodeIndex = stackSource.Interner.FrameIntern(nodeName); sample.StackIndex = stackSource.Interner.CallStackIntern(nodeIndex, stackSource.GetCallStack(data.CallStackIndex(), data)); stackSource.AddSample(sample); }; eventSource.Process(); return(stackSource); }
public StackSource GetStackSource(TraceEvents events) { if (events == null) { ThrowHelper.ThrowArgumentNullException(nameof(events)); } var stackSource = new MutableTraceEventStackSource(events.Log) { ShowUnknownAddresses = true }; var eventSource = events.GetSource(); var sample = new StackSourceSample(stackSource); var clrTraceEventParser = new ClrTraceEventParser(eventSource); clrTraceEventParser.ExceptionStart += delegate(ExceptionTraceData data) { sample.Metric = 1; sample.TimeRelativeMSec = data.TimeStampRelativeMSec; // Create a call stack that ends with the 'throw' var nodeName = "Throw(" + data.ExceptionType + ") " + data.ExceptionMessage; var nodeIndex = stackSource.Interner.FrameIntern(nodeName); sample.StackIndex = stackSource.Interner.CallStackIntern(nodeIndex, stackSource.GetCallStack(data.CallStackIndex(), data)); stackSource.AddSample(sample); }; eventSource.Process(); return(stackSource); }
public void RunTests(string etlFileName) { Console.WriteLine($"In {nameof(ObservableTests)}.{nameof(RunTests)}(\"{etlFileName}\")"); PrepareTestData(); string etlFilePath = Path.Combine(UnZippedDataDir, etlFileName); Console.WriteLine("Start ObservableTests"); using (var source = new ETWTraceEventSource(etlFilePath)) { var startCallbackCount = source.CallbackCount(); Console.WriteLine("StartCallbackCount = " + startCallbackCount); var clrParser = new ClrTraceEventParser(source); var eventSourceParser = new DynamicTraceEventParser(source); IObservable <GCAllocationTickTraceData> gcTicks = clrParser.Observe <GCAllocationTickTraceData>("GC/AllocationTick"); IObservable <TraceEvent> logMessages = eventSourceParser.Observe("PerfView", "PerfViewLog"); IObservable <TraceEvent> allPerfView = eventSourceParser.Observe("PerfView", null); IObservable <TraceEvent> perfViewTicks = eventSourceParser.Observe("PerfView", "Tick"); IObservable <TraceEvent> allTasks = eventSourceParser.Observe("System.Threading.Tasks.TplEventSource", null); var cnt = 0; using (var gcSub = Subscribe(gcTicks, gcTickData => Console.WriteLine("Got Tick {0}", gcTickData.AllocationAmount), () => Console.WriteLine("Ticks Completed."))) using (var manifestSub = Subscribe(perfViewTicks, manifestData => Console.WriteLine("Got PerfView Tick {0:f4}", manifestData.TimeStampRelativeMSec), () => Console.WriteLine("Manifests Completed"))) using (var allTasksSub = Subscribe(allTasks, delegate(TraceEvent allTasksData) { if (allTasksData.EventName != "ManifestData") { Console.WriteLine("Got AllTasks: Data = {0}", allTasksData); } }, () => Console.WriteLine("allTasks Completed"))) using (var logSub = Subscribe(logMessages, logMessageData => Console.WriteLine("Got PerfView Log Message {0}", logMessageData.PayloadByName("message")), () => Console.WriteLine("Log Messages Completed"))) { IDisposable allPerfSub = null; allPerfSub = Subscribe(allPerfView, delegate(TraceEvent allPerfViewData) { cnt++; if (cnt >= 5) { Console.WriteLine("Canceling allPerfiew"); allPerfSub.Dispose(); allPerfSub = null; } Console.WriteLine("allPerfView {0}", allPerfViewData); }, () => Console.WriteLine("allPerfView Completed")); source.Process(); if (allPerfSub != null) { allPerfSub.Dispose(); } } var endCallbackCount = source.CallbackCount(); Console.WriteLine("endCallbackCount = " + endCallbackCount); } Console.WriteLine("Done ObservableTests"); }
public IEnumerable <Counter> Parse(string mergeTraceFile, string processName, IList <int> pids, string commandLine) { var loadingParser = new EventParser("Loading", (1, 2)); var emittingParser = new EventParser("Emitting", (3, 4)); var compilationParser = new EventParser("Compilation", (5, 6)); var jittingParser = new EventParser("Jit", (7, 8)); using (var source = new TraceSourceManager(mergeTraceFile)) { var dynamicParser = new DynamicTraceEventParser(source.Source); var clrParser = new ClrTraceEventParser(source.Source); loadingParser.AddStartStopCallbacks(source, dynamicParser, clrParser, ProviderName, pids); emittingParser.AddStartStopCallbacks(source, dynamicParser, clrParser, ProviderName, pids); compilationParser.AddStartStopCallbacks(source, dynamicParser, clrParser, ProviderName, pids); jittingParser.AddStartStopCallbacks(source, dynamicParser, clrParser, ProviderName, pids); source.Process(); } var processTimeParser = new ProcessTimeParser(); Counter processTimeCounter = null; if (!Util.IsWindows()) { processName = "corerun"; } foreach (var counter in processTimeParser.Parse(mergeTraceFile, processName, pids, commandLine)) { if (counter.Name == "Process Time") { processTimeCounter = counter; } } return(new[] { processTimeCounter, new Counter() { Name = "Loading Interval", MetricName = "ms", DefaultCounter = false, TopCounter = true, Results = loadingParser.Intervals.ToArray() }, new Counter() { Name = "Emitting Interval", MetricName = "ms", DefaultCounter = false, TopCounter = true, Results = emittingParser.Intervals.ToArray() }, new Counter() { Name = "Jit Interval", MetricName = "ms", DefaultCounter = false, TopCounter = true, Results = jittingParser.Intervals.ToArray() }, new Counter() { Name = "Compilation Interval", MetricName = "ms", DefaultCounter = false, TopCounter = true, Results = compilationParser.Intervals.ToArray() } }); }
/// <summary> /// Wire up parsing of CLR event data from the specified ETWTraceEventSource. /// </summary> /// <param name="eventSource">The ETWTraceEventSource from which to parse the data.</param> private void ParseClrTraceEvents(ETWTraceEventSource eventSource) { if (m_clrEvents == ClrTraceEventParser.Keywords.None) { return; } var clrTraceEventParser = new ClrTraceEventParser(eventSource); // iterate over each set bit, wiring up a callback to parse the data ulong eventBits = (ulong)m_clrEvents; int bitPos = 0; while (eventBits > 0) { // cycle through until a set bit is found while ((((ulong)eventBits) & (ulong)(1 << bitPos)) == 0) { ++bitPos; Debug.Assert(bitPos < 64); } var bitVal = (ulong)(1 << bitPos); // now strip it from eventBits and covert it to its enum value eventBits ^= bitVal; ClrTraceEventParser.Keywords clrEvent = (ClrTraceEventParser.Keywords)bitVal; // aggregate the high and low events if both are available (enabling both provides a more complete value) if ((clrEvent & ClrTraceEventParser.Keywords.GCSampledObjectAllocationHigh) == ClrTraceEventParser.Keywords.GCSampledObjectAllocationHigh || (clrEvent & ClrTraceEventParser.Keywords.GCSampledObjectAllocationLow) == ClrTraceEventParser.Keywords.GCSampledObjectAllocationLow || (clrEvent & ClrTraceEventParser.Keywords.GCAllObjectAllocation) == ClrTraceEventParser.Keywords.GCAllObjectAllocation) { if (!m_aed.ClrEventsData.ContainsKey(ClrPerfEvents.GCBytesAllocated)) { m_aed.AddData(new EventDataScalarLong <ClrPerfEvents>(ClrPerfEvents.GCBytesAllocated)); } var gcBytesAllocated = (EventDataScalarLong <ClrPerfEvents>)m_aed.ClrEventsData[ClrPerfEvents.GCBytesAllocated]; clrTraceEventParser.GCSampledObjectAllocation += delegate(GCSampledObjectAllocationTraceData data) { if (string.Compare(data.ProcessName, m_process, true) == 0) { gcBytesAllocated.Value += data.TotalSizeForTypeSample; m_processFound = true; } }; } else { Console.WriteLine("WARNING: CLR event {0} NYI for reporting.", clrEvent); } } }
public void SubscribeRuntimeEvents(Microsoft.Diagnostics.Tracing.TraceEventSource s) { _parser = new ClrTraceEventParser(s); //_parser.LoaderAppDomainLoad += d => Console.WriteLine($"LoaderAppDomainLoad {d.AppDomainID}"); //_parser.LoaderAppDomainUnload += d => Console.WriteLine($"LoaderAppDomainUnload {d.AppDomainID}"); //_parser.LoaderAssemblyLoad += d => Console.WriteLine($"LoaderAssemblyLoad {d.FullyQualifiedAssemblyName}"); //_parser.LoaderAssemblyUnload += d => Console.WriteLine($"LoaderAssemblyUnload {d.FullyQualifiedAssemblyName}"); //_parser.LoaderDomainModuleLoad += d => Console.WriteLine($"LoaderDomainModuleLoad {d.ModuleNativePath}"); //_parser.LoaderModuleDCStartV2 += d => Console.WriteLine($"LoaderModuleDCStartV2 {d.ModuleNativePath}"); //_parser.LoaderModuleDCStopV2 += d => Console.WriteLine($"LoaderModuleDCStopV2 {d.ModuleNativePath}"); //_parser.LoaderModuleLoad += d => Console.WriteLine($"LoaderModuleLoad {d.ModuleNativePath}"); //_parser.LoaderModuleUnload += d => Console.WriteLine($"LoaderModuleUnload {d.ModuleNativePath}"); //_parser.AssemblyLoaderAppDomainAssemblyResolveHandlerInvoked += d => Console.WriteLine($"AssemblyLoaderAppDomainAssemblyResolveHandlerInvoked {d.ResultAssemblyPath}"); //_parser.AssemblyLoaderAssemblyLoadContextResolvingHandlerInvoked += d => Console.WriteLine($"AssemblyLoaderAssemblyLoadContextResolvingHandlerInvoked {d.ResultAssemblyPath}"); //_parser.AssemblyLoaderAssemblyLoadFromResolveHandlerInvoked += d => Console.WriteLine($"AssemblyLoaderAssemblyLoadFromResolveHandlerInvoked {d.RequestingAssemblyPath}"); //_parser.AssemblyLoaderKnownPathProbed += d => Console.WriteLine($"AssemblyLoaderKnownPathProbed {d.PathSource}"); _parser.AssemblyLoaderResolutionAttempted += d => { switch (d.Result) { case ResolutionAttemptedResult.Success: Console.WriteLine($"AssemblyLoaderResolutionAttempted {d.Result} {d.AssemblyLoadContext} {d.ResultAssemblyPath} "); break; //default: // Console.WriteLine($"AssemblyLoaderResolutionAttempted {d.Result} {d.AssemblyLoadContext} {d.AssemblyName}"); // break; } }; //_parser.AssemblyLoaderStart += d => //{ // if (d.AssemblyLoadContext != "Default") Console.WriteLine($"AssemblyLoaderStart {d.AssemblyLoadContext} {d.AssemblyPath}"); //}; //_parser.AssemblyLoaderStop += d => //{ // if (d.AssemblyLoadContext != "Default") Console.WriteLine($"AssemblyLoaderStop {d.AssemblyLoadContext} {d.AssemblyPath}"); //}; //_parser.MethodLoad += d => Console.WriteLine($"MethodLoad {d.MethodToken}"); //_parser.MethodLoadVerbose += d => Console.WriteLine($"MethodLoadVerbose {d.MethodNamespace} {d.MethodName}"); //_parser.TypeLoadStart += d => Console.WriteLine($"TypeLoadStart {d.TypeLoadStartID}"); //_parser.TypeLoadStop += d => Console.WriteLine($"TypeLoadStop {d.TypeName}"); }
public static AspNetCoreParserResults ParseDotNetCoreRequests(Microsoft.Diagnostics.Tracing.Etlx.TraceLog dataFile, int minRequestDurationMilliseconds) { AspNetCoreParserResults results = new AspNetCoreParserResults(); var processes = new List <AspNetCoreProcess>(); var aspnetCoreRequests = new Dictionary <string, AspNetCoreRequest>(); var requestsFullTrace = new Dictionary <AspNetCoreRequestId, List <AspNetCoreTraceEvent> >(); var failedRequests = new Dictionary <AspNetCoreRequest, List <AspNetCoreTraceEvent> >(); try { var source = dataFile.Events.GetSource(); var parser = new DynamicTraceEventParser(source); var clrParser = new ClrTraceEventParser(source); parser.AddCallbackForProviderEvent(MicrosoftExtensionsLoggingProvider, StartEvent, delegate(TraceEvent data) { ParseExtensionsLoggingEvent(data, minRequestDurationMilliseconds, "Arguments", aspnetCoreRequests, failedRequests, requestsFullTrace, AspNetCoreRequestEventType.Start); }); parser.AddCallbackForProviderEvent(MicrosoftExtensionsLoggingProvider, StopEvent, delegate(TraceEvent data) { ParseExtensionsLoggingEvent(data, minRequestDurationMilliseconds, string.Empty, aspnetCoreRequests, failedRequests, requestsFullTrace, AspNetCoreRequestEventType.Stop); }); parser.AddCallbackForProviderEvent(MicrosoftExtensionsLoggingProvider, FormatMessageEvent, delegate(TraceEvent data) { ParseExtensionsLoggingEvent(data, minRequestDurationMilliseconds, "FormattedMessage", aspnetCoreRequests, failedRequests, requestsFullTrace, AspNetCoreRequestEventType.Message); }); clrParser.ThreadPoolWorkerThreadWait += delegate(ThreadPoolWorkerThreadTraceData data) { if (!processes.Any(p => p.Id == data.ProcessID && p.Name == data.ProcessName)) { var coreProcess = new AspNetCoreProcess { Id = data.ProcessID, Name = data.ProcessName }; processes.Add(coreProcess); } }; source.Process(); } catch (Exception ex) { Logger.LogDiagnoserErrorEvent("Failed while parsing .net core events", ex); } foreach (var request in aspnetCoreRequests.Values) { if (request.EndTimeRelativeMSec == 0) { request.EndTimeRelativeMSec = dataFile.SessionEndTimeRelativeMSec; request.IncompleteRequest = true; } } results.AspNetCoreRequestsFullTrace = requestsFullTrace; results.Requests = aspnetCoreRequests; results.Processes = processes; results.FailedRequests = failedRequests; return(results); }
private void TraceEvents() { // will attempt to create a session named "MySession" using (var session = new TraceEventSession("MySession")) { // set up Ctrl-C to stop the session SetupCtrlCHandler(() => { session.Stop(); }); // set up parser to read CLR events var clrParser = new ClrTraceEventParser(session.Source); if (ExceptionEnabled == 1) { // subscribe to all exception start events clrParser.ExceptionStart += delegate(ExceptionTraceData data) { // if exception was in user process, add it to list of exceptions if (data.ProcessID == myProcess.Id) { Exceptions e = new Exceptions(); e.type = data.ExceptionType; e.timestamp = DateTime.Now; e.App = instance; lock (lockObject) { ExceptionVals.Add(e); } } }; } if (ContentionEnabled == 1) { // subscribe to all contention start events clrParser.ContentionStart += delegate(ContentionTraceData data) { if (data.ProcessID == myProcess.Id) { Contention c = new Contention(); c.type = "Start"; c.id = data.ActivityID; c.timestamp = DateTime.Now; c.App = instance; lock (lockObject) { ContentionVals.Add(c); } } }; // subscribe to all contention stop events clrParser.ContentionStop += delegate(ContentionTraceData data) { if (data.ProcessID == myProcess.Id) { Contention c = new Contention(); c.type = "Stop"; c.id = data.ActivityID; c.timestamp = DateTime.Now; c.App = instance; lock (lockObject) { ContentionVals.Add(c); } } }; } if (GCEnabled == 1) { // subscribe to all GC start events clrParser.GCStart += delegate(GCStartTraceData data) { if (data.ProcessID == myProcess.Id) { GC gc = new GC(); gc.type = "Start"; gc.timestamp = DateTime.Now; gc.id = data.ThreadID; gc.App = instance; lock (lockObject) { GCVals.Add(gc); } } }; // subscribe to all GC stop events clrParser.GCStop += delegate(GCEndTraceData data) { if (data.ProcessID == myProcess.Id) { GC gc = new GC(); gc.type = "Stop"; gc.timestamp = DateTime.Now; gc.id = data.ThreadID; gc.App = instance; lock (lockObject) { GCVals.Add(gc); } } }; // subscribe to all GC memory allocation ticks clrParser.GCAllocationTick += delegate(GCAllocationTickTraceData data) { if (data.ProcessID == myProcess.Id) { GC gc = new GC(); gc.type = "Allocation Tick"; gc.timestamp = DateTime.Now; gc.id = data.ThreadID; gc.App = instance; lock (lockObject) { GCVals.Add(gc); } } }; // subscribe to all creations of concurrent threads for GC clrParser.GCCreateConcurrentThread += delegate(GCCreateConcurrentThreadTraceData data) { if (data.ProcessID == myProcess.Id) { GC gc = new GC(); gc.type = "Create Concurrent Thread"; gc.timestamp = DateTime.Now; gc.id = data.ThreadID; gc.App = instance; lock (lockObject) { GCVals.Add(gc); } } }; // subscribe to all restart stops clrParser.GCRestartEEStop += delegate(GCNoUserDataTraceData data) { if (data.ProcessID == myProcess.Id) { GC gc = new GC(); gc.type = "Restart EE Stop"; gc.timestamp = DateTime.Now; gc.id = data.ThreadID; gc.App = instance; lock (lockObject) { GCVals.Add(gc); } } }; // subscribe to all suspension starts clrParser.GCSuspendEEStart += delegate(GCSuspendEETraceData data) { if (data.ProcessID == myProcess.Id) { GC gc = new GC(); gc.type = "Suspend EE Start"; gc.timestamp = DateTime.Now; gc.id = data.ThreadID; gc.App = instance; lock (lockObject) { GCVals.Add(gc); } } }; // subscribe to all concurrent thread terminations clrParser.GCTerminateConcurrentThread += delegate(GCTerminateConcurrentThreadTraceData data) { if (data.ProcessID == myProcess.Id) { GC gc = new GC(); gc.type = "Concurrent Thread Termination"; gc.timestamp = DateTime.Now; gc.id = data.ThreadID; gc.App = instance; lock (lockObject) { GCVals.Add(gc); } } }; // subscribe to all GC triggers clrParser.GCTriggered += delegate(GCTriggeredTraceData data) { if (data.ProcessID == myProcess.Id) { GC gc = new GC(); gc.type = "Triggered"; gc.timestamp = DateTime.Now; gc.id = data.ThreadID; gc.App = instance; lock (lockObject) { GCVals.Add(gc); } } }; } if (JitEnabled == 1) { // subscribe to all Jit start events clrParser.MethodJittingStarted += delegate(MethodJittingStartedTraceData data) { if (data.ProcessID == myProcess.Id) { Jit j = new Jit(); j.method = data.MethodName; j.timestamp = DateTime.Now; j.App = instance; lock (lockObject) { JitVals.Add(j); } } }; } if (HttpEnabled == 1) { // subscribe to all dynamic events (used for HTTP request event tracking) session.Source.Dynamic.All += delegate(TraceEvent data) { if (data.ProcessID == myProcess.Id && data.EventName == "Request/Start") { Http_Request request = new Http_Request(); request.type = "Start"; request.timestamp = DateTime.Now; request.activityID = data.ActivityID; request.App = instance; request.method = data.PayloadString(0); request.path = data.PayloadString(1); lock (lockObject) { RequestVals.Add(request); } } else if (data.ProcessID == myProcess.Id && data.EventName == "Request/Stop") { Http_Request request = new Http_Request(); request.type = "Stop"; request.timestamp = DateTime.Now; request.activityID = data.ActivityID; request.App = instance; lock (lockObject) { RequestVals.Add(request); } } }; } // set up providers for events using GUIDs - first EnableProvider command is to receive activity IDs for associated events session.EnableProvider(new Guid("2e5dba47-a3d2-4d16-8ee0-6671ffdcd7b5"), TraceEventLevel.Informational, 0x80); var AspSourceGuid = TraceEventProviders.GetEventSourceGuidFromName("Microsoft-AspNetCore-Hosting"); session.EnableProvider(AspSourceGuid); session.EnableProvider(ClrTraceEventParser.ProviderGuid, TraceEventLevel.Verbose, (0x8000 | 0x4000 | 0x1 | 0x10)); session.Source.Process(); // call the callbacks for each event } }
public ClrEvents(ClrTraceEventParser.Keywords events) { m_events = events; }
/// <summary> /// Wire up parsing of CLR event data from the specified ETWTraceEventSource. /// </summary> /// <param name="eventSource">The ETWTraceEventSource from which to parse the data.</param> private void ParseClrTraceEvents(ETWTraceEventSource eventSource) { if (m_clrEvents == ClrTraceEventParser.Keywords.None) return; var clrTraceEventParser = new ClrTraceEventParser(eventSource); // iterate over each set bit, wiring up a callback to parse the data ulong eventBits = (ulong)m_clrEvents; int bitPos = 0; while (eventBits > 0) { // cycle through until a set bit is found while ((((ulong)eventBits) & (ulong)(1 << bitPos)) == 0) { ++bitPos; Debug.Assert(bitPos < 64); } var bitVal = (ulong)(1 << bitPos); // now strip it from eventBits and covert it to its enum value eventBits ^= bitVal; ClrTraceEventParser.Keywords clrEvent = (ClrTraceEventParser.Keywords)bitVal; // aggregate the high and low events if both are available (enabling both provides a more complete value) if ((clrEvent & ClrTraceEventParser.Keywords.GCSampledObjectAllocationHigh) == ClrTraceEventParser.Keywords.GCSampledObjectAllocationHigh || (clrEvent & ClrTraceEventParser.Keywords.GCSampledObjectAllocationLow) == ClrTraceEventParser.Keywords.GCSampledObjectAllocationLow || (clrEvent & ClrTraceEventParser.Keywords.GCAllObjectAllocation) == ClrTraceEventParser.Keywords.GCAllObjectAllocation) { if (!m_aed.ClrEventsData.ContainsKey(ClrPerfEvents.GCBytesAllocated)) m_aed.AddData(new EventDataScalarLong<ClrPerfEvents>(ClrPerfEvents.GCBytesAllocated)); var gcBytesAllocated = (EventDataScalarLong<ClrPerfEvents>)m_aed.ClrEventsData[ClrPerfEvents.GCBytesAllocated]; clrTraceEventParser.GCSampledObjectAllocation += delegate(GCSampledObjectAllocationTraceData data) { if (string.Compare(data.ProcessName, m_process, true) == 0) { gcBytesAllocated.Value += data.TotalSizeForTypeSample; m_processFound = true; } }; } else { Console.WriteLine("WARNING: CLR event {0} NYI for reporting.", clrEvent); } } }
public static List <IisRequestInfo> ParseClrExceptions(TraceLog dataFile, Dictionary <Guid, IisRequest> iisRequests, out int failedRequestsWithClrExceptions, out List <ExceptionSummaryByName> exceptionSummary) { List <IisRequestInfo> listRequestsFailed = new List <IisRequestInfo>(); List <ExceptionDetails> allExceptions = new List <ExceptionDetails>(); failedRequestsWithClrExceptions = 0; var dispatcher = dataFile.Events.GetSource(); var clr = new ClrTraceEventParser(dispatcher); clr.ExceptionStart += delegate(ExceptionTraceData data) { //if (data.ProcessID == g_processId) { ExceptionDetails ex = new ExceptionDetails(); if (data.ExceptionMessage == "NULL") { ex.ExceptionMessage = "''"; } else { ex.ExceptionMessage = data.ExceptionMessage; } ex.ExceptionType = data.ExceptionType; ex.ThreadId = data.ThreadID; ex.ProcessId = data.ProcessID; ex.TimeStampRelativeMSec = data.TimeStampRelativeMSec; ex.ProcessName = data.ProcessName; if (ex.StackTrace == null) { ex.StackTrace = new List <string>(); } var cs = data.CallStack(); var stackTrace = ""; if (cs != null) { while (cs != null) { stackTrace = $"{cs.CodeAddress.ModuleName}!{cs.CodeAddress.FullMethodName}"; cs = cs.Caller; if (!string.IsNullOrWhiteSpace(stackTrace)) { if (stackTrace.Contains(".")) { if (stackTrace.IndexOf('(') > 1) { ex.StackTrace.Add(stackTrace.Substring(0, stackTrace.IndexOf('('))); } else { ex.StackTrace.Add(stackTrace); } } } } } ex.StackTraceHash = string.Join(",", ex.StackTrace).GetHashCode(); if (ex.ExceptionMessage.Length > 5) { allExceptions.Add(ex); } } }; dispatcher.Process(); foreach (var request in iisRequests.Values.Where(x => x.FailureDetails != null)) { IisRequestInfo iisRequest = new IisRequestInfo(); iisRequest.Method = request.Method; iisRequest.ContextId = request.ContextId; iisRequest.slowestPipelineEvent = IisRequestParser.GetSlowestEvent(request); iisRequest.totalTimeSpent = request.EndTimeRelativeMSec - request.StartTimeRelativeMSec; iisRequest.requestPath = request.Path; iisRequest.csBytes = (request.BytesReceived == 0) ? "-" : request.BytesReceived.ToString(); iisRequest.scBytes = (request.BytesSent == 0) ? "-" : request.BytesSent.ToString(); iisRequest.statusCode = (request.StatusCode == 0) ? "-" : request.StatusCode.ToString(); iisRequest.SubStatusCode = request.SubStatusCode.ToString(); iisRequest.FailureDetails = request.FailureDetails; iisRequest.FailureDetails.ExceptionDetails = FindExceptionForThisRequest(request, allExceptions); if (iisRequest.FailureDetails.ExceptionDetails.Count > 0) { failedRequestsWithClrExceptions++; } listRequestsFailed.Add(iisRequest); } var groupedExceptions = from c in allExceptions group c by new { c.ProcessName, c.ExceptionType, c.ExceptionMessage, c.StackTraceHash } into g select new ExceptionSummary() { ProcessName = g.Key.ProcessName, ExceptionType = g.Key.ExceptionType, ExceptionMessage = g.Key.ExceptionMessage, StackTraceHash = g.Key.StackTraceHash, Count = g.Count() }; // // This additional grouping is done to remove similar stacks // and take only top 10 stack traces. // var groupedExceptionsByName = from c in groupedExceptions group c by new { c.ProcessName, c.ExceptionType, c.ExceptionMessage, c.Count } into g select new ExceptionSummaryByName() { ProcessName = g.Key.ProcessName, ExceptionType = g.Key.ExceptionType, ExceptionMessage = g.Key.ExceptionMessage, Count = g.Key.Count, StackTraceHashes = g.Select(x => x.StackTraceHash).Take(10).ToList() }; var groupedExceptionsArray = groupedExceptionsByName.ToArray(); for (int i = 0; i < groupedExceptionsArray.Count(); i++) { groupedExceptionsArray[i].StackTrace = new List <StackSummary>(); foreach (var stackTraceHash in groupedExceptionsArray[i].StackTraceHashes) { StackSummary s = new StackSummary { StackTraceHash = stackTraceHash, StackTrace = allExceptions.Find(x => x.StackTraceHash == stackTraceHash).StackTrace }; groupedExceptionsArray[i].StackTrace.Add(s); } } exceptionSummary = groupedExceptionsArray.OrderByDescending(x => x.Count).ToList(); return(listRequestsFailed); }