示例#1
0
 private static void Main()
 {
     var session = new TraceEventSession("CHROMETRACE");
     var source = new ETWTraceEventSource("CHROMETRACE", TraceEventSourceType.Session);
     session.EnableProvider(ChromeEventParser.ProviderGuid, TraceEventLevel.Informational);
     using (new ChromeEventParser(source))
     {
         source.Process();
     }
 }
        internal void ProcessEtlFile()
        {
            // Open the file
            using (var source = new ETWTraceEventSource(etlFilePath))
            {
                // DynamicTraceEventParser knows about EventSourceEvents
                var parser = new DynamicTraceEventParser(source);

                // Set up a callback for every event that prints the event
                parser.All += traceEventHandler;

                // Read the file, processing the callbacks.
                source.Process();

                // Close the file.
            }
        }
示例#3
0
        private void ProcessEtwSource(ISourceDataProcessor <QuicEvent, object, Guid> dataProcessor, IProgress <int> progress, CancellationToken cancellationToken)
        {
            using var source = new ETWTraceEventSource(filePaths);
            long StartTime = 0;

            source.AllEvents += (evt) =>
            {
                if (cancellationToken.IsCancellationRequested)
                {
                    source.StopProcessing();
                    return;
                }

                if (info == null && evt.TimeStamp.Ticks != 0 && !IsKnownSynthEvent(evt))
                {
                    StartTime = evt.TimeStamp.Ticks;

                    var firstEventNano = (evt.TimeStamp.Ticks - source.SessionStartTime.Ticks) * 100;
                    var lastEventNano  = (source.SessionEndTime.Ticks - source.SessionStartTime.Ticks) * 100;
                    info = new DataSourceInfo(firstEventNano, lastEventNano, evt.TimeStamp.ToUniversalTime());
                }
                else if (evt.ProviderGuid == QuicEvent.ProviderGuid)
                {
                    try
                    {
                        var quicEvent = QuicEtwEvent.TryCreate(evt, new Timestamp((evt.TimeStamp.Ticks - StartTime) * 100));
                        if (quicEvent != null)
                        {
                            dataProcessor.ProcessDataElement(quicEvent, this, cancellationToken);
                        }
                    }
                    catch
                    {
                    }
                }

                progress.Report((int)(evt.TimeStampRelativeMSec / source.SessionEndTimeRelativeMSec * 100));
            };

            source.Process();

            if (info == null)
            {
                info = new DataSourceInfo(0, (source.SessionEndTime.Ticks - source.SessionStartTime.Ticks) * 100, source.SessionStartTime.ToUniversalTime());
            }
        }
示例#4
0
        /// <summary>
        /// Starts a new ETW session, if it's not yet started.
        /// </summary>
        /// <exception cref="InvalidOperationException">The session is already started.</exception>
        public void Start()
        {
            if (this.isStarted)
            {
                throw new InvalidOperationException("ETW session is already started.");
            }

            // Stop the native ETW session, because it can be started by the previous application instance.
            this.Stop();

            ManualResetEvent startedEvent = new ManualResetEvent(false);

            Task.Factory.StartNew(
                () =>
            {
                // Create a new real-time session.
                this.eventSession = new TraceEventSession(this.name, fileName: null);
                this.eventSession.StopOnDispose = true;
                this.eventSession.BufferSizeMB  = this.bufferSizeMB;
                this.eventSession.EnableProvider(LazyCopyEventParser.ProviderGuid);

                using (this.eventSource = new ETWTraceEventSource(this.name, TraceEventSourceType.Session))
                {
                    LazyCopyEventParser parser = new LazyCopyEventParser(this.eventSource);
                    parser.FileAccessed       += this.NotifyFileAccessed;
                    parser.FileFetched        += this.NotifyFileFetched;
                    parser.FileNotFetched     += this.NotifyFileNotFetched;

                    try
                    {
                        startedEvent.Set();
                        this.eventSource.Process();
                    }
                    finally
                    {
                        parser.FileAccessed   -= this.NotifyFileAccessed;
                        parser.FileFetched    -= this.NotifyFileFetched;
                        parser.FileNotFetched -= this.NotifyFileNotFetched;
                    }
                }
            },
                TaskCreationOptions.LongRunning);

            startedEvent.WaitOne();
            this.isStarted = true;
        }
示例#5
0
        public void CreateSession(string fileName = null, bool setupSource = true)
        {
            if (fileName == null)
            {
                session = new TraceEventSession(sessionName);
            }
            else
            {
                session = new TraceEventSession(sessionName, fileName);
            }

            if (setupSource)
            {
                source = session.Source;
                SetupSource();
            }
        }
示例#6
0
        /// <summary>
        /// The analyze events data.
        /// </summary>
        public void AnalyzeEventsData()
        {
#if NET46
            using (var source = new ETWTraceEventSource(this.perfDataFileName))
            {
                // Open the file
                var parser = new DynamicTraceEventParser(source);
                parser.All += delegate(TraceEvent data)
                {
                    try
                    {
                        if (data.ProviderName.Equals("TestPlatform") && !data.EventName.Equals("ManifestData"))
                        {
                            Console.WriteLine("Received Event : {0}", data.ToString());
                            var key = data.ProcessID + "_" + data.ThreadID.ToString() + "_" + data.TaskName;

                            if (!testPlatformTaskMap.ContainsKey(key))
                            {
                                var list = new List <TestPlatformTask> {
                                    CreateTestPlatformTask(data)
                                };
                                testPlatformTaskMap.Add(key, list);
                            }
                            else
                            {
                                if (data.Opcode == TraceEventOpcode.Start)
                                {
                                    testPlatformTaskMap[key].Add(CreateTestPlatformTask(data));
                                }
                                else
                                {
                                    UpdateTask(testPlatformTaskMap[key].Last(), data);
                                }
                            }
                        }
                    }
                    catch (Exception ex)
                    {
                        Console.WriteLine(ex.ToString());
                    }
                };
                source.Process(); // Read the file, processing the callbacks.
            }
#endif
        }
示例#7
0
        static void Main(string[] args)
        {
            // create a new real-time ETW trace session
            using (var session = new TraceEventSession(SessionName)) {
                // enable IIS ETW provider and set up a new trace source on it
                session.EnableProvider(IISLogTraceEventParser.ProviderName, TraceEventLevel.Verbose);

                using (var traceSource = new ETWTraceEventSource(SessionName, TraceEventSourceType.Session)) {
                    Console.WriteLine("Session started, listening for events...");
                    var parser = new IISLogTraceEventParser(traceSource);
                    parser.IISLog += OnIISRequest;

                    traceSource.Process();
                    Console.ReadLine();
                    traceSource.StopProcessing();
                }
            }
        }
        static void Main(string[] args)
        {
            // create a new real-time ETW trace session
              using ( var session = new TraceEventSession(SessionName) ) {
            // enable IIS ETW provider and set up a new trace source on it
            session.EnableProvider(IISLogTraceEventParser.ProviderName, TraceEventLevel.Verbose);

            using ( var traceSource = new ETWTraceEventSource(SessionName, TraceEventSourceType.Session) ) {
              Console.WriteLine("Session started, listening for events...");
              var parser = new IISLogTraceEventParser(traceSource);
              parser.IISLog += OnIISRequest;

              traceSource.Process();
              Console.ReadLine();
              traceSource.StopProcessing();
            }
              }
        }
        /// <summary>
        /// Processing the data in a particular file.
        /// </summary>
        private static void DataProcessing(string dataFileName)
        {
            Out.WriteLine("Opening the output file and printing the results.");
            Out.WriteLine("The list is filtered quite a bit...");
            using (var source = new ETWTraceEventSource(dataFileName))
            {
                if (source.EventsLost != 0)
                {
                    Out.WriteLine("WARNING: there were {0} lost events", source.EventsLost);
                }

                // Set up callbacks to
                source.Clr.All    += Print;
                source.Kernel.All += Print;

                // When you merge a file, some 'symbol' events are injected into the trace.
                // To avoid these showing up as 'unknown' add the parser for these.  This
                // also shows how you hook up a TraceEventParser that is not support by
                // properties on the source itself (like CLR, and kernel)
                var symbolParser = new SymbolTraceEventParser(source);
                symbolParser.All += Print;

#if DEBUG
                // The callback above will only be called for events the parser recognizes (in the case of Kernel and CLR parsers)
                // It is sometimes useful to see the other events that are not otherwise being handled.  The source knows about these and you
                // can ask the source to send them to you like this.
                source.UnhandledEvents += delegate(TraceEvent data)
                {
                    // To avoid 'rundown' events that happen in the beginning and end of the trace filter out things during those times
                    if (data.TimeStampRelativeMSec < 1000 || 9000 < data.TimeStampRelativeMSec)
                    {
                        return;
                    }

                    Out.WriteLine("GOT UNHANDLED EVENT: " + data.Dump());
                };
#endif

                // go into a loop processing events can calling the callbacks.  This will return when the all the events
                // In the file are processed, or the StopProcessing() call is made.
                source.Process();
                Out.WriteLine("Done Processing.");
            }
        }
        public void Writing_Message_To_Etw() {
            var fpath = Path.Combine(Path.GetTempPath(), "_etwnlogtest.etl");
            using (var session = new TraceEventSession("SimpleMonitorSession", fpath)) {
                //var eventSourceGuid = TraceEventProviders.GetEventSourceGuidFromName("MyEventSource");
                var eventSourceGuid = TraceEventProviders.GetEventSourceGuidFromName("LowLevelDesign-NLogEtwSource");
                session.EnableProvider(eventSourceGuid);

                // send events to session
                var logger = LogManager.GetLogger("A");
                logger.Debug("test-debug");
                logger.Info("test-info");
                logger.Warn("test-warn");
                logger.Error("test-error");
                logger.Fatal("test-fatal");

                Thread.Sleep(5000);
            }

            var collectedEvents = new List<ExtendedEtwEvent>(5);
            using (var source = new ETWTraceEventSource(fpath)) {
                var parser = new DynamicTraceEventParser(source);
                parser.All += delegate(TraceEvent data) {
                    collectedEvents.Add(new ExtendedEtwEvent {
                        EventId = (int)data.ID,
                        Level = data.Level,
                        LoggerName = (String)data.PayloadByName("LoggerName"),
                        Message = (String)data.PayloadByName("Message")
                    });
                };
                source.Process();
            }
            File.Delete(fpath);

            // assert collected events
            var expectedEvents = new ExtendedEtwEvent[] {
                new ExtendedEtwEvent { EventId = 1, LoggerName = "A", Level = TraceEventLevel.Verbose, Message = "DEBUG|A|test-debug" },
                new ExtendedEtwEvent { EventId = 2, LoggerName = "A", Level = TraceEventLevel.Informational, Message = "INFO|A|test-info" },
                new ExtendedEtwEvent { EventId = 3, LoggerName = "A", Level = TraceEventLevel.Warning, Message = "WARN|A|test-warn" },
                new ExtendedEtwEvent { EventId = 4, LoggerName = "A", Level = TraceEventLevel.Error, Message = "ERROR|A|test-error" },
                new ExtendedEtwEvent { EventId = 5, LoggerName = "A", Level = TraceEventLevel.Critical, Message = "FATAL|A|test-fatal" }
            };
            Assert.Equal(collectedEvents, expectedEvents);
        }
