Ejemplo n.º 1
0
        public static StackSource CPUStacks(
            this Microsoft.Diagnostics.Tracing.Etlx.TraceLog eventLog,
            Microsoft.Diagnostics.Tracing.Etlx.TraceProcess process = null,
            Predicate <TraceEvent> predicate = null)
        {
            Microsoft.Diagnostics.Tracing.Etlx.TraceEvents events;

            if (process == null)
            {
                events = eventLog.Events.Filter((x) => ((predicate == null) || predicate(x)) && x is SampledProfileTraceData && x.ProcessID != 0);
            }
            else
            {
                events = process.EventsInProcess.Filter((x) => ((predicate == null) || predicate(x)) && x is SampledProfileTraceData);
            }

            var traceStackSource = new TraceEventStackSource(events);

            traceStackSource.ShowUnknownAddresses = true;

            // Clone the samples so that the caller doesn't have to go back to the ETL file from here on.
            return(CopyStackSource.Clone(traceStackSource));
        }
Ejemplo n.º 2
0
        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);
        }
Ejemplo n.º 3
0
        /// <summary>
        /// Reads trace and prints managed stacks
        /// </summary>
        /// <param name="console"></param>
        /// <param name="traceFile"></param>
        /// <returns>Returns 0 for success and 1 for failure</returns>
        /// <remarks>This code is adopted from josalem code https://github.com/josalem/DotStack </remarks>
        public static int Analyze(IConsole console, FileInfo traceFile)
        {
            if (string.IsNullOrEmpty(traceFile.FullName))
            {
                Console.ForegroundColor = ConsoleColor.Red;
                console.Error.WriteLine("-f [process-id] Process ID is required.");
                Console.ResetColor();
                return(1);
            }

            Console.WriteLine("[Trace analysis started...]\n");

            // Both the namespaces have TraceLog, here we use Microsoft.Diagnostics.Tracing.Etlx.TraceLog;
            // The following line creates a etlx file and then does analysis using that.
            string tempEtlxFilename = TraceLog.CreateFromEventPipeDataFile(traceFile.FullName);

            using (var symbolReader = new SymbolReader(System.IO.TextWriter.Null)
            {
                SymbolPath = SymbolPath.MicrosoftSymbolServerPath
            })

                using (var eventLog = new TraceLog(tempEtlxFilename))
                {
                    var stackSource = new MutableTraceEventStackSource(eventLog)
                    {
                        OnlyManagedCodeStacks = true
                    };

                    var computer = new SampleProfilerThreadTimeComputer(eventLog, symbolReader);
                    computer.GenerateThreadTimeStacks(stackSource);

                    var samplesForThread = new Dictionary <string, List <StackSourceSample> >();

                    stackSource.ForEach((sample) =>
                    {
                        var stackIndex = sample.StackIndex;
                        while (!stackSource.GetFrameName(stackSource.GetFrameIndex(stackIndex), false).StartsWith("Thread ("))
                        {
                            stackIndex = stackSource.GetCallerIndex(stackIndex);
                        }

                        var threadName = stackSource.GetFrameName(stackSource.GetFrameIndex(stackIndex), false);
                        if (samplesForThread.TryGetValue(threadName, out var samples))
                        {
                            samples.Add(sample);
                        }
                        else
                        {
                            samplesForThread[threadName] = new List <StackSourceSample>()
                            {
                                sample
                            };
                        }
                    });

                    foreach (var(threadName, samples) in samplesForThread)
                    {
                        PrintStack(threadName, samples[0], stackSource);
                    }
                }

            Console.WriteLine("\n[Trace analysis completed...]");
            return(0);
        }
