public override void EventSourceCommand(string eventSourceName, EventCommand command, FilteringOptions options = null) { if (command == EventCommand.Enable) { if (options == null) { options = new FilteringOptions(); } _session.EnableProvider(eventSourceName, (TraceEventLevel)options.Level, (ulong)options.Keywords, new TraceEventProviderOptions() { Arguments = options.Args }); } else if (command == EventCommand.Disable) { _session.DisableProvider(TraceEventProviders.GetEventSourceGuidFromName(eventSourceName)); } else { throw new NotImplementedException(); } Thread.Sleep(200); // Calls are async, give them time to work. }
/// <summary> /// Parse a provider input definition /// This function can retrieve provider from Name definition or Guid definition /// /// A name definition is associated with a manifest based provider and function will /// check if the provider is recorded on current workstation /// /// If name is not found we will try to parse Guid definition. /// A Guid definition must follow : /// TYPE{GUID} /// When /// TYPE: Manifest | TL | WPP /// GUID: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx /// /// </summary> /// <param name="name">input provider definition</param> /// <returns>ProviderGuid definition</returns> public static ProviderGuid Parse(string name) { var providerGuid = TraceEventProviders.GetProviderGuidByName(name); if (providerGuid != Guid.Empty) { return(new ProviderGuid { Type = ProviderType.Manifest, Guid = providerGuid }); } var matches = PATTERN.Matches(name); if (matches.Count != 1) { throw new Exception("Invalid Provider Format"); } GroupCollection matchGroup = matches[0].Groups; return(new ProviderGuid { Type = (ProviderType)Enum.Parse(typeof(ProviderType), matchGroup["type"].Value), Guid = Guid.Parse(matchGroup["guid"].Value) }); }
/// <summary> /// Initializes a new instance of the <see cref="EventSourceSettings" /> class. /// </summary> /// <param name="name">The friendly event source name.</param> /// <param name="eventSourceId">The event source id.</param> /// <param name="level">The level.</param> /// <param name="matchAnyKeyword">The match any keyword.</param> /// <param name="arguments">The arguments for the event source.</param> /// <param name="processNameFilters">The the process filters.</param> /// <exception cref="ConfigurationException">A validation exception.</exception> public EventSourceSettings( string name = null, Guid?eventSourceId = null, EventLevel level = EventLevel.LogAlways, EventKeywords matchAnyKeyword = Keywords.All, IEnumerable <KeyValuePair <string, string> > arguments = null, IEnumerable <string> processNameFilters = null) { // If no Id, Name should not be optional so we may derive an Id from it. if (!eventSourceId.HasValue || eventSourceId == Guid.Empty) { if (string.IsNullOrWhiteSpace(name)) { throw new ConfigurationException(Properties.Resources.MissingEventSourceNameAndId); } eventSourceId = TraceEventProviders.GetEventSourceGuidFromName(name); } else if (!string.IsNullOrWhiteSpace(name)) { // throw and both name & Id specified throw new ConfigurationException(Properties.Resources.EventSourceAmbiguityError); } this.EventSourceId = eventSourceId.Value; this.Name = name ?? eventSourceId.ToString(); // Set a not null value for later use this.Level = level; this.MatchAnyKeyword = matchAnyKeyword; this.Arguments = arguments ?? Enumerable.Empty <KeyValuePair <string, string> >(); this.ProcessNamesToFilter = processNameFilters ?? Enumerable.Empty <string>(); }
public EtwTracingInterceptorTest() { eventSession = new TraceEventSession(Guid.NewGuid().ToString()); var eventSourceGuid = TraceEventProviders.GetEventSourceGuidFromName("Microsoft-WindowsAzure"); eventSession.EnableProvider(eventSourceGuid); }
static EtwProviderSelectionViewModel() { _providers = TraceEventProviders.GetPublishedProviders().Select(g => new Provider { Name = TraceEventProviders.GetProviderName(g), Guid = g }).ToArray(); }
private static void RealTimeSession() { if (options.ParsedClrKeywords == 0 && options.ParsedKernelKeywords == KernelTraceEventParser.Keywords.None && options.OtherProviders.Count == 0) { Bail("No events to collect"); } Console.CancelKeyPress += (_, __) => CloseSession(); if (options.DurationInSeconds > 0) { Task.Delay(TimeSpan.FromSeconds(options.DurationInSeconds)) .ContinueWith(_ => CloseSession()); } using (session = new TraceEventSession("etrace-realtime-session")) { if (options.ParsedKernelKeywords != KernelTraceEventParser.Keywords.None) { session.EnableKernelProvider(options.ParsedKernelKeywords); } if (options.ParsedClrKeywords != 0) { session.EnableProvider(ClrTraceEventParser.ProviderGuid, matchAnyKeywords: (ulong)options.ParsedClrKeywords); } if (options.OtherProviders.Any()) { foreach (var provider in options.OtherProviders) { Guid guid; if (Guid.TryParse(provider, out guid)) { session.EnableProvider(Guid.Parse(provider)); } else { guid = TraceEventProviders.GetProviderGuidByName(provider); if (guid != Guid.Empty) { session.EnableProvider(guid); } } } } if (options.IsOutFile) { outRelogger = new ETWReloggerTraceEventSource(session.SessionName, TraceEventSourceType.Session, options.OutFile); isOutReloggerSet = true; ProcessTrace(outRelogger); } else { ProcessTrace(session.Source); } } }
public void Start() { etwSession = new TraceEventSession("RequestSession"); etwSession.Source.Dynamic.All += HandleEtwEvent; var eventSourceProviderGuid = TraceEventProviders.GetEventSourceGuidFromName(EventSource.GetName(typeof(EtwSource))); etwSession.EnableProvider(eventSourceProviderGuid); Task.Factory.StartNew(() => etwSession.Source.Process()); }
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); }
//Level 4 is default -- after keywords public ProviderBrowser(Window parent, Action <string, string, string> update) { Owner = parent; m_keyStrings = new List <String>(); m_selectedKeys = new List <string>(); m_keys = new Dictionary <string, ProviderDataItem>(); m_processNames = new List <String>(); m_updateParent = update; m_level = "Verbose"; InitializeComponent(); ProviderNameFilter.Focus(); LevelListBox.Items.Add("Always"); LevelListBox.Items.Add("Critical"); LevelListBox.Items.Add("Error"); LevelListBox.Items.Add("Warning"); LevelListBox.Items.Add("Informational"); LevelListBox.Items.Add("Verbose"); LevelListBox.SelectedItem = "Verbose"; var processInfos = new ProcessInfos(); m_processNames.Add("*"); foreach (var process in processInfos.Processes) { // If the name is null, it is likely a system process, it will not have managed code, so don't bother. if (process.Name == null) { continue; } // if (process.ProcessID == myProcessId) // continue; /*// Only show processes with GC heaps. * if (!allProcs && !m_procsWithHeaps.ContainsKey(process.ProcessID)) * continue;*/ m_processNames.Add(process.ToString()); } ProcessNameListBox.ItemsSource = m_processNames; // Get Provider names m_providerNames = new List <String>(); foreach (Guid guid in TraceEventProviders.GetPublishedProviders()) { m_providerNames.Add(TraceEventProviders.GetProviderName(guid)); //keyStrings.Add(TraceEventProviders.GetProviderKeywords(guid).ToString()); } // setup GUI controls. ProviderNameListBox.ItemsSource = m_providerNames; KeyNameListBox.ItemsSource = m_keyStrings; }
protected override void EnableProviders(TraceEventSession session) { var options = new TraceEventProviderOptions() { ProcessNameFilter = new string[] { "Quadrant.exe" } }; Guid eventSource = TraceEventProviders.GetEventSourceGuidFromName(QuadrantProvider); session.EnableProvider(eventSource, options: options); EnabledDefaultProviders(session, options); }
private void ThreadCallback(object state) { using (var session = new TraceEventSession("MyRealTimeSession")) { var providerName = "Microsoft-Windows-DotNETRuntime"; var eventSourceGuid = TraceEventProviders.GetProviderGuidByName(providerName); session.EnableProvider(eventSourceGuid); session.Source.Clr.GCHeapStats += ClrOnGcHeapStats; session.Source.Clr.GCStart += ClrOnGcStart; session.Source.Clr.GCStop += Clr_GCStop; session.Source.Process(); } }
public static void X() { // Create a new session, turn on some events, and get the stream of events var session = new TraceEventSession("MySession"); session.EnableProvider(TraceEventProviders.GetEventSourceGuidFromName("MyEventSource")); var eventStream = session.Source; // Create an in memory GENERIC list of parsed (basically string) records that can hold the results GenericEventSource eventSource = new GenericEventSource(); // Hook up the ETW eventStream to the generic in memory event source. var dynamicParser = new DynamicTraceEventParser(eventStream); Action <TraceEvent> sendToEventStore = delegate(TraceEvent data) { var processName = data.ProcessName; if (!processName.StartsWith("(")) { processName += " (" + data.ProcessID + ")"; } var fieldNames = data.PayloadNames; var fields = new string[fieldNames.Length]; for (int i = 0; i < fields.Length; i++) { fields[i] = data.PayloadString(i); } var genericRecord = new GenericEventRecord(data.EventName, data.ProcessName, data.TimeStampRelativeMSec, fieldNames, fields); eventSource.Records.AddRecord(genericRecord); }; dynamicParser.All += sendToEventStore; var registeredParser = new RegisteredTraceEventParser(eventStream); registeredParser.All += sendToEventStore; eventStream.UnhandledEvents += sendToEventStore; // Start processing ETW events and filling the in-memory list (which the GUI is observing). var thread = new Thread(delegate() { session.Source.Process(); }); thread.Start(); var window = new EventWindow(GuiApp.MainWindow, eventSource); window.Show(); }
public TraceEventProvider(string nameOrGuid, TraceEventLevel level = TraceEventLevel.Verbose) { Guid guid; if (!Guid.TryParse(nameOrGuid, out guid)) { this.Guid = TraceEventProviders.GetEventSourceGuidFromName(nameOrGuid); } else { this.Guid = guid; } this.Level = level; }
private static void List() { if ((options.List & ListFlags.CLR) != 0) { Console.WriteLine("\nSupported CLR keywords (use with --clr):\n"); foreach (var keyword in Enum.GetNames(typeof(ClrTraceEventParser.Keywords))) { Console.WriteLine($"\t{keyword}"); } } if ((options.List & ListFlags.Kernel) != 0) { Console.WriteLine("\nSupported kernel keywords (use with --kernel):\n"); foreach (var keyword in Enum.GetNames(typeof(KernelTraceEventParser.Keywords))) { Console.WriteLine($"\t{keyword}"); } } if ((options.List & ListFlags.Registered) != 0) { Console.WriteLine("\nRegistered or enabled providers (use with --other):\n"); foreach (var provider in TraceEventProviders.GetRegisteredOrEnabledProviders() .Select(guid => TraceEventProviders.GetProviderName(guid)) .OrderBy(n => n)) { Console.WriteLine($"\t{provider}"); } } if ((options.List & ListFlags.Published) != 0) { Console.WriteLine("\nPublished providers (use with --other):\n"); foreach (var provider in TraceEventProviders.GetPublishedProviders() .Select(guid => TraceEventProviders.GetProviderName(guid)) .OrderBy(n => n)) { Console.WriteLine($"\t{provider}"); } } if ((options.List & ListFlags.Framework) != 0) { Console.WriteLine("\nPublished providers (use with --framework):\n"); foreach (var keyword in Enum.GetNames(typeof(FrameworkEventSourceTraceEventParser.Keywords))) { Console.WriteLine($"\t{keyword}"); } } }
static void Main(string[] args) { using (var session = new TraceEventSession("MyRealTimeSession3")) // Create a session to listen for events { session.Source.Dynamic.All += delegate(TraceEvent data) // Set Source (stream of events) from session. { // Get dynamic parser (knows about EventSources) // Subscribe to all EventSource events Console.WriteLine(data.FormattedMessage); // Print each message as it comes in }; var eventSourceGuid = TraceEventProviders.GetEventSourceGuidFromName("MyEdit3"); // Get the unique ID for the eventSouce. session.EnableProvider(eventSourceGuid); // Enable MyEventSource. session.Source.Process(); // Wait for incoming events (forever). } }
/// <summary> /// Main function (entry point) /// </summary> /// <param name="args">Provider Name as first parameter, Output file as second parameter</param> static int Main(string[] args) { if (args.Length == 1) { foreach (var providerName in TraceEventProviders.GetPublishedProviders().Select(x => TraceEventProviders.GetProviderName(x))) { Console.WriteLine("Create dissector for provider " + providerName); if (providerName == "TPM") { continue; } // Ignore this provider during install // because we made it by hand to handle // upper layer if (providerName == "Microsoft-Windows-NDIS-PacketCapture") { continue; } if (System.Environment.OSVersion.Version.Major == 6 && System.Environment.OSVersion.Version.Minor == 1) { if (providerName == "Microsoft-Windows-UIAutomationCore") { Console.WriteLine("Ignore provider " + providerName + " on Windows 7"); continue; } } Directory.CreateDirectory(args[0]); CreateDissectorFromProvider(providerName, Path.Combine(args[0], providerName.Replace("-", "_").Replace(" ", "_") + ".lua")); } } else if (args.Length == 2) { CreateDissectorFromProvider(args[0], args[1]); return(0); } else { PrintUsage(); } return(0); }
public static Guid GetProviderGuidFromProviderName(string name) { if (String.IsNullOrEmpty(name)) { return(Guid.Empty); } // Legacy GUID lookups (events which existed before the current Guid generation conventions) if (name == TplEtwProviderTraceEventParser.ProviderName) { return(TplEtwProviderTraceEventParser.ProviderGuid); } else if (name == ClrTraceEventParser.ProviderName) { return(ClrTraceEventParser.ProviderGuid); } else if (name == ClrPrivateTraceEventParser.ProviderName) { return(ClrPrivateTraceEventParser.ProviderGuid); } else if (name == ClrRundownTraceEventParser.ProviderName) { return(ClrRundownTraceEventParser.ProviderGuid); } else if (name == ClrStressTraceEventParser.ProviderName) { return(ClrStressTraceEventParser.ProviderGuid); } else if (name == FrameworkEventSourceTraceEventParser.ProviderName) { return(FrameworkEventSourceTraceEventParser.ProviderGuid); } // Needed as long as eventpipeinstance v1 objects are supported else if (name == SampleProfilerTraceEventParser.ProviderName) { return(SampleProfilerTraceEventParser.ProviderGuid); } // Hash the name according to current event source naming conventions else { return(TraceEventProviders.GetEventSourceGuidFromName(name)); } }
private void RunAsync() { var elevated = TraceEventSession.IsElevated(); var eventSourceGuid = TraceEventProviders.GetProviderGuidByName(providerName); session = new TraceEventSession(sessionName, "data.etl"); kernelSession = new TraceEventSession(KernelTraceEventParser.KernelSessionName, "data.kernel.etl"); kernelSession.EnableKernelProvider(KernelTraceEventParser.Keywords.ImageLoad | KernelTraceEventParser.Keywords.Process | KernelTraceEventParser.Keywords.Thread); var optionsWithStacks = new TraceEventProviderOptions() { StacksEnabled = true }; session.EnableProvider(ClrTraceEventParser.ProviderGuid, TraceEventLevel.Verbose, (ulong)ClrTraceEventParser.Keywords.Default); session.EnableProvider(ClrTraceEventParser.ProviderGuid, TraceEventLevel.Verbose, (ulong)ClrTraceEventParser.Keywords.GC, optionsWithStacks); }
public static EventSourceDefinition Parse(string providerName, ulong matchAnyKeywords, int traceLevel, IEnumerable <int> ids, IEnumerable <int> processIds, IEnumerable <string> processNames) { Guid providerGuid = TraceEventProviders.GetProviderGuidByName(providerName); if (providerGuid == Guid.Empty) { providerGuid = TraceEventProviders.GetEventSourceGuidFromName(providerName); if (providerGuid == Guid.Empty) { throw new ArgumentException(string.Format("Provider name doesn't exist: {0}", providerName)); } } var definition = new EventSourceDefinition() { ProviderName = providerName, ProviderGuid = providerGuid, Keywords = matchAnyKeywords, TraceLevel = (TraceEventLevel)traceLevel, }; if (ids != null) { var idList = new List <int>(ids); definition.Ids = idList.Count > 0 ? idList : null; } if (processIds != null) { var processIdList = new List <int>(processIds); definition.ProcessIds = processIdList.Count > 0 ? processIdList : null; } if (processNames != null) { var processNameList = new List <string>(processNames); definition.ProcessNames = processNameList.Count > 0 ? processNameList : null; } return(definition); }
private void ProviderSelected(object sender, SelectionChangedEventArgs e) { var selectedItem = ProviderNameListBox.SelectedItem; if (selectedItem != null) { m_selectedProvider = selectedItem.ToString(); m_keys = new Dictionary <string, ProviderDataItem>(); foreach (var keyword in TraceEventProviders.GetProviderKeywords(TraceEventProviders.GetProviderGuidByName(m_selectedProvider))) { m_keys.Add(keyword.Name.ToString(), keyword); } m_keyStrings = new List <String>(); foreach (var key in m_keys.Keys) { m_keyStrings.Add(m_keys[key].Name.ToString()); } KeyNameListBox.ItemsSource = m_keyStrings; m_selectedKeys = new List <string>(); updateDisplays(); } }
private void DoProcessSelected(object sender, SelectionChangedEventArgs e) { var selectedItem = ProcessNameListBox.SelectedItem; if (selectedItem != null) { m_keyStrings = new List <String>(); m_selectedKeys = new List <string>(); m_providerNames = new List <String>(); m_selectedProvider = null; m_providerNames = new List <String>(); if (selectedItem.ToString() == "*") { foreach (Guid guid in TraceEventProviders.GetPublishedProviders()) { m_providerNames.Add(TraceEventProviders.GetProviderName(guid)); } } else { //if (selectedItem.ToString() == "*") // TemplateProperty; // else m_selectedProcess = selectedItem.ToString(); int begin = m_selectedProcess.IndexOf("|"); int end = m_selectedProcess.IndexOf("| Alive", begin + 1); m_selectedProcess = m_selectedProcess.Substring(begin + 8, end - begin - 8); foreach (var provider in TraceEventProviders.GetRegisteredProvidersInProcess(int.Parse(m_selectedProcess))) { m_providerNames.Add(TraceEventProviders.GetProviderName(provider)); } KeyNameListBox.ItemsSource = m_keyStrings; } ProviderNameListBox.ItemsSource = m_providerNames; updateDisplays(); } }
static void Main(string[] args) { Console.WriteLine("\n Auth0 Claims Provider Logs on {0}\n\n", Environment.MachineName); using (var session = new TraceEventSession("Auth0.ClaimsProvider.LogsProcessor")) { session.Source.Dynamic.All += delegate(TraceEvent data) { if (!String.IsNullOrEmpty(data.FormattedMessage)) { // Get the process name. var processName = "Unknown process"; try { var process = Process.GetProcessById(data.ProcessID); if (process != null) { processName = process.ProcessName; process.Dispose(); } } catch (Exception) { } // Display the process. Console.WriteLine(" {0} - {1} [{2}]", data.TimeStamp.ToString("HH:mm:ss"), data.FormattedMessage, processName); } }; session.EnableProvider( TraceEventProviders.GetEventSourceGuidFromName("Auth0-ClaimsProviderEventSource")); session.Source.Process(); } Console.ReadLine(); }
private void TraceEvents() { // will attempt to create a session named "MySession" using (var session = new TraceEventSession("MySession")) { // set up Ctrl-C to stop the session SetupCtrlCHandler(() => { session.Stop(); }); // set up parser to read CLR events var clrParser = new ClrTraceEventParser(session.Source); if (ExceptionEnabled == 1) { // subscribe to all exception start events clrParser.ExceptionStart += delegate(ExceptionTraceData data) { // if exception was in user process, add it to list of exceptions if (data.ProcessID == myProcess.Id) { Exceptions e = new Exceptions(); e.type = data.ExceptionType; e.timestamp = DateTime.Now; e.App = instance; lock (lockObject) { ExceptionVals.Add(e); } } }; } if (ContentionEnabled == 1) { // subscribe to all contention start events clrParser.ContentionStart += delegate(ContentionTraceData data) { if (data.ProcessID == myProcess.Id) { Contention c = new Contention(); c.type = "Start"; c.id = data.ActivityID; c.timestamp = DateTime.Now; c.App = instance; lock (lockObject) { ContentionVals.Add(c); } } }; // subscribe to all contention stop events clrParser.ContentionStop += delegate(ContentionTraceData data) { if (data.ProcessID == myProcess.Id) { Contention c = new Contention(); c.type = "Stop"; c.id = data.ActivityID; c.timestamp = DateTime.Now; c.App = instance; lock (lockObject) { ContentionVals.Add(c); } } }; } if (GCEnabled == 1) { // subscribe to all GC start events clrParser.GCStart += delegate(GCStartTraceData data) { if (data.ProcessID == myProcess.Id) { GC gc = new GC(); gc.type = "Start"; gc.timestamp = DateTime.Now; gc.id = data.ThreadID; gc.App = instance; lock (lockObject) { GCVals.Add(gc); } } }; // subscribe to all GC stop events clrParser.GCStop += delegate(GCEndTraceData data) { if (data.ProcessID == myProcess.Id) { GC gc = new GC(); gc.type = "Stop"; gc.timestamp = DateTime.Now; gc.id = data.ThreadID; gc.App = instance; lock (lockObject) { GCVals.Add(gc); } } }; // subscribe to all GC memory allocation ticks clrParser.GCAllocationTick += delegate(GCAllocationTickTraceData data) { if (data.ProcessID == myProcess.Id) { GC gc = new GC(); gc.type = "Allocation Tick"; gc.timestamp = DateTime.Now; gc.id = data.ThreadID; gc.App = instance; lock (lockObject) { GCVals.Add(gc); } } }; // subscribe to all creations of concurrent threads for GC clrParser.GCCreateConcurrentThread += delegate(GCCreateConcurrentThreadTraceData data) { if (data.ProcessID == myProcess.Id) { GC gc = new GC(); gc.type = "Create Concurrent Thread"; gc.timestamp = DateTime.Now; gc.id = data.ThreadID; gc.App = instance; lock (lockObject) { GCVals.Add(gc); } } }; // subscribe to all restart stops clrParser.GCRestartEEStop += delegate(GCNoUserDataTraceData data) { if (data.ProcessID == myProcess.Id) { GC gc = new GC(); gc.type = "Restart EE Stop"; gc.timestamp = DateTime.Now; gc.id = data.ThreadID; gc.App = instance; lock (lockObject) { GCVals.Add(gc); } } }; // subscribe to all suspension starts clrParser.GCSuspendEEStart += delegate(GCSuspendEETraceData data) { if (data.ProcessID == myProcess.Id) { GC gc = new GC(); gc.type = "Suspend EE Start"; gc.timestamp = DateTime.Now; gc.id = data.ThreadID; gc.App = instance; lock (lockObject) { GCVals.Add(gc); } } }; // subscribe to all concurrent thread terminations clrParser.GCTerminateConcurrentThread += delegate(GCTerminateConcurrentThreadTraceData data) { if (data.ProcessID == myProcess.Id) { GC gc = new GC(); gc.type = "Concurrent Thread Termination"; gc.timestamp = DateTime.Now; gc.id = data.ThreadID; gc.App = instance; lock (lockObject) { GCVals.Add(gc); } } }; // subscribe to all GC triggers clrParser.GCTriggered += delegate(GCTriggeredTraceData data) { if (data.ProcessID == myProcess.Id) { GC gc = new GC(); gc.type = "Triggered"; gc.timestamp = DateTime.Now; gc.id = data.ThreadID; gc.App = instance; lock (lockObject) { GCVals.Add(gc); } } }; } if (JitEnabled == 1) { // subscribe to all Jit start events clrParser.MethodJittingStarted += delegate(MethodJittingStartedTraceData data) { if (data.ProcessID == myProcess.Id) { Jit j = new Jit(); j.method = data.MethodName; j.timestamp = DateTime.Now; j.App = instance; lock (lockObject) { JitVals.Add(j); } } }; } if (HttpEnabled == 1) { // subscribe to all dynamic events (used for HTTP request event tracking) session.Source.Dynamic.All += delegate(TraceEvent data) { if (data.ProcessID == myProcess.Id && data.EventName == "Request/Start") { Http_Request request = new Http_Request(); request.type = "Start"; request.timestamp = DateTime.Now; request.activityID = data.ActivityID; request.App = instance; request.method = data.PayloadString(0); request.path = data.PayloadString(1); lock (lockObject) { RequestVals.Add(request); } } else if (data.ProcessID == myProcess.Id && data.EventName == "Request/Stop") { Http_Request request = new Http_Request(); request.type = "Stop"; request.timestamp = DateTime.Now; request.activityID = data.ActivityID; request.App = instance; lock (lockObject) { RequestVals.Add(request); } } }; } // set up providers for events using GUIDs - first EnableProvider command is to receive activity IDs for associated events session.EnableProvider(new Guid("2e5dba47-a3d2-4d16-8ee0-6671ffdcd7b5"), TraceEventLevel.Informational, 0x80); var AspSourceGuid = TraceEventProviders.GetEventSourceGuidFromName("Microsoft-AspNetCore-Hosting"); session.EnableProvider(AspSourceGuid); session.EnableProvider(ClrTraceEventParser.ProviderGuid, TraceEventLevel.Verbose, (0x8000 | 0x4000 | 0x1 | 0x10)); session.Source.Process(); // call the callbacks for each event } }
/// <summary> /// Generate the thread time stacks, outputting to 'stackSource'. /// </summary> /// <param name="outputStackSource"></param> /// <param name="traceEvents">Optional filtered trace events.</param> public void GenerateThreadTimeStacks(MutableTraceEventStackSource outputStackSource, TraceEvents traceEvents = null) { m_outputStackSource = outputStackSource; m_sample = new StackSourceSample(outputStackSource); m_nodeNameInternTable = new Dictionary <double, StackSourceFrameIndex>(10); m_ExternalFrameIndex = outputStackSource.Interner.FrameIntern("UNMANAGED_CODE_TIME"); m_cpuFrameIndex = outputStackSource.Interner.FrameIntern("CPU_TIME"); TraceLogEventSource eventSource = traceEvents == null?m_eventLog.Events.GetSource() : traceEvents.GetSource(); if (GroupByStartStopActivity) { UseTasks = true; } if (UseTasks) { m_activityComputer = new ActivityComputer(eventSource, m_symbolReader); m_activityComputer.AwaitUnblocks += delegate(TraceActivity activity, TraceEvent data) { var sample = m_sample; sample.Metric = (float)(activity.StartTimeRelativeMSec - activity.CreationTimeRelativeMSec); sample.TimeRelativeMSec = activity.CreationTimeRelativeMSec; // The stack at the Unblock, is the stack at the time the task was created (when blocking started). sample.StackIndex = m_activityComputer.GetCallStackForActivity(m_outputStackSource, activity, GetTopFramesForActivityComputerCase(data, data.Thread(), true)); StackSourceFrameIndex awaitFrame = m_outputStackSource.Interner.FrameIntern("AWAIT_TIME"); sample.StackIndex = m_outputStackSource.Interner.CallStackIntern(awaitFrame, sample.StackIndex); m_outputStackSource.AddSample(sample); if (m_threadToStartStopActivity != null) { UpdateStartStopActivityOnAwaitComplete(activity, data); } }; // We can provide a bit of extra value (and it is useful for debugging) if we immediately log a CPU // sample when we schedule or start a task. That we we get the very instant it starts. var tplProvider = new TplEtwProviderTraceEventParser(eventSource); tplProvider.AwaitTaskContinuationScheduledSend += OnSampledProfile; tplProvider.TaskScheduledSend += OnSampledProfile; tplProvider.TaskExecuteStart += OnSampledProfile; tplProvider.TaskWaitSend += OnSampledProfile; tplProvider.TaskWaitStop += OnTaskUnblock; // Log the activity stack even if you don't have a stack. } if (GroupByStartStopActivity) { m_startStopActivities = new StartStopActivityComputer(eventSource, m_activityComputer, IgnoreApplicationInsightsRequestsWithRelatedActivityId); // Maps thread Indexes to the start-stop activity that they are executing. m_threadToStartStopActivity = new StartStopActivity[m_eventLog.Threads.Count]; /********* Start Unknown Async State machine for StartStop activities ******/ // The delegates below along with the AddUnkownAsyncDurationIfNeeded have one purpose: // To inject UNKNOWN_ASYNC stacks when there is an active start-stop activity that is // 'missing' time. It has the effect of insuring that Start-Stop tasks always have // a metric that is not unrealistically small. m_activityComputer.Start += delegate(TraceActivity activity, TraceEvent data) { StartStopActivity newStartStopActivityForThread = m_startStopActivities.GetCurrentStartStopActivity(activity.Thread, data); UpdateThreadToWorkOnStartStopActivity(activity.Thread, newStartStopActivityForThread, data); }; m_activityComputer.AfterStop += delegate(TraceActivity activity, TraceEvent data, TraceThread thread) { StartStopActivity newStartStopActivityForThread = m_startStopActivities.GetCurrentStartStopActivity(thread, data); UpdateThreadToWorkOnStartStopActivity(thread, newStartStopActivityForThread, data); }; m_startStopActivities.Start += delegate(StartStopActivity startStopActivity, TraceEvent data) { // We only care about the top-most activities since unknown async time is defined as time // where a top most activity is running but no thread (or await time) is associated with it // fast out otherwise (we just insure that we mark the thread as doing this activity) if (startStopActivity.Creator != null) { UpdateThreadToWorkOnStartStopActivity(data.Thread(), startStopActivity, data); return; } // Then we have a refcount of exactly one Debug.Assert(m_unknownTimeStartMsec.Get((int)startStopActivity.Index) >= 0); // There was nothing running before. m_unknownTimeStartMsec.Set((int)startStopActivity.Index, -1); // Set it so just we are running. m_threadToStartStopActivity[(int)data.Thread().ThreadIndex] = startStopActivity; }; m_startStopActivities.Stop += delegate(StartStopActivity startStopActivity, TraceEvent data) { // We only care about the top-most activities since unknown async time is defined as time // where a top most activity is running but no thread (or await time) is associated with it // fast out otherwise if (startStopActivity.Creator != null) { return; } double unknownStartTime = m_unknownTimeStartMsec.Get((int)startStopActivity.Index); if (0 < unknownStartTime) { AddUnkownAsyncDurationIfNeeded(startStopActivity, unknownStartTime, data); } // Actually emit all the async unknown events. List <StackSourceSample> samples = m_startStopActivityToAsyncUnknownSamples.Get((int)startStopActivity.Index); if (samples != null) { foreach (var sample in samples) { m_outputStackSource.AddSample(sample); // Adding Unknown ASync } m_startStopActivityToAsyncUnknownSamples.Set((int)startStopActivity.Index, null); } m_unknownTimeStartMsec.Set((int)startStopActivity.Index, 0); Debug.Assert(m_threadToStartStopActivity[(int)data.Thread().ThreadIndex] == startStopActivity || m_threadToStartStopActivity[(int)data.Thread().ThreadIndex] == null); m_threadToStartStopActivity[(int)data.Thread().ThreadIndex] = null; }; } eventSource.Clr.GCAllocationTick += OnSampledProfile; eventSource.Clr.GCSampledObjectAllocation += OnSampledProfile; var eventPipeTraceEventPraser = new SampleProfilerTraceEventParser(eventSource); eventPipeTraceEventPraser.ThreadSample += OnSampledProfile; if (IncludeEventSourceEvents) { eventSource.Dynamic.All += delegate(TraceEvent data) { // TODO decide what the correct heuristic is. // Currently I only do this for things that might be an EventSoruce (uses the name->Guid hashing) // Most importantly, it excludes the high volume CLR providers. if (!TraceEventProviders.MaybeAnEventSource(data.ProviderGuid)) { return; } // We don't want most of the FrameworkEventSource events either. if (data.ProviderGuid == FrameworkEventSourceTraceEventParser.ProviderGuid) { if (!((TraceEventID)140 <= data.ID && data.ID <= (TraceEventID)143)) // These are the GetResponce and GetResestStream events { return; } } // We don't care about EventPipe sample profiler events. if (data.ProviderGuid == SampleProfilerTraceEventParser.ProviderGuid) { return; } // We don't care about the TPL provider. Too many events. if (data.ProviderGuid == TplEtwProviderTraceEventParser.ProviderGuid) { return; } // We don't care about ManifestData events. if (data.ID == (TraceEventID)0xFFFE) { return; } TraceThread thread = data.Thread(); if (thread == null) { return; } StackSourceCallStackIndex stackIndex = GetCallStack(data, thread); // Tack on additional info about the event. var fieldNames = data.PayloadNames; for (int i = 0; i < fieldNames.Length; i++) { var fieldName = fieldNames[i]; var value = data.PayloadString(i); var fieldNodeName = "EventData: " + fieldName + "=" + value; var fieldNodeIndex = m_outputStackSource.Interner.FrameIntern(fieldNodeName); stackIndex = m_outputStackSource.Interner.CallStackIntern(fieldNodeIndex, stackIndex); } stackIndex = m_outputStackSource.Interner.CallStackIntern(m_outputStackSource.Interner.FrameIntern("EventName: " + data.ProviderName + "/" + data.EventName), stackIndex); m_threadState[(int)thread.ThreadIndex].LogThreadStack(data.TimeStampRelativeMSec, stackIndex, thread, this, false); }; } eventSource.Process(); m_outputStackSource.DoneAddingSamples(); m_threadState = null; }
private static void GetRegisteredProvidersInProcess() { new List <string>(TraceEventProviders.GetRegisteredProvidersInProcess(System.Diagnostics.Process.GetCurrentProcess().Id) .Select(p => TraceEventProviders.GetProviderName(p))).ForEach(name => Debug.WriteLine(name)); }
public static bool ProcessCanBeMonitored(int processId) { return(TraceEventProviders .GetRegisteredProvidersInProcess(processId) .Contains(WcfProviderGuid)); }
/// <summary> /// Initializes a new instance of the <see cref="EtwEventDynamicProcessor"/> class. /// </summary> /// <param name="providerName">The name of the provider which events we are going to consume.</param> /// <param name="traceEventHandler">The callback which is called every time new event appears.</param> internal EtwEventDynamicProcessor(string providerName, Action <TraceEvent> traceEventHandler) { this.providerName = providerName; providerGuid = TraceEventProviders.GetEventSourceGuidFromName(providerName); this.traceEventHandler = traceEventHandler; }
public static EtwManifest ParseWmiEventTraceClass(Guid provider) { // we make a best effort attempt to fit the metadata of this Legacy (MOF) provider into the instrumentation manifest format // we need to find the EventTrace class where the Guid class qualifier matches our provider Guid // afaik you can't query for qualifiers...just classes and properties. :-/ // so we loop through all of the EventTrace classes and compare var providerSearcher = new ManagementObjectSearcher("root\\WMI", $"SELECT * FROM meta_class WHERE __superclass = 'EventTrace'", null); ManagementClass providerClass = null; foreach (ManagementClass candidateProviderClass in providerSearcher.Get()) { foreach (QualifierData qd in candidateProviderClass.Qualifiers) { if (qd.Name.ToLower() == "guid" && new Guid((string)qd.Value) == provider) { providerClass = candidateProviderClass; break; // found } } if (providerClass != null) { break; // found } } if (providerClass == null) { throw new ApplicationException($"Provider {provider} has no corresponding EventTrace class in WMI Repository"); // not found } var manifest = new EtwManifest(string.Empty) { ProviderGuid = provider, ProviderSymbol = (string)providerClass["__CLASS"] }; var events = new SortedDictionary <string, EtwEvent>(); var templates = new List <EtwTemplate>(); var stringTable = new Dictionary <string, string>(); // the provider name is usually in the Description Qualifier for the EventTrace class (but not always?) // and the keywords are properties for the EventTrace class // but we can already get both of these easily from Microsoft.Diagnostics.Tracing manifest.ProviderName = TraceEventProviders.GetProviderName(provider); manifest.Keywords = TraceEventProviders.GetProviderKeywords(provider).Select(info => new EtwKeyword { Name = info.Name, Mask = info.Value, Message = info.Description }).ToArray(); // event details are in the grandchildren of the top-level (EventTrace) provider class // WMI EventTrace children ~ a versioned category grouping // WMI EventTrace grandchildren ~ instrumentation manifest templates // note - event version can be set on the category and/or the event var templateNames = new SortedSet <string>(); var taskSearcher = new ManagementObjectSearcher("root\\WMI", $"SELECT * FROM meta_class WHERE __superclass = '{providerClass["__CLASS"]}'", null); foreach (ManagementClass categoryVersionClass in taskSearcher.Get()) { var categoryVersion = 0; var category = string.Empty; var categoryDescription = string.Empty; var displayName = string.Empty; foreach (QualifierData qd in categoryVersionClass.Qualifiers) { if (qd.Value.GetType() == typeof(Int32) && qd.Name.ToLower() == "eventversion") { categoryVersion = (Int32)qd.Value; } else if (qd.Value.GetType() == typeof(String) && qd.Name.ToLower() == "guid") { category = (string)qd.Value; } else if (qd.Value.GetType() == typeof(String) && qd.Name.ToLower() == "description") { categoryDescription = (string)qd.Value; } else if (qd.Value.GetType() == typeof(String) && qd.Name.ToLower() == "displayname") { displayName = (string)qd.Value; } } var templateSearcher = new ManagementObjectSearcher("root\\WMI", $"SELECT * FROM meta_class WHERE __superclass = '{categoryVersionClass["__CLASS"]}'", null); foreach (ManagementClass templateClass in templateSearcher.Get()) { // EventTypeName qualifier ~ OpCode var template = (string)templateClass["__CLASS"]; var eventType = string.Empty; var version = categoryVersion; var description = categoryDescription; foreach (QualifierData qd in templateClass.Qualifiers) { if (qd.Value.GetType() == typeof(Int32) && qd.Name.ToLower() == "eventversion") { version = (Int32)qd.Value; // override category version with specific event version } else if (qd.Value.GetType() == typeof(String) && qd.Name.ToLower() == "eventtypename") { eventType = (string)qd.Value; } else if (qd.Value.GetType() == typeof(String) && qd.Name.ToLower() == "description") { description = (string)qd.Value; } } if (!string.IsNullOrEmpty(categoryDescription)) { stringTable.Add(template, categoryDescription); } // EventType -> id(s) var ids = new SortedSet <Int32>(); foreach (QualifierData qd in templateClass.Qualifiers) { if (qd.Name.ToLower() == "eventtype") { if (qd.Value.GetType() == typeof(Int32)) { ids.Add((Int32)qd.Value); } else if (qd.Value.GetType().IsArray) { foreach (var element in (Array)qd.Value) { if (element.GetType() == typeof(Int32)) { ids.Add((Int32)element); } } } break; } } // sort by category, id, version foreach (var id in ids) { events.Add($"{category}{id,6}{version,6}", new EtwEvent { Value = id, Symbol = template, Opcode = eventType, Version = version, Template = template, Keyword = description, Task = category }); } // create a template from the properties var templateData = new SortedDictionary <int, EtwTemplateData>(); foreach (PropertyData pd in templateClass.Properties) { foreach (QualifierData qd in pd.Qualifiers) { if (qd.Value.GetType() == typeof(Int32) && qd.Name.ToLower() == "wmidataid") { var id = (int)qd.Value; templateData[id] = new EtwTemplateData { Name = pd.Name, Type = pd.Type.ToString() }; break; } } } templates.Add(new EtwTemplate(template, templateData.Values.ToArray())); } } manifest.Events = events.Values.ToArray(); manifest.Templates = templates.ToArray(); manifest.StringTable = stringTable; return(manifest); }
public void Writing_Message_To_Etw() { var resetEvent = new ManualResetEvent(false); var collectedEvents = new List <NLogEtwEventData>(5); var providerName = etwTarget.ProviderName.Render(LogEventInfo.CreateNullEvent()); using (var session = new TraceEventSession("SimpleMonitorSession")) { // Dynamic-Parser does not work with pure EventSource-objects session.Source.Registered.All += delegate(TraceEvent data) { if (data.Level == TraceEventLevel.Always) { return; // Not ours } collectedEvents.Add(new NLogEtwEventData(data) { EventId = 0, // Raw EventSource gives "random" EventId LoggerName = (string)data.PayloadByName("LoggerName"), Message = (string)data.PayloadByName("Message"), }); if (collectedEvents.Count == 5) { resetEvent.Set(); } }; session.Source.UnhandledEvents += delegate(TraceEvent data) { if ((int)data.ID == 0xFFFE) { return; // The EventSource manifest events show up as unhanded, filter them out. } }; var task = System.Threading.Tasks.Task.Run(() => session.Source.Process()); Thread.Sleep(1000); session.EnableProvider(providerName); Thread.Sleep(1000); // 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"); try { var eventSourceGuid = TraceEventProviders.GetEventSourceGuidFromName(providerName); session.DisableProvider(eventSourceGuid); } catch { Thread.Sleep(1000); var eventSourceGuid = TraceEventProviders.GetEventSourceGuidFromName(providerName); session.DisableProvider(eventSourceGuid); } Thread.Sleep(1000); logger.Fatal("don't log this one"); resetEvent.WaitOne(20000); } // assert collected events var expectedEvents = new NLogEtwEventData[] { new NLogEtwEventData { EventId = 0, ProviderName = providerName, TaskName = "Debug", Level = TraceEventLevel.Verbose, LoggerName = "A", Message = "DEBUG|A|test-debug" }, new NLogEtwEventData { EventId = 0, ProviderName = providerName, TaskName = "Info", Level = TraceEventLevel.Informational, LoggerName = "A", Message = "INFO|A|test-info" }, new NLogEtwEventData { EventId = 0, ProviderName = providerName, TaskName = "Warn", Level = TraceEventLevel.Warning, LoggerName = "A", Message = "WARN|A|test-warn" }, new NLogEtwEventData { EventId = 0, ProviderName = providerName, TaskName = "Error", Level = TraceEventLevel.Error, LoggerName = "A", Message = "ERROR|A|test-error" }, new NLogEtwEventData { EventId = 0, ProviderName = providerName, TaskName = "Fatal", Level = TraceEventLevel.Critical, LoggerName = "A", Message = "FATAL|A|test-fatal" } }; Assert.Equal(collectedEvents, expectedEvents); }
private static void RealTimeSession() { if (options.ParsedClrKeywords == 0 && options.ParsedKernelKeywords == KernelTraceEventParser.Keywords.None && options.ParsedFrameworkEventKeywords == 0 && options.OtherProviders.Count == 0) { Bail("No events to collect"); } Console.CancelKeyPress += (_, __) => CloseSession(); if (options.DurationInSeconds > 0) { Task.Delay(TimeSpan.FromSeconds(options.DurationInSeconds)) .ContinueWith(_ => CloseSession()); } using (session = new TraceEventSession("etrace-realtime-session")) { if (options.ParsedKernelKeywords != KernelTraceEventParser.Keywords.None) { session.EnableKernelProvider(options.ParsedKernelKeywords); } if (options.ParsedClrKeywords != 0) { session.EnableProvider(ClrTraceEventParser.ProviderGuid, matchAnyKeywords: (ulong)options.ParsedClrKeywords); } if (options.ParsedFrameworkEventKeywords != 0) { session.EnableProvider(FrameworkEventSourceTraceEventParser.ProviderGuid, matchAnyKeywords: (ulong)options.ParsedFrameworkEventKeywords); if (options.HttpStatsOnly) { var ep = eventProcessor as HttpEventStatisticsAggregator; ep.parser = new FrameworkEventSourceTraceEventParser(session.Source); ep.options = options; ep.SetupHttpStatsParsing(options); } else if (options.HttpLatencyStatsOnly) { var ep = eventProcessor as HttpEventStatisticsAggregator; ep.parser = new FrameworkEventSourceTraceEventParser(session.Source); ep.options = options; ep.SetupHttpLatencyParsing(options); } } if (options.OtherProviders.Any()) { foreach (var provider in options.OtherProviders) { Guid guid; if (Guid.TryParse(provider, out guid)) { session.EnableProvider(Guid.Parse(provider)); } else { guid = TraceEventProviders.GetProviderGuidByName(provider); if (guid != Guid.Empty) { session.EnableProvider(guid); } } } } ProcessTrace(session.Source); } }