示例#11
0
        private bool VerifyManifestAndRemoveFile(string fileName)
        {
            Assert.True(File.Exists(fileName));

            ETWTraceEventSource source = new ETWTraceEventSource(fileName);

            var sawManifestData = false;

            source.Dynamic.All += (eventData) =>
            {
                if (eventData.ProviderName.Equals("SimpleEventSource") && eventData.EventName.Equals("ManifestData"))
                {
                    sawManifestData = true;
                }
            };
            source.Process();
            //File.Delete(fileName);
            return(sawManifestData);
        }
        public void Start()
        {
            if (this.session != null)
            {
                throw new InvalidOperationException("The session is already started.");
            }

            CloseExistingSession(this.name);
            this.session = new TraceEventSession(this.name, null);
            this.session.StopOnDispose = true;
            this.session.EnableProvider(KernelProcessProviderId, TraceEventLevel.Informational, ulong.MaxValue, 0x10);
            this.eventSource = new ETWTraceEventSource(this.name, TraceEventSourceType.Session);
            this.parser      = new RegisteredTraceEventParser(this.eventSource);
            this.parser.All += this.OnEventRead;

            // Process() blocks until the session is shut down, so we'll run this on another thread.
            this.cts         = new CancellationTokenSource();
            this.processTask = Task.Factory.StartNew(() => this.eventSource.Process(), TaskCreationOptions.LongRunning);
        }
示例#13
0
        private static void Main(string[] args)
        {
            string sessionName = "mySession";
            using (MyEventSource source = new MyEventSource())
            using (TraceEventSession session = new TraceEventSession(sessionName, null)) // the null second parameter means 'real time session'
            using (ETWTraceEventSource eventSource = new ETWTraceEventSource(sessionName, TraceEventSourceType.Session))
            {
                DynamicTraceEventParser parser = new DynamicTraceEventParser(eventSource);
                parser.All += delegate(TraceEvent data)
                {
                    Console.WriteLine("Event name:{0}. Payload:{1}.", data.EventName, data.PayloadValue(0));
                };

                session.EnableProvider(source.Guid);
                source.String("Hello world");
                source.Int(123);
                eventSource.Process();
            }
        }
        /// <summary>
        /// Start listening and processing events.
        /// </summary>
        internal void StartProcessing()
        {
            StopProcessing();

            stopProcessing = false;

            // Create new trace session.
            traceEventSession = new TraceEventSession(TraceEventSessionName, null);
            traceEventSession.StopOnDispose = true;

            // Open a ETW event source for processing. Provide the name of real time sessing to open.
            traceEventSource = new ETWTraceEventSource(TraceEventSessionName, TraceEventSourceType.Session);

            DynamicTraceEventParser parser = new DynamicTraceEventParser(traceEventSource);

            parser.All += (traceEvent) =>
            {
                if (stopProcessing)
                {
                    traceEventSource.StopProcessing();
                }

                traceEventHandler(traceEvent);
            };

            // Add an additional provider represented by providerGuid
            traceEventSession.EnableProvider(providerGuid);

            // Enqueue on the thread pool's global queue.
            // Processing never completes by itself, but only is Close() method is called.
            eventProcessingTask = Task.Factory.StartNew(() =>
            {
                try
                {
                    traceEventSource.Process();
                }
                catch (NullReferenceException)
                {
                    // There is a bug in ETWTraceEventSource it can throw NullReferenceException exception!
                }
            });
        }
示例#15
0
        private static void Main(string[] args)
        {
            string sessionName = "mySession";

            using (MyEventSource source = new MyEventSource())
                using (TraceEventSession session = new TraceEventSession(sessionName, null)) // the null second parameter means 'real time session'
                    using (ETWTraceEventSource eventSource = new ETWTraceEventSource(sessionName, TraceEventSourceType.Session))
                    {
                        DynamicTraceEventParser parser = new DynamicTraceEventParser(eventSource);
                        parser.All += delegate(TraceEvent data)
                        {
                            Console.WriteLine("Event name:{0}. Payload:{1}.", data.EventName, data.PayloadValue(0));
                        };

                        session.EnableProvider(source.Guid);
                        source.String("Hello world");
                        source.Int(123);
                        eventSource.Process();
                    }
        }
        private void CreateEventSourceOnBufferFile()
        {
            String oldFile = SwitchBufferFiles();

            Trace.WriteLine(String.Format("Starting processing on: {0}", oldFile));
            this.eventSource = new ETWTraceEventSource(
                oldFile, TraceEventSourceType.FileOnly
                );

            var sortedProvs = eventProviders.OrderBy(x => x.IsKernelProvider ? 0 : 1);

            foreach (var provider in sortedProvs)
            {
                provider.RegisterParser(this.eventSource);
            }

            this.observableStream = JoinStreams(sortedProvs);
            this.sourceProcessor.Start(this.observableStream);
            new Task(Process).Start();
        }
示例#17
0
        private static EtwPerformanceMetricEvaluationContext GetEtwReader(
            string fileName,
            string sessionName,
            IEnumerable <PerformanceTestMessage> performanceTestMessages)
        {
            using (var source = new ETWTraceEventSource(fileName))
            {
                if (source.EventsLost > 0)
                {
                    throw new Exception($"Events were lost in trace '{fileName}'");
                }

                using (var context = new EtwPerformanceMetricEvaluationContext(
                           fileName, source, performanceTestMessages, sessionName))
                {
                    source.Process();
                    return(context);
                }
            }
        }
示例#18
0
        public void Start()
        {
            using (var session = new TraceEventSession("netric"))
            {
                session.EnableProvider(NetricInterceptWebRequestTraceEventParser.ProviderName);
                session.EnableProvider(NetricInterceptClrTraceEventParser.ProviderName);

                using (var source = new ETWTraceEventSource("netric", TraceEventSourceType.Session))
                {
                    var requestTraceEventParser = new NetricInterceptWebRequestTraceEventParser(source);
                    requestTraceEventParser.OnBegin+= x => _receiverActor.Tell(new EtwEventProcessingActor.RequestBegin(x));
                    requestTraceEventParser.OnEnd += x => _receiverActor.Tell(new EtwEventProcessingActor.RequestEnd(x));

                    var clrTraceEventParser = new NetricInterceptClrTraceEventParser(source);
                    clrTraceEventParser.OnEnter += x => _receiverActor.Tell(new EtwEventProcessingActor.MethodEnter(x));
                    clrTraceEventParser.OnLeave += x => _receiverActor.Tell(new EtwEventProcessingActor.MethodLeave(x));
                    source.Process();
                }
            }
        }
        public IPerformanceMetricReader GetReader()
        {
            using (var source = new ETWTraceEventSource(_etlPath))
            {
                if (source.EventsLost > 0)
                    throw new Exception($"Events were lost in trace '{_etlPath}'");

                var evaluationContext = new EtwPerformanceMetricEvaluationContext(_etlPath, source, _tests, _project.RunId);
                try
                {
                    source.Process();
                    return evaluationContext;
                }
                catch
                {
                    evaluationContext.Dispose();
                    throw;
                }
            }
        }