Ejemplo n.º 4
0
        public static void ToHtml(TextWriter writer, List <TraceProcess> perProc, string fileName, string title, ReportType type, bool justBody = false, bool doServerGCReport = false, RuntimeLoaderStatsData runtimeOpsStats = null, Microsoft.Diagnostics.Tracing.Etlx.TraceLog traceLog = null)
        {
            if (!justBody)
            {
                writer.WriteLine("<html>");
                writer.WriteLine("<head>");
                writer.WriteLine("<title>{0}</title>", Path.GetFileNameWithoutExtension(fileName));
                writer.WriteLine("<meta charset=\"UTF-8\"/>");
                writer.WriteLine("<meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\"/>");
                writer.WriteLine("</head>");
                writer.WriteLine("<body>");
            }
            writer.WriteLine("<H2>{0}</H2>", title);
            List <TraceProcess> sortedProcs = perProc;

            if (type == ReportType.JIT)
            {
                sortedProcs.Sort((TraceProcess p1, TraceProcess p2) => { return(-p1.LoadedDotNetRuntime().JIT.Stats().TotalCpuTimeMSec.CompareTo(p2.LoadedDotNetRuntime().JIT.Stats().TotalCpuTimeMSec)); });
            }
            else if (type == ReportType.GC)
            {
                sortedProcs.Sort((TraceProcess p1, TraceProcess p2) => { return(-p1.LoadedDotNetRuntime().GC.Stats().MaxSizePeakMB.CompareTo(p2.LoadedDotNetRuntime().GC.Stats().MaxSizePeakMB)); });
            }
            else if (type == ReportType.RuntimeLoader)
            {
                sortedProcs.Sort((TraceProcess p1, TraceProcess p2) => { return(-RuntimeLoaderStats.TotalCPUMSec(p1, runtimeOpsStats).CompareTo(RuntimeLoaderStats.TotalCPUMSec(p2, runtimeOpsStats))); });
            }
            else if (type == ReportType.FileVersion)
            {
                sortedProcs.Sort((TraceProcess p1, TraceProcess p2) => { return(string.Compare(p1.Name, p2.Name)); });
            }

            int count = sortedProcs.Count;

            if (count > 1)
            {
                writer.WriteLine("<UL>");
                foreach (var data in sortedProcs)
                {
                    var mang = data.LoadedDotNetRuntime();

                    if (mang == null)
                    {
                        continue;
                    }

                    if (type == ReportType.JIT && !mang.JIT.Stats().Interesting)
                    {
                        continue;
                    }

                    if (type == ReportType.RuntimeLoader && !RuntimeLoaderStats.IsInteresting(data, runtimeOpsStats))
                    {
                        continue;
                    }

                    var id = Shorten(data.CommandLine);
                    if (string.IsNullOrEmpty(id))
                    {
                        id = data.Name;
                    }

                    writer.WriteLine("<LI><A HREF=\"#Stats_{0}\">Process {0,5}: {1}</A></LI>", data.ProcessID, XmlUtilities.XmlEscape(id));
                }
                writer.WriteLine("</UL>");
                writer.WriteLine("<HR/><HR/><BR/><BR/>");
            }
            foreach (TraceProcess stats in sortedProcs)
            {
                var mang = stats.LoadedDotNetRuntime();
                if (mang == null)
                {
                    continue;
                }

                if (type == ReportType.GC)
                {
                    Stats.GcStats.ToHtml(writer, stats, mang, fileName, doServerGCReport);
                }

                if (type == ReportType.JIT && mang.JIT.Stats().Interesting)
                {
                    Stats.JitStats.ToHtml(writer, stats, mang, fileName);
                }

                if (type == ReportType.RuntimeLoader && RuntimeLoaderStats.IsInteresting(stats, runtimeOpsStats))
                {
                    Stats.RuntimeLoaderStats.ToHtml(writer, stats, fileName, runtimeOpsStats);
                }

                if (type == ReportType.FileVersion)
                {
                    Stats.FileVersionInformation.ToHtml(writer, stats, traceLog);
                }
            }

            writer.WriteLine("<BR/><BR/><BR/><BR/><BR/><BR/><BR/><BR/><BR/><BR/>");
            if (!justBody)
            {
                writer.WriteLine("</body>");
                writer.WriteLine("</html>");
            }
        }