/// <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;
        }
Example #2
0
        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);
        }
Example #3
0
        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);
        }
Example #4
0
        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);
        }
Example #5
0
        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");
        }
Example #6
0
        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()
                }
            });
        }
Example #7
0
        /// <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);
                }
            }
        }
Example #8
0
 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);
        }
Example #10
0
        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
            }
        }
Example #11
0
 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);
                }
            }
        }
Example #13
0
        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);
        }