示例#20
0
        public void Stop()
        {
            using (var rundownSession = new TraceEventSession(sessionName + "Rundown", "data.clrRundown.etl"))
            {
                rundownSession.EnableProvider(ClrRundownTraceEventParser.ProviderGuid, TraceEventLevel.Verbose,
                                              (ulong)ClrRundownTraceEventParser.Keywords.Default);
                // Poll until 2 second goes by without growth.
                for (var prevLength = new FileInfo("data.clrRundown.etl").Length;;)
                {
                    Thread.Sleep(2000);
                    var newLength = new FileInfo("data.clrRundown.etl").Length;
                    if (newLength == prevLength)
                    {
                        break;
                    }
                    prevLength = newLength;
                }
            }

            // TODO: Currenty not aware of any more sophisticated control, when hosting sub-process it will wait for timeout without new events after sub-process ends
            //Thread.Sleep(4000);
            stopped = true;
            session?.Dispose();
            kernelSession?.Dispose();
            TraceEventSession.MergeInPlace("data.etl", TextWriter.Null);

            //var traceLog = TraceLog.OpenOrConvert("data.etl");
            //var simpleTraceLogProcess = traceLog.Processes.LastProcessWithID(Process.GetCurrentProcess().Id);
            //foreach (var data in simpleTraceLogProcess.EventsInProcess)
            //{
            //}

            using (var source = new ETWTraceEventSource("data.etl"))
            {
                source.Clr.GCHeapStats       += ClrOnGcHeapStats;
                source.Clr.GCStart           += ClrOnGcStart;
                source.Clr.GCStop            += ClrOnGcStop;
                source.Clr.GCGenerationRange += ClrOnGcGenerationRange;
                source.Process();
            }
        }
        public void Writing_Message_To_Etw()
        {
            var resetEvent = new ManualResetEvent(false);
            var fpath = Path.Combine(Path.GetTempPath(), "_etwnlogtest.etl");
            using (var session = new TraceEventSession("SimpleMonitorSession", fpath)) {
                session.EnableProvider(providerId);

                // send events to session
                var logger = LogManager.GetLogger("A");
                logger.Debug("test-debug");
                logger.Info("test-info");
                logger.Warn("test-warn");
                logger.Error("test-error");
                logger.Fatal("test-fatal");
            }

            var collectedEvents = new List<SimpleEtwEvent>(5);
            using (var source = new ETWTraceEventSource(fpath)) {
                source.UnhandledEvents += delegate(TraceEvent data) {
                                                                        collectedEvents.Add(new SimpleEtwEvent { Level = data.Level, Message = data.FormattedMessage });
                                                                        if (collectedEvents.Count == 5)
                                                                        {
                                                                            resetEvent.Set();
                                                                        }
                };
                source.Process();
            }
            File.Delete(fpath);

            // assert collected events
            var expectedEvents = new SimpleEtwEvent[] {
                new SimpleEtwEvent { Level = TraceEventLevel.Verbose, Message = "DEBUG|A|test-debug" },
                new SimpleEtwEvent { Level = TraceEventLevel.Informational, Message = "INFO|A|test-info" },
                new SimpleEtwEvent { Level = TraceEventLevel.Warning, Message = "WARN|A|test-warn" },
                new SimpleEtwEvent { Level = TraceEventLevel.Error, Message = "ERROR|A|test-error" },
                new SimpleEtwEvent { Level = TraceEventLevel.Critical, Message = "FATAL|A|test-fatal" }
            };
            resetEvent.WaitOne(20000);
            Assert.Equal(expectedEvents.Length, collectedEvents.Count);
            Assert.Equal(expectedEvents, collectedEvents);
        }
        /// <summary>
        /// Generate the PerfEventsData from the info provided to the ctor.
        /// </summary>
        /// <returns>A new instance of the AggregateEventsData class.</returns>
        public AggregateEventsData Generate()
        {
            using (var eventSource = new ETWTraceEventSource(m_etlFile))
            {
                if (eventSource.EventsLost > 0)
                    Console.WriteLine("WARNING: {0} events were lost during capture.", eventSource.EventsLost);

                m_aed = new AggregateEventsData(m_testName, Platform.Windows, eventSource.PointerSize == 8 ? Architecture.Amd64 : Architecture.X86);

                ParseClrTraceEvents(eventSource);
                ParseKernelTraceEvents(eventSource);

                // process the stream of events
                eventSource.Process();
            }

            if (!m_processFound)
                throw new ArgumentException(string.Format("No data was found for process named {0}.  Please ensure the name of the process is correct.", m_process));

            return m_aed;
        }
示例#23
0
        /// <summary>
        /// Creates the .NET CAP Report
        /// </summary>
        /// <param name="etlFile"></param>
        /// <returns></returns>
        public static ClrCap.CAPAnalysis CreateGCCap(string etlFile)
        {
            using (ETWTraceEventSource source = new ETWTraceEventSource(etlFile, TraceEventSourceType.MergeAll))
            {
                using (ETWTraceEventModelSource model = new ETWTraceEventModelSource(source))
                {
                    model.DisableAll().EnableGC();

                    ClrCap.CAPAnalysis report = new ClrCap.CAPAnalysis();

                    SetupCapCollectors(model.Source, report);
                    model.Process();
                    UpdateCommonInfo(etlFile, model.Source, report);

                    // generate the report
                    ClrCap.CAP.GenerateGCCAPReport(model.Processes, report);

                    return(report);
                }
            }
        }
示例#24
0
        private void SetupListeners(ETWTraceEventSource source)
        {
            // register for high and low keyword
            // if both are set, each allocation will trigger an event (beware performance issues...)
            source.Clr.GCSampledObjectAllocation += OnSampleObjectAllocation;

            // required to receive the mapping between type ID (received in GCSampledObjectAllocation)
            // and their name (received in TypeBulkType)
            source.Clr.TypeBulkType += OnTypeBulkType;

            // messages to get callstacks
            // the correlation seems to be as "simple" as taking the last event on the same thread
            source.Clr.ClrStackWalk += OnClrStackWalk;

            // needed to get JITed method details
            source.Clr.MethodLoadVerbose      += OnMethodDetails;
            source.Clr.MethodDCStartVerboseV2 += OnMethodDetails;

            // get notified when a module is load to map the corresponding symbols
            source.Kernel.ImageLoad += OnImageLoad;
        }
 /// <summary>
 /// Enable the Kernel provider and listening to the provider for ProcessStartGroup event,
 /// which is published by the TraceEvent library. ProcessStartGroup events are used to
 /// calculate the ProcessID->ProcessName mapping, which will be used in the UI displaying.
 /// However, this mechanism is not supported on XP/2003, and we cannot receive ProcessStartGroup
 /// events on XP/2003.
 /// </summary>
 public void EnableKernelSession()
 {
     if (m_kernelProcessTraceThread == null)
     {
         m_kernelSession = new TraceEventSession(KernelTraceEventParser.KernelSessionName, null);
         try
         {
             m_kernelSession.EnableKernelProvider(KernelTraceEventParser.Keywords.Process);
         }
         catch (UnauthorizedAccessException)
         {
             MessageBox.Show(Resource.ResourceManager.GetString("Err_UnauthorizedAccess"));
             Environment.Exit(0);
         }
         m_kernelSource = new ETWTraceEventSource(KernelTraceEventParser.KernelSessionName, TraceEventSourceType.Session);
         m_kernelSource.Kernel.ProcessStartGroup += AcceptKernelProcessStartEvent;
         m_kernelProcessTraceThread      = new Thread(KernelProcessTraceMethod);
         m_kernelProcessTraceThread.Name = "KernelProcessTrace";
         m_kernelProcessTraceThread.Start();
     }
 }
示例#26
0
        public IterationDataSource(string rootDir, string iterFolder)
        {
            string resultFile = Path.Combine(iterFolder, Constants.ResultJsonName);

            Debug.Assert(File.Exists(resultFile));
            IterationResult iter = JsonConvert.DeserializeObject <IterationResult>(File.ReadAllText(resultFile));

            string traceFile = Path.Combine(rootDir, iter.TracePathLocation);

            Debug.Assert(File.Exists(traceFile));

            // we have to unzip the trace that PerfView collected. Normally
            // PerfView does it, but since we're not using PerfView to read
            // the data we collected we're stuck doing it ourselves.
            string unzippedEtlPath = Path.Combine(iterFolder, Constants.UnzippedTraceName);

            Logger.LogVerbose($"Unzipping trace {traceFile}");
            ZipFile.ExtractToDirectory(traceFile, unzippedEtlPath);

            // traceFile has a .etl.zip extensions, and we're looking for a file with a .etl
            // extension in the unzipped ETL path.
            string strippedFilename = Path.GetFileNameWithoutExtension(traceFile);

            Logger.LogVerbose("Parsing ETW events");
            var source = new ETWTraceEventSource(Path.Combine(unzippedEtlPath, strippedFilename));

            m_source = source;
            source.NeedLoadedDotNetRuntimes();
            Logger.LogVerbose("Calculating GC stats");
            source.Process();

            Trace = source.Processes()
                    // TODO(segilles) this isn't quite right, it's possible (but HIGHLY unlikely)
                    // that we could collide pids.
                    .First(t => t.ProcessID == iter.Pid)
                    .LoadedDotNetRuntime();
            TraceLocation = iter.TracePathLocation;
            DurationMsec  = iter.DurationMsec;
            ExitCode      = iter.ExitCode;
        }
        public IPerformanceMetricReader GetReader()
        {
            using (var source = new ETWTraceEventSource(_etlPath))
            {
                if (source.EventsLost > 0)
                {
                    throw new Exception($"Events were lost in trace '{_etlPath}'");
                }

                var evaluationContext = new EtwPerformanceMetricEvaluationContext(_etlPath, source, _tests, _project.RunId);
                try
                {
                    source.Process();
                    return(evaluationContext);
                }
                catch
                {
                    evaluationContext.Dispose();
                    throw;
                }
            }
        }
示例#28
0
        public override void Dispose()
        {
            _session.Flush();
            Thread.Sleep(1010);     // Let it drain.
            _session.Dispose();     // This also will kill the real time thread

            if (_dataFileName != null)
            {
                using (var traceEventSource = new ETWTraceEventSource(_dataFileName))
                {
                    Debug.WriteLine("Processing data file " + Path.GetFullPath(_dataFileName));

                    // Parse all the events as as best we can, and also send unhandled events there as well.
                    traceEventSource.Registered.All  += OnEventHelper;
                    traceEventSource.Dynamic.All     += OnEventHelper;
                    traceEventSource.UnhandledEvents += OnEventHelper;
                    // Process all the events in the file.
                    traceEventSource.Process();
                    Debug.WriteLine("Done processing data file " + Path.GetFullPath(_dataFileName));
                }
            }
        }
示例#29
0
        private static void CallThis()
        {
            var sessionName = "ProcessMonitorSession";

            using (var session = new TraceEventSession(sessionName, null))
            {
                session.StopOnDispose = true;
                using (var source = new ETWTraceEventSource(sessionName, TraceEventSourceType.Session))
                {
                    var registeredParser = new RegisteredTraceEventParser(source);
                    registeredParser.All += delegate(TraceEvent data)
                    {
                        var taskName = data.TaskName;
                        if (taskName == "ProcessStart" || taskName == "ProcessStop")
                        {
                            string exe     = (string)data.PayloadByName("ImageName");
                            string exeName = Path.GetFileNameWithoutExtension(exe);

                            int processId = (int)data.PayloadByName("ProcessID");
                            if (taskName == "ProcessStart")
                            {
                                int parentProcessId = (int)data.PayloadByName("ParentProcessID");
                                // log:
                                //string.Format("{0:HH:mm:ss.fff}: {1,-12}: {2} ID: {3} ParentID: {4}", data.TimeStamp, taskName, exeName, processId, parentProcessId);
                            }
                            else
                            {
                                int  exitCode = (int)data.PayloadByName("ExitCode");
                                long cpuCycle = (long)data.PayloadByName("CPUCycleCount");
                                // log:
                                //string.Format("{0:HH:mm:ss.fff}: {1,-12}: {2} ID: {3} EXIT: {4} CPU Cycles: {5:n0}", data.TimeStamp, taskName, exeName, processId, exitCode, cpuCycle);
                            }
                        }
                    };

                    //var processProviderGuid = TraceEventSession.
                }
            }
        }
示例#30
0
        private static void WorkerTraceEvents(object sender, DoWorkEventArgs e)
        {
            try
            {
                if (TraceEventSession.IsElevated() != true)
                {
                    throw new InvalidOperationException(
                              "Collecting ETW trace events requires administrative privileges.");
                }

                if (TraceEventSession.GetActiveSessionNames().Contains(SessionName))
                {
                    Debug.WriteLine(
                        $"The session name '{SessionName}' is already in use, stopping existing and restart a new one.");
                    TraceEventSession.GetActiveSession(SessionName).Stop(true);
                }

                // An End-To-End ETW Tracing Example: EventSource and TraceEvent
                // https://blogs.msdn.microsoft.com/vancem/2012/12/20/an-end-to-end-etw-tracing-example-eventsource-and-traceevent/
                using (var traceEventSession = new TraceEventSession(SessionName))
                {
                    traceEventSession.StopOnDispose = true;
                    using (var traceEventSource = new ETWTraceEventSource(SessionName, TraceEventSourceType.Session))
                    {
                        traceEventSession.EnableProvider(OmaDmClient);
                        traceEventSession.EnableProvider(OmaDmClientProvider);

                        new RegisteredTraceEventParser(traceEventSource).All += (data =>
                                                                                 (sender as BackgroundWorker)?.ReportProgress(0, data.Clone()));
                        traceEventSource.Process();
                    }
                }
            }
            catch (Exception ex)
            {
                Debug.WriteLine($"Exception: {ex}");
            }
        }
        public void Dispose()
        {
            if (!this.disposed)
            {
                this.disposing = true;

                if (this.eventsLost > 0)
                {
                    this.logger.TraceEventServiceProcessEventsLost(this.sessionName, this.eventsLost);
                }

                // By disposing source we force this.source.Process() to exit and end workerTask
                // Note that source reference is not released rigth after Dispose() to avoid 'CallbackOnCollectedDelegate'exception
                // that might be thrown before Process() ends.
                this.source.Dispose();
                this.workerTask.Wait();
                this.session.Dispose();
                this.session = null;
                this.source = null;

                this.disposed = true;
            }
        }
        public void Dispose()
        {
            if (!this.disposed)
            {
                this.disposing = true;

                if (this.eventsLost > 0)
                {
                    this.logger.TraceEventServiceProcessEventsLost(this.sessionName, this.eventsLost);
                }

                // By disposing source we force this.source.Process() to exit and end workerTask
                // Note that source reference is not released rigth after Dispose() to avoid 'CallbackOnCollectedDelegate'exception
                // that might be thrown before Process() ends.
                this.source.Dispose();
                this.workerTask.Wait();
                this.session.Dispose();
                this.session = null;
                this.source  = null;

                this.disposed = true;
            }
        }
示例#33
0
        private void StartListening()
        {
            this.eventSinkThread = new Thread(() => {
                using (var session = new TraceEventSession("mo-session-01"))
                {
                    this.session = session;
                    using (var source = new ETWTraceEventSource("mo-session-01", TraceEventSourceType.Session))
                    {
                        var parser  = new DynamicTraceEventParser(source);
                        parser.All += (TraceEvent data) =>
                        {
                            var trace = TraceEventToTraceData(data);
                            model.AddTrace(trace);
                        };

                        session.EnableProvider(this.model.SelectedProvider);
                        source.Process();
                    }
                }
            });

            this.eventSinkThread.Start();
        }
        private void Initialize()
        {
            this.session = TraceEventUtil.CreateSession(this.sessionName);

            // Hook up the ETWTraceEventSource to the specified session
            this.source = new ETWTraceEventSource(this.sessionName, TraceEventSourceType.Session);

            this.manifestCache = new TraceEventManifestsCache(this.source.Dynamic);

            // get any previously cached manifest and update the schema cache
            this.UpdateCaches();

            // hook up to all incoming events and filter out manifests
            this.source.Dynamic.All += e => this.ProcessEvent(e);

            // listen to new manifests
            this.source.Dynamic.DynamicProviderAdded += m => this.OnManifestReceived(m);

            // We collect all the manifests and save/terminate process when done
            this.source.UnhandledEvents += e => this.ProcessUnhandledEvent(e);

            foreach (var eventSource in this.eventSources)
            {
                // Bind the provider (EventSource/EventListener) with the session
                TraceEventUtil.EnableProvider(
                    this.session,
                    eventSource.EventSourceId,
                    eventSource.Level,
                    eventSource.MatchAnyKeyword,
                    eventSource.Arguments,
                    eventSource.ProcessNamesToFilter);
            }

            // source.Process() is blocking so we need to launch it on a separate thread.
            this.workerTask = Task.Factory.StartNew(() => this.source.Process(), TaskCreationOptions.LongRunning).
                              ContinueWith(t => this.HandleProcessTaskFault(t));
        }
示例#35
0
    static int Main(string[] args)
    {
        if (args.Length != 2)
        {
            Console.WriteLine("Usage: EtlConverter.exe <input.etl> <output.log>");
            return(1);
        }

        var inputFile  = args[0];
        var outputFile = args[1];

        if (!File.Exists(inputFile))
        {
            Console.WriteLine("Input File {} does not exist", inputFile);
            return(2);
        }

        try {
            fs = new FileStream(outputFile, FileMode.Create);
        } catch (Exception e) {
            Console.WriteLine("Failed to open output file: {}", e);
            return(3);
        }

        using (var source = new ETWTraceEventSource(inputFile))
        {
            // setup the callbacks
            source.Dynamic.All += Print;

            // iterate over the file, calling the callbacks.
            Console.WriteLine("Processing...");
            source.Process();
            Console.WriteLine("Done!");
        }

        return(0);
    }
示例#36
0
        private static void RoundTwo(string[] args)
        {
            using (var netPerfFile = NetPerfFile.Create(args))
            {
                using (var etlFile = EtlFile.Create(args))
                {
                    Console.WriteLine("\tStart: Enable EventPipe.");
                    TraceControl.Enable(EventPipeGetConfig(EventPipeAndEtwEventSource.Log, EventPipeAndEtwEventSource.Keywords.EventPipeKeyword, netPerfFile.Path));
                    Console.WriteLine("\tEnd: Enable EventPipe.\n");

                    Console.WriteLine("\tStart: Enable ETW.");
                    TraceEventSession etwSession = EnableETW(EventPipeAndEtwEventSource.Log, EventPipeAndEtwEventSource.Keywords.EtwKeyword, etlFile.Path);
                    Console.WriteLine("\tEnd: Enable ETW.\n");

                    WriteAllEvents(EventPipeAndEtwEventSource.Log);

                    Console.WriteLine("\tStart: Disable EventPipe.");
                    TraceControl.Disable();
                    Console.WriteLine("\tEnd: Disable EventPipe.\n");

                    WriteAllEvents(EventPipeAndEtwEventSource.Log);

                    Console.WriteLine("\tStart: Disable ETW.");
                    DisableETW(etwSession);
                    Console.WriteLine("\tEnd: Disable ETW.\n");

                    Console.WriteLine("\tStart: Processing events from EventPipe file.");

                    EventResults eventPipeResults = new EventResults();
                    EventResults etwResults       = new EventResults();

                    using (var trace = new TraceLog(TraceLog.CreateFromEventPipeDataFile(netPerfFile.Path)).Events.GetSource())
                    {
                        trace.Dynamic.All += delegate(TraceEvent data)
                        {
                            eventPipeResults.AddEvent(data);
                        };

                        trace.Process();
                    }

                    // Validate EventPipe results.
                    eventPipeResults.Print("EventPipe Results:");
                    Assert.Equal("EventPipeEvent1Count", eventPipeResults.Event1Count, 1);
                    Assert.Equal("EventPipeEvent2Count", eventPipeResults.Event2Count, 0);
                    Assert.Equal("EventPipeEvent3Count", eventPipeResults.Event3Count, 1);

                    Console.WriteLine("\tEnd: Processing events from EventPipe file.\n");

                    Console.WriteLine("\tStart: Processing events from ETW file.");

                    using (var trace = new ETWTraceEventSource(etlFile.Path))
                    {
                        trace.Dynamic.All += delegate(TraceEvent data)
                        {
                            etwResults.AddEvent(data);
                        };

                        trace.Process();
                    }

                    // Validate ETW results.
                    etwResults.Print("ETW Results:");
                    Assert.Equal("EventPipeEvent1Count", etwResults.Event1Count, 0);
                    Assert.Equal("EventPipeEvent2Count", etwResults.Event2Count, 2);
                    Assert.Equal("EventPipeEvent3Count", etwResults.Event3Count, 2);

                    Console.WriteLine("\tEnd: Processing events from ETW file.");
                }
            }
        }
 public static bool TraceETWTraceEventSource
                     (
                         string providerName
                         , string tracedFileName
                         , string[] traceEvents = null
                         , Action
                                 <
                                     long
                                     , TraceEventDispatcher
                                     , TraceEventSession
                                     , TraceEvent
                                 > onOneEventTracedOnceProcessAction = null
                         , TraceEventProviderOptions traceEventProviderOptions = null
                         , TraceEventSourceType traceEventSourceType = TraceEventSourceType.MergeAll
                         , TraceEventLevel traceEventLevel = TraceEventLevel.Always
                         , ulong matchKeywords = ulong.MaxValue
                         , bool needCountHits = false
                     )
 {
     var r = false;
     if (!(TraceEventSession.IsElevated() ?? false))
     {
         Out.WriteLine("To turn on ETW events you need to be Administrator, please run from an Admin process.");
         return r;
     }
     if
         (
             traceEvents != null
             &&
             traceEvents.Length > 0
             &&
             onOneEventTracedOnceProcessAction != null
         )
     {
         using (var source = new ETWTraceEventSource(tracedFileName, traceEventSourceType))
         {
             //闭包
             long sequence = 0;
             RegisterCallbacks
                 (
                     providerName
                     , traceEvents
                     , source
                     , null
                     , (x, y, z) =>
                     {
                         long id = 0;
                         if (needCountHits)
                         {
                             id = Interlocked.Increment(ref sequence);
                         }
                         onOneEventTracedOnceProcessAction
                                         (
                                             id
                                             , x
                                             , y
                                             , z
                                         );
                     }
                 );
             source.Process();   // call the callbacks for each event
         }
     }
     return true;
 }
        private void Initialize()
        {
            this.session = TraceEventUtil.CreateSession(this.sessionName);

            // Hook up the ETWTraceEventSource to the specified session
            this.source = new ETWTraceEventSource(this.sessionName, TraceEventSourceType.Session);

            this.manifestCache = new TraceEventManifestsCache(this.source.Dynamic);

            // get any previously cached manifest and update the schema cache
            this.UpdateCaches();

            // hook up to all incoming events and filter out manifests
            this.source.Dynamic.All += e => this.ProcessEvent(e);

            // listen to new manifests
            this.source.Dynamic.DynamicProviderAdded += m => this.OnManifestReceived(m);

            // We collect all the manifests and save/terminate process when done
            this.source.UnhandledEvents += e => this.ProcessUnhandledEvent(e);

            foreach (var eventSource in this.eventSources)
            {
                // Bind the provider (EventSource/EventListener) with the session
                TraceEventUtil.EnableProvider(
                    this.session,
                    eventSource.EventSourceId,
                    eventSource.Level,
                    eventSource.MatchAnyKeyword,
                    eventSource.Arguments,
                    eventSource.ProcessNamesToFilter);
            }

            // source.Process() is blocking so we need to launch it on a separate thread.
            this.workerTask = Task.Factory.StartNew(() => this.source.Process(), TaskCreationOptions.LongRunning).
                                           ContinueWith(t => this.HandleProcessTaskFault(t));
        }
        /// <summary>
        /// Processing the data in a particular file.  
        /// </summary>
        static void DataProcessing(string dataFileName)
        {
            Out.WriteLine("Opening the output file and printing the results.");
            using (var source = new ETWTraceEventSource(dataFileName))
            {
                if (source.EventsLost != 0)
                    Out.WriteLine("WARNING: there were {0} lost events", source.EventsLost);

                // Set up callbacks to 
                source.Clr.All += Print;
                source.Kernel.All += Print;

                // When you merge a file, some 'symbol' events are injected into the trace.  
                // To avoid these showing up as 'unknown' add the parser for these.  This
                // also shows how you hook up a TraceEventParser that is not support by
                // properties on the source itself (like CLR, and kernel)
                var symbolParser = new SymbolTraceEventParser(source);
                symbolParser.All += Print;    

#if DEBUG
                // The callback above will only be called for events the parser recognizes (in the case of Kernel and CLR parsers)
                // It is sometimes useful to see the other events that are not otherwise being handled.  The source knows about these and you 
                // can ask the source to send them to you like this.  
                source.UnhandledEvents += delegate(TraceEvent data)
                {
                    if ((int)data.ID == 0xFFFE)         // The EventSource manifest events show up as unhandled, filter them out.
                        return;

                    // To avoid 'rundown' events that happen in the beginning and end of the trace filter out things during those times
                    if (data.TimeStampRelativeMSec < 1000 || 9000 < data.TimeStampRelativeMSec)
                        return;

                    Out.WriteLine("GOT UNHANDLED EVENT: " + data.Dump());
                };
#endif

                // go into a loop processing events can calling the callbacks.  This will return when the all the events
                // In the file are processed, or the StopProcessing() call is made.  
                source.Process();
                Out.WriteLine("Done Processing.");
            }
        }
 protected virtual void Dispose(bool disposing)
 {
     if (this.TraceEventSource != null && disposing)
     {
         this.StopProcessing();
         this.TraceEventSource.Dispose();
         this.TraceEventSource = null;
     }
 }
        /// <summary>
        /// Process the data in 'dataFileName' printing the events and doing delta computation between 'MyFirstEvent'
        /// and 'MySecondEvent'.
        /// </summary>
        static void ProcessData(string dataFileName)
        {
            // prepare to read from the session, connect the ETWTraceEventSource to the file
            // Notice there is no session at this point (reading and controlling are not necessarily related).
            // YOu can read the file on another machine if you like.
            Out.WriteLine("Opening {0} to see what data is in the file.", dataFileName);
            using (var source = new ETWTraceEventSource(dataFileName))
            {
                if (source.EventsLost != 0)
                {
                    Out.WriteLine("WARNING: there were {0} lost events", source.EventsLost);
                }

                // To demonstrate non-trivial event manipulation, we calculate the time delta between 'MyFirstEvent and 'MySecondEvent'
                // firstEventTimeMSec remembers all the 'MyFirstEvent' arrival times (indexed by their ID)
                var firstEventTimeMSec = new Dictionary <int, double>();

                /*****************************************************************************************************/
                // Hook up events.   To so this first we need a 'Parser. which knows how to part the events of a particular Event Provider.
                // In this case we get a DynamicTraceEventSource, which knows how to parse any EventSource provider.    This parser
                // is so common, that TraceEventSource as a shortcut property called 'Dynamic' that fetches this parsers.

                // For debugging, and demo purposes, hook up a callback for every event that 'Dynamic' knows about (this is not EVERY
                // event only those know about by DynamiceTraceEventParser).   However the 'UnhandledEvents' handler below will catch
                // the other ones.
                source.Dynamic.All += delegate(TraceEvent data)
                {
                    Out.WriteLine(data.PayloadByName("MyName"));
                    Out.WriteLine("GOT EVENT: " + data.ToString());
                };

                // Add logic on what to do when we get "MyFirstEvent"
                source.Dynamic.AddCallbackForProviderEvent("Microsoft-Demos-SimpleMonitor", "MyFirstEvent", delegate(TraceEvent data)
                {
                    // On First Events, simply remember the ID and time of the event
                    firstEventTimeMSec[(int)data.PayloadByName("MyId")] = data.TimeStampRelativeMSec;
                });

                // Add logic on what to do when we get "MySecondEvent"
                source.Dynamic.AddCallbackForProviderEvent("Microsoft-Demos-SimpleMonitor", "MySecondEvent", delegate(TraceEvent data)
                {
                    // On Second Events, if the ID matches, compute the delta and display it.
                    var myID = (int)data.PayloadByName("MyId");
                    double firstEventTime;
                    if (firstEventTimeMSec.TryGetValue(myID, out firstEventTime))
                    {
                        firstEventTimeMSec.Remove(myID);            // We are done with the ID after matching it, so remove it from the table.
                        Out.WriteLine("   >>> Time Delta from first Event = {0:f3} MSec", data.TimeStampRelativeMSec - firstEventTime);
                    }
                    else
                    {
                        Out.WriteLine("   >>> WARNING, Found a 'SecondEvent' without a corresponding 'FirstEvent'");
                    }
                });

                // Add logic on what to do when we get "Stop"
                source.Dynamic.AddCallbackForProviderEvent("Microsoft-Demos-SimpleMonitor", "MyStopEvent", delegate(TraceEvent data)
                {
                    Out.WriteLine("    >>> Got a stop message");
                    // Stop processing after we we see the 'Stop' event
                    source.StopProcessing();
                });

#if DEBUG
                // There may be events that are not handled by ANY of the callbacks above.  This is often a bug in your program
                // (you forgot a callback).  In debug we would like to see these to know that something is probably wrong.
                // The 'UnhandledEvents' callback will be called whenever no other callback has handled the event.   There is
                // also an 'All callback on the source (not a particular parser) that will call back on EVERY event from the source
                source.UnhandledEvents += delegate(TraceEvent data)
                {
                    if ((int)data.ID != 0xFFFE)         // The EventSource manifest events show up as unhandled, filter them out.
                    {
                        Out.WriteLine("GOT UNHANDLED EVENT: " + data.Dump());
                    }
                };
#endif

                // go into a loop processing events can calling the callbacks.  This will return when the all the events
                // In the file are processed, or the StopProcessing() call is made.
                source.Process();
                Out.WriteLine("Done Processing.");
            }
        }
        /// <summary>
        /// Wire up parsing of kernel event data from the specified ETWTraceEventSource.
        /// </summary>
        /// <param name="eventSource">The ETWTraceEventSource from which to parse the data.</param>
        private void ParseKernelTraceEvents(ETWTraceEventSource eventSource)
        {
            if (m_kernelEvents == KernelTraceEventParser.Keywords.None)
                return;

            var kernelParser = new KernelTraceEventParser(eventSource);

            // iterate over each set bit, wiring up a callback to parse the data
            uint eventBits = (uint)m_kernelEvents;
            int bitPos = 0;

            while (eventBits > 0)
            {
                // cycle through until a set bit is found
                while ((((uint)eventBits) & (uint)(1 << bitPos)) == 0)
                {
                    ++bitPos;
                    Debug.Assert(bitPos < 32);
                }

                var bitVal = (uint)(1 << bitPos);

                // now strip it from eventBits and covert it to its enum value
                eventBits ^= bitVal;
                KernelTraceEventParser.Keywords kernelEvent = (KernelTraceEventParser.Keywords)bitVal;

                if ((kernelEvent & KernelTraceEventParser.Keywords.ImageLoad) == KernelTraceEventParser.Keywords.ImageLoad)
                {
                    var modLoads = new EventDataListString<KernelPerfEvents>(KernelPerfEvents.ModuleLoad);

                    modLoads.Values = new HashSet<string>(StringComparer.OrdinalIgnoreCase);

                    kernelParser.ImageLoad += delegate(ImageLoadTraceData data)
                    {
                        if (string.Compare(data.ProcessName, m_process, true) == 0)
                        {
                            var modName = Path.GetFileName(data.FileName);
                            if (!modLoads.Values.Contains(modName))
                                modLoads.Values.Add(modName);

                            m_processFound = true;
                        }
                    };

                    m_aed.AddData(modLoads);
                }
                else
                {
                    Console.WriteLine("WARNING: Kernel event {0} NYI for reporting.", kernelEvent);
                }
            }
        }
        /// <summary>
        /// Process the data in 'dataFileName' printing the events and doing delta computation between 'MyFirstEvent'
        /// and 'MySecondEvent'.  
        /// </summary>
        static void ProcessData(string dataFileName)
        {
            // prepare to read from the session, connect the ETWTraceEventSource to the file
            // Notice there is no session at this point (reading and controlling are not necessarily related). 
            // YOu can read the file on another machine if you like.  
            Out.WriteLine("Opening {0} to see what data is in the file.", dataFileName);
            using (var source = new ETWTraceEventSource(dataFileName))
            {
                if (source.EventsLost != 0)
                    Out.WriteLine("WARNING: there were {0} lost events", source.EventsLost);

                // To demonstrate non-trivial event manipulation, we calculate the time delta between 'MyFirstEvent and 'MySecondEvent'
                // firstEventTimeMSec remembers all the 'MyFirstEvent' arrival times (indexed by their ID)  
                var firstEventTimeMSec = new Dictionary<int, double>();

                /*****************************************************************************************************/
                // Hook up events.   To so this first we need a 'Parser. which knows how to part the events of a particular Event Provider.
                // In this case we get a DynamicTraceEventSource, which knows how to parse any EventSource provider.    This parser
                // is so common, that TraceEventSource as a shortcut property called 'Dynamic' that fetches this parsers.  

                // For debugging, and demo purposes, hook up a callback for every event that 'Dynamic' knows about (this is not EVERY
                // event only those know about by DynamiceTraceEventParser).   However the 'UnhandledEvents' handler below will catch
                // the other ones.
                source.Dynamic.All += delegate(TraceEvent data)
                {
                    Out.WriteLine(data.PayloadByName("MyName"));
                    Out.WriteLine("GOT EVENT: " + data.ToString());
                };

                // Add logic on what to do when we get "MyFirstEvent"
                source.Dynamic.AddCallbackForProviderEvent("Microsoft-Demos-SimpleMonitor", "MyFirstEvent", delegate(TraceEvent data)
                {
                    // On First Events, simply remember the ID and time of the event
                    firstEventTimeMSec[(int)data.PayloadByName("MyId")] = data.TimeStampRelativeMSec;
                });

                // Add logic on what to do when we get "MySecondEvent"
                source.Dynamic.AddCallbackForProviderEvent("Microsoft-Demos-SimpleMonitor", "MySecondEvent", delegate(TraceEvent data)
                {
                    // On Second Events, if the ID matches, compute the delta and display it. 
                    var myID = (int)data.PayloadByName("MyId");
                    double firstEventTime;
                    if (firstEventTimeMSec.TryGetValue(myID, out firstEventTime))
                    {
                        firstEventTimeMSec.Remove(myID);            // We are done with the ID after matching it, so remove it from the table. 
                        Out.WriteLine("   >>> Time Delta from first Event = {0:f3} MSec", data.TimeStampRelativeMSec - firstEventTime);
                    }
                    else
                        Out.WriteLine("   >>> WARNING, Found a 'SecondEvent' without a corresponding 'FirstEvent'");
                });

                // Add logic on what to do when we get "Stop"
                source.Dynamic.AddCallbackForProviderEvent("Microsoft-Demos-SimpleMonitor", "Stop", delegate(TraceEvent data)
                {
                    Out.WriteLine("    >>> Got a stop message");
                    // Stop processing after we we see the 'Stop' event
                    source.StopProcessing();
                });

#if DEBUG
                // There may be events that are not handled by ANY of the callbacks above.  This is often a bug in your program 
                // (you forgot a callback).  In debug we would like to see these to know that something is probably wrong.  
                // The 'UnhandledEvents' callback will be called whenever no other callback has handled the event.   There is
                // also an 'All callback on the source (not a particular parser) that will call back on EVERY event from the source
                source.UnhandledEvents += delegate(TraceEvent data)
                {
                    if ((int)data.ID != 0xFFFE)         // The EventSource manifest events show up as unhandled, filter them out.
                        Out.WriteLine("GOT UNHANDLED EVENT: " + data.Dump());
                };
#endif

                // go into a loop processing events can calling the callbacks.  This will return when the all the events
                // In the file are processed, or the StopProcessing() call is made.  
                source.Process();
                Out.WriteLine("Done Processing.");
            }
        }
示例#44
0
        public void OverflowCircularBufferTest()
        {
            string dataFileName = "OverflowData.etl";

            var sessionName = Path.GetFileNameWithoutExtension(dataFileName) + "Session";
            var logger = ADShutdownEventSourceTester.ADShutdownEventSource.Log;

            // Normalize to a full path name.  
            dataFileName = Path.GetFullPath(dataFileName);
            Debug.WriteLine(String.Format("Creating data file {0}", dataFileName));

            TraceEventSession session = null;
            using (session = new TraceEventSession(sessionName, dataFileName))
            {
                // Turn on the eventSource given its name.
                session.CircularBufferMB = 1;
                session.BufferSizeMB = 1;
                session.EnableProvider(logger.Name);

                Thread.Sleep(100);  // Enabling is async. Wait a bit.

                // Generate events for all the tests, surrounded by events that tell us we are starting a test.  
                var info = new AppDomainSetup { ApplicationBase = AppDomain.CurrentDomain.BaseDirectory };
                var appDomain =
                AppDomain.CreateDomain("TestShutdownAD", new Evidence(), info);
                byte[] b = new byte[1000];
                var tester = (ADShutdownEventSourceTester)appDomain
                .CreateInstanceAndUnwrap(
                    typeof(TestShutdown).Assembly.GetName().Name,
                    typeof(ADShutdownEventSourceTester).FullName);

                for (int i = 0; i < 1500; i++)
                {
                    tester.LogBytes(b);
                }
                // Unload the AD and expect the manifest to be logged.
                AppDomain.Unload(appDomain);
                session.Flush();
            }

            // Parse ETL and search for manifest events
            using (var traceEventSource = new ETWTraceEventSource(dataFileName))
            {
                bool hasManifestEvents = false;
                Action<TraceEvent> onEvent = delegate (TraceEvent data)
                {
                    // Check for manifest events. 
                    if ((int)data.ID == 0xFFFE)
                        hasManifestEvents = true;
                };

                // Parse all the events as best we can, and also send unhandled events there as well.  
                traceEventSource.Registered.All += onEvent;
                traceEventSource.Dynamic.All += onEvent;
                traceEventSource.UnhandledEvent += onEvent;
                traceEventSource.Process();

                // Expect at least one manifest event.
                Assert.True(hasManifestEvents);
            }

            logger.Dispose();
        }
示例#45
0
        public override void Dispose()
        {
            _session.Flush();
            Thread.Sleep(1010);      // Let it drain.
            _session.Dispose();     // This also will kill the real time thread 

            if (_dataFileName != null)
            {
                using (var traceEventSource = new ETWTraceEventSource(_dataFileName))
                {
                    Debug.WriteLine("Processing data file " + Path.GetFullPath(_dataFileName));

                    // Parse all the events as best we can, and also send unhandled events there as well.  
                    traceEventSource.Registered.All += OnEventHelper;
                    traceEventSource.Dynamic.All += OnEventHelper;
                    traceEventSource.UnhandledEvents += OnEventHelper;
                    // Process all the events in the file.  
                    traceEventSource.Process();
                    Debug.WriteLine("Done processing data file " + Path.GetFullPath(_dataFileName));
                }
            }
        }
示例#46
0
        public IEnumerable <Counter> Parse(string mergeTraceFile, string processName, IList <int> pids)
        {
            var    results     = new List <double>();
            double threadTime  = 0;
            var    threadTimes = new List <double>();
            var    ins         = new Dictionary <int, double>();
            double start       = -1;
            int?   pid         = null;

            using (var source = new ETWTraceEventSource(mergeTraceFile))
            {
                source.Kernel.ProcessStart += evt =>
                {
                    if (evt.ProcessName.Equals(processName, StringComparison.OrdinalIgnoreCase) && pids.Contains(evt.ProcessID))
                    {
                        if (pid.HasValue)
                        {
                            // Processes might be reentrant. For now this traces the first (outermost) process of a given name.
                            return;
                        }
                        pid   = evt.ProcessID;
                        start = evt.TimeStampRelativeMSec;
                    }
                };

                source.Kernel.ThreadCSwitch += evt =>
                {
                    if (!pid.HasValue) // we're currently in a measurement interval
                    {
                        return;
                    }

                    if (evt.NewProcessID != pid && evt.OldProcessID != pid)
                    {
                        return;                                              // but this isn't our process
                    }
                    if (evt.OldProcessID == pid)                             // this is a switch out from our process
                    {
                        if (ins.TryGetValue(evt.OldThreadID, out var value)) // had we ever recorded a switch in for this thread?
                        {
                            threadTime += evt.TimeStampRelativeMSec - value;
                            ins.Remove(evt.OldThreadID);
                        }
                    }
                    else // this is a switch in to our process
                    {
                        ins[evt.NewThreadID] = evt.TimeStampRelativeMSec;
                    }
                };

                ClrPrivateTraceEventParser clrpriv = new ClrPrivateTraceEventParser(source);
                clrpriv.StartupMainStart += evt =>
                {
                    if (pid.HasValue && evt.ProcessID == pid && evt.ProcessName.Equals(processName, StringComparison.OrdinalIgnoreCase))
                    {
                        results.Add(evt.TimeStampRelativeMSec - start);
                        pid = null;
                        threadTimes.Add(threadTime);
                        threadTime = 0;
                        start      = 0;
                    }
                };
                source.Process();
            }
            return(new[] { new Counter()
                           {
                               Name = "Time To Main", Results = results.ToArray(), TopCounter = true, DefaultCounter = true, HigherIsBetter = false, MetricName = "ms"
                           },
                           new Counter()
                           {
                               Name = "Time on Thread", Results = threadTimes.ToArray(), TopCounter = true, DefaultCounter = false, HigherIsBetter = false, MetricName = "ms"
                           } });
        }
        private void CreateEventSourceOnBufferFile()
        {
            String oldFile = SwitchBufferFiles();
              Trace.WriteLine(String.Format("Starting processing on: {0}", oldFile));
              this.eventSource = new ETWTraceEventSource(
            oldFile, TraceEventSourceType.FileOnly
              );

              var sortedProvs = eventProviders.OrderBy(x => x.IsKernelProvider ? 0 : 1);
              foreach (var provider in sortedProvs) {
            provider.RegisterParser(this.eventSource);
              }

              this.observableStream = JoinStreams(sortedProvs);
              this.sourceProcessor.Start(this.observableStream);
              new Task(Process).Start();
        }
示例#48
0
        public static void Main(string[] args)
        {
            string traceFile     = args[0];
            string benchmarkName = "dotnet";
            int    benchmarkPid  = -2;

            Dictionary <string, uint> allEventCounts = new Dictionary <string, uint>();
            Dictionary <string, uint> eventCounts    = new Dictionary <string, uint>();
            Dictionary <string, uint> processCounts  = new Dictionary <string, uint>();

            using (var source = new ETWTraceEventSource(traceFile))
            {
                source.Kernel.All += delegate(TraceEvent data)
                {
                    if (allEventCounts.ContainsKey(data.EventName))
                    {
                        allEventCounts[data.EventName]++;
                    }
                    else
                    {
                        allEventCounts[data.EventName] = 1;
                    }

                    if (data.ProcessID == benchmarkPid)
                    {
                        if (eventCounts.ContainsKey(data.EventName))
                        {
                            eventCounts[data.EventName]++;
                        }
                        else
                        {
                            eventCounts[data.EventName] = 1;
                        }
                    }

                    switch (data.EventName)
                    {
                    case "Process/Start":
                    case "Process/DCStart":
                    {
                        // Process was running when tracing started (DCStart)
                        // or started when tracing was running (Start)
                        ProcessTraceData pdata = (ProcessTraceData)data;
                        if (String.Equals(pdata.ProcessName, benchmarkName, StringComparison.OrdinalIgnoreCase))
                        {
                            Console.WriteLine("Found process [{0}] {1}: {2}", pdata.ProcessID, pdata.ProcessName, pdata.CommandLine);
                            benchmarkPid = pdata.ProcessID;
                        }
                        else
                        {
                            // Console.WriteLine("Ignoring events from process {0}", pdata.ProcessName);
                        }
                        break;
                    }

                    case "Image/DCStart":
                    {
                        ImageLoadTraceData imageLoadTraceData = (ImageLoadTraceData)data;

                        if (data.ProcessID == 0)
                        {
                            string fileName  = imageLoadTraceData.FileName;
                            ulong  imageBase = imageLoadTraceData.ImageBase;
                            int    imageSize = imageLoadTraceData.ImageSize;

                            string fullName = fileName + "@" + imageBase.ToString();

                            if (!ImageMap.ContainsKey(fullName))
                            {
                                ImageInfo imageInfo = new ImageInfo(Path.GetFileName(fileName), imageBase, imageSize);
                                ImageMap.Add(fullName, imageInfo);
                            }
                        }

                        break;
                    }

                    case "Image/Load":
                    {
                        ImageLoadTraceData imageLoadTraceData = (ImageLoadTraceData)data;

                        if (imageLoadTraceData.ProcessID == benchmarkPid)
                        {
                            string fileName  = imageLoadTraceData.FileName;
                            ulong  imageBase = imageLoadTraceData.ImageBase;
                            int    imageSize = imageLoadTraceData.ImageSize;

                            // Suppress ngen images here, otherwise we lose visibility
                            // into ngen methods...

                            if (fileName.Contains(".ni."))
                            {
                                break;
                            }

                            string fullName = fileName + "@" + imageBase.ToString();

                            if (!ImageMap.ContainsKey(fullName))
                            {
                                ImageInfo imageInfo = new ImageInfo(Path.GetFileName(fileName), imageBase, imageSize);
                                ImageMap.Add(fullName, imageInfo);
                            }
                        }

                        break;
                    }

                    case "PerfInfo/PMCSample":
                    {
                        PMCCounterProfTraceData traceData = (PMCCounterProfTraceData)data;
                        if (traceData.ProcessID == benchmarkPid)
                        {
                            ulong instructionPointer = traceData.InstructionPointer;
                            // Not sure how to find the PMC reload interval... sigh
                            ulong count = 1;
                            UpdateSampleCountMap(instructionPointer, count);
                            UpdateThreadCountMap(traceData.ThreadID, count);
                        }
                        break;
                    }
                    }
                };

                source.Clr.All += delegate(TraceEvent data)
                {
                    if (allEventCounts.ContainsKey(data.EventName))
                    {
                        allEventCounts[data.EventName]++;
                    }
                    else
                    {
                        allEventCounts[data.EventName] = 1;
                    }

                    if (data.ProcessID == benchmarkPid)
                    {
                        if (eventCounts.ContainsKey(data.EventName))
                        {
                            eventCounts[data.EventName]++;
                        }
                        else
                        {
                            eventCounts[data.EventName] = 1;
                        }

                        switch (data.EventName)
                        {
                        case "Method/JittingStarted":
                        {
                            MethodJittingStartedTraceData jitStartData = (MethodJittingStartedTraceData)data;
                            JitInvocation jitInvocation = new JitInvocation();
                            jitInvocation.ThreadId           = jitStartData.ThreadID;
                            jitInvocation.MethodId           = jitStartData.MethodID;
                            jitInvocation.InitialThreadCount = ThreadCountMap[jitInvocation.ThreadId];
                            ActiveJitInvocations.Add(jitInvocation.ThreadId, jitInvocation);
                            AllJitInvocations.Add(jitInvocation);
                            break;
                        }

                        case "Method/LoadVerbose":
                        {
                            MethodLoadUnloadVerboseTraceData loadUnloadData = (MethodLoadUnloadVerboseTraceData)data;
                            if (ActiveJitInvocations.ContainsKey(loadUnloadData.ThreadID))
                            {
                                JitInvocation j = ActiveJitInvocations[loadUnloadData.ThreadID];
                                ActiveJitInvocations.Remove(j.ThreadId);
                                j.FinalThreadCount = ThreadCountMap[j.ThreadId];
                                if (j.FinalThreadCount < j.InitialThreadCount)
                                {
                                    Console.WriteLine("eh? negative jit count...");
                                }
                                else
                                {
                                    JitSampleCount += j.FinalThreadCount - j.InitialThreadCount;
                                }
                            }
                            else
                            {
                                // ?
                            }
                            break;
                        }

                        case "Method/UnloadVerbose":
                        {
                            // Pretend this is an "image"
                            MethodLoadUnloadVerboseTraceData loadUnloadData = (MethodLoadUnloadVerboseTraceData)data;
                            string fullName = GetName(loadUnloadData);
                            string key      = fullName + "@" + loadUnloadData.MethodID.ToString("X");
                            if (!ImageMap.ContainsKey(key))
                            {
                                ImageInfo methodInfo = new ImageInfo(fullName, loadUnloadData.MethodStartAddress,
                                                                     loadUnloadData.MethodSize);
                                ImageMap.Add(key, methodInfo);
                                methodInfo.IsJitGeneratedCode = true;
                                methodInfo.IsJittedCode       = loadUnloadData.IsJitted;
                            }
                            //else
                            //{
                            //    Console.WriteLine("eh? see method {0} again in rundown", fullName);
                            //}
                            break;
                        }
                        }
                    }
                };

                source.Process();
            }


            AttributeSampleCounts();

            //foreach (var e in allEventCounts)
            //{
            //    Console.WriteLine("Event {0} occurred {1} times", e.Key, e.Value);
            //}
            //foreach (var e in processCounts)
            //{
            //    Console.WriteLine("Process {0} had {1} events", e.Key, e.Value);
            //}

            if (!eventCounts.ContainsKey("PerfInfo/PMCSample"))
            {
                Console.WriteLine("No PMC events seen, sorry.");
            }
            else
            {
                ulong InstrsPerEvent = 65536;
                ulong pmcEvents      = eventCounts["PerfInfo/PMCSample"];

                Console.WriteLine("InstRetired for {0}: {1} events, {2:E} instrs",
                                  benchmarkName, pmcEvents, pmcEvents * InstrsPerEvent);
                Console.WriteLine("Jitting           : {0:00.00%} ({1} methods)",
                                  (double)JitSampleCount / TotalSampleCount, AllJitInvocations.Count);
                // Console.WriteLine("  JitInterface    : {0:00.00%}", (double) JitSampleCount - JitDllSampleCount);
                Console.WriteLine("Jit-generated code: {0:00.00%}", (double)JitGeneratedCodeSampleCount / TotalSampleCount);
                Console.WriteLine("  Jitted code     : {0:00.00%}", (double)JittedCodeSampleCount / TotalSampleCount);
                Console.WriteLine();

                double ufrac = (double)UnknownImageCount / TotalSampleCount;
                if (ufrac > 0.002)
                {
                    Console.WriteLine("{0:00.00%}   {1,-8:G3}   {2} {3}",
                                      ufrac,
                                      UnknownImageCount * InstrsPerEvent,
                                      "?      ",
                                      "Unknown");
                }

                // Collect up significant counts
                List <ImageInfo> significantInfos = new List <ImageInfo>();

                foreach (var i in ImageMap)
                {
                    double frac = (double)i.Value.SampleCount / TotalSampleCount;
                    if (frac > 0.002)
                    {
                        significantInfos.Add(i.Value);
                    }
                }

                significantInfos.Sort(ImageInfo.MoreSamples);

                foreach (var i in significantInfos)
                {
                    Console.WriteLine("{0:00.00%}   {1,-8:G3}   {2}  {3}",
                                      (double)i.SampleCount / TotalSampleCount,
                                      i.SampleCount * InstrsPerEvent,
                                      i.IsJitGeneratedCode ? (i.IsJittedCode ? "jit   " : "prejit") : "native",
                                      i.Name);
                }
            }
        }
 private void ReleaseProcessingSession()
 {
     if ( this.eventSource != null ) {
     this.eventSource.Dispose();
     this.eventSource = null;
       }
 }
        /// <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);
                }
            }
        }
示例#51
0
        public void Load(string fileName)
        {
            ETWTraceEventSource source = new ETWTraceEventSource(fileName);
            RegisteredTraceEventParser parser = new RegisteredTraceEventParser(source);

            parser.All += Parser_All;
            source.Process();
        }