public void Start(Process process) { _process = process; _counters = new SortedDictionary <string, string>(); _task = new Task(() => { var diagnosticsClient = new DiagnosticsClient(_process.Id); var providerList = new List <EventPipeProvider>() { new EventPipeProvider(name: "System.Runtime", keywords: long.MaxValue, eventLevel: EventLevel.Verbose, arguments: new Dictionary <string, string>() { { "EventCounterIntervalSec", "1" } }) }; _session = diagnosticsClient.StartEventPipeSession( providers: providerList, requestRundown: false); var source = new EventPipeEventSource(_session.EventStream); source.Dynamic.AddCallbackForProviderEvent("System.Runtime", "EventCounters", CounterEvent); source.Process(); }); _task.Start(); }
/// <summary> /// Запуск мониторинга /// </summary> /// <returns>Задача, которая выполняется в течение всего процесса мониторинга</returns> public async Task Start() { var client = new DiagnosticsClient(_pid); using var session = client.StartEventPipeSession(_providers, false); var streamTask = Task.Run(() => { var source = new EventPipeEventSource(session.EventStream); source.Dynamic.All += ProcessEvents; try { source.Process(); } catch (Exception ex) { session.Stop(); _logger.Error($"Error encountered while processing events from {_pid}:{ex}"); } }); var cancelTask = Task.Run(async() => { await _cancelTcs.Task; session.Stop(); _logger.Information($"Session stopped {_pid}"); }); await Task.WhenAny(streamTask, cancelTask); }
protected override async Task ExecuteAsync(CancellationToken cancellationToken) { await Task.Yield(); var providerList = new List <Provider>() { new Provider(name: "Microsoft-Extensions-Logging", keywords: (ulong)LoggingEventSource.Keywords.FormattedMessage, eventLevel: EventLevel.LogAlways) }; var configuration = new SessionConfiguration( circularBufferSizeMB: 1000, outputPath: "", providers: providerList); var binaryReader = EventPipeClient.CollectTracing(_options.ProcessId, configuration, out var sessionId); var source = new EventPipeEventSource(binaryReader); source.Dynamic.AddCallbackForProviderEvent("Microsoft-Extensions-Logging", "FormattedMessage", (traceEvent) => { // Level, FactoryID, LoggerName, EventID, EventName, FormattedMessage var categoryName = (string)traceEvent.PayloadValue(2); if (!loggerCache.ContainsKey(categoryName)) { loggerCache.TryAdd(categoryName, _loggerFactory.CreateLogger(categoryName)); } if (loggerCache.TryGetValue(categoryName, out var logger)) { var logLevel = (LogLevel)traceEvent.PayloadValue(0); switch (logLevel) { case LogLevel.Trace: logger.LogTrace((string)traceEvent.PayloadValue(4)); break; case LogLevel.Debug: logger.LogDebug((string)traceEvent.PayloadValue(4)); break; case LogLevel.Information: logger.LogInformation((string)traceEvent.PayloadValue(4)); break; case LogLevel.Warning: logger.LogWarning((string)traceEvent.PayloadValue(4)); break; case LogLevel.Error: logger.LogError((string)traceEvent.PayloadValue(4)); break; case LogLevel.Critical: logger.LogCritical((string)traceEvent.PayloadValue(4)); break; } } }); source.Process(); _lifetime.StopApplication(); }
private static void Run(string appName, IConfigurationRoot config) { var pid = FindPidByAppName(appName); if (pid == -1) { Console.WriteLine("Application is not running..."); throw new Exception("Application is not running..."); } var client = new DiagnosticsClient(pid); var intervalSeconds = config.GetSection("SampleIntervalInSeconds").Value; var evtProvider = EventPipeProviderHelper.ToProvider( $"System.Runtime:0xffffffff:5:EventCounterIntervalSec={intervalSeconds}"); var hostingProvider = EventPipeProviderHelper.ToProvider( $"Microsoft.AspNetCore.Hosting:0x0:4:EventCounterIntervalSec={intervalSeconds}"); var session = client.StartEventPipeSession(new[] { evtProvider, hostingProvider }, false); var source = new EventPipeEventSource(session.EventStream); source.Dynamic.All += Dynamic_All; source.Process(); Console.ReadKey(); session.Dispose(); source.Dispose(); }
public IEnumerable <Counter> Parse(string mergeTraceDirectory, string mergeTraceFilter, string processName, IList <int> pids, string commandLine) { var times = new List <double>(); var files = new HashSet <string>(); Console.WriteLine($"Finding files from {mergeTraceDirectory} with filter: {mergeTraceFilter}"); foreach (var file in Directory.GetFiles(mergeTraceDirectory, mergeTraceFilter)) { Console.WriteLine($"Found {file}"); files.Add(file); } foreach (var trace in files) { Console.WriteLine($"Parsing {trace}"); using (var source = new EventPipeEventSource(trace)) { source.Clr.MethodLoadVerbose += evt => { if (evt.MethodName == "Main") { times.Add(evt.TimeStampRelativeMSec); } }; source.Process(); } } return(new[] { new Counter() { Name = "Generic Startup", MetricName = "ms", DefaultCounter = true, TopCounter = true, Results = times.ToArray() } }); }
public EventPipeListener(int targetProcessId, IEnumerable <EventPipeProvider> providers) { var client = new DiagnosticsClient(targetProcessId); _listeningSession = client.StartEventPipeSession(providers); _eventSource = new EventPipeEventSource(_listeningSession.EventStream); _eventSource.Kernel.All += (TraceEvent @event) => KernelEvents?.Invoke(@event); _eventSource.Clr.All += (TraceEvent @event) => ClrEvents?.Invoke(@event); _eventSource.Dynamic.All += (TraceEvent @event) => CustomEvents?.Invoke(@event); Task.Factory.StartNew(() => _eventSource.Process(), _cts.Token, TaskCreationOptions.LongRunning, TaskScheduler.Default); //with a code like this we can output a memory dump depending on some threshold of CPU usage /* * _eventSource.Dynamic.All += (TraceEvent obj) => * { * if (obj.EventName.Equals("EventCounters")) * { * IDictionary<string, object> payloadVal = (IDictionary<string, object>)(obj.PayloadValue(0)); * IDictionary<string, object> payloadFields = (IDictionary<string, object>)(payloadVal["Payload"]); * if (payloadFields["Name"].ToString().Equals("cpu-usage")) * { * double cpuUsage = Double.Parse(payloadFields["Mean"]); * if (cpuUsage > (double)threshold) * { * client.WriteDump(DumpType.Normal, "./minidump.dmp"); * } * } * } * } */ }
/// <summary> /// This uses CopyToAsync to copy the trace into a filesystem first, and then uses EventPipeEventSource /// on the file to post-process it and return the total # of events read. /// </summary> static void UseFS(int pid) { int eventsRead = 0; const string fileName = "./temp.nettrace"; DiagnosticsClient client = new DiagnosticsClient(pid); EventPipeSession session = client.StartEventPipeSession(new EventPipeProvider("MySource", EventLevel.Verbose)); Console.WriteLine("session open"); using (FileStream fs = new FileStream(fileName, FileMode.Create, FileAccess.Write)) { Task copyTask = session.EventStream.CopyToAsync(fs); while (!copyTask.Wait(100)) { ; } } EventPipeEventSource epes = new EventPipeEventSource(fileName); epes.Dynamic.All += (TraceEvent data) => { eventsRead += 1; }; epes.Process(); Console.WriteLine("Used post processing."); Console.WriteLine("Read total: " + eventsRead.ToString()); Console.WriteLine("Dropped total: " + epes.EventsLost.ToString()); }
public static async Task <bool> TEST_TracesHaveRelevantEvents() { bool fSuccess = true; string serverName = ReverseServer.MakeServerAddress(); Logger.logger.Log($"Server name is '{serverName}'"); var server = new ReverseServer(serverName); using var memoryStream = new MemoryStream(); Task <bool> subprocessTask = Utils.RunSubprocess( currentAssembly: Assembly.GetExecutingAssembly(), environment: new Dictionary <string, string> { { Utils.DiagnosticPortsEnvKey, $"{serverName}" } }, duringExecution: async(pid) => { Stream stream = await server.AcceptAsync(); IpcAdvertise advertise = IpcAdvertise.Parse(stream); Logger.logger.Log(advertise.ToString()); var config = new SessionConfiguration( circularBufferSizeMB: 1000, format: EventPipeSerializationFormat.NetTrace, providers: new List <Provider> { new Provider("Microsoft-Windows-DotNETRuntimePrivate", 0x80000000, EventLevel.Verbose) }); Logger.logger.Log("Starting EventPipeSession over standard connection"); using Stream eventStream = EventPipeClient.CollectTracing(pid, config, out var sessionId); Logger.logger.Log($"Started EventPipeSession over standard connection with session id: 0x{sessionId:x}"); Task readerTask = eventStream.CopyToAsync(memoryStream); Logger.logger.Log($"Send ResumeRuntime Diagnostics IPC Command"); // send ResumeRuntime command (0x04=ProcessCommandSet, 0x01=ResumeRuntime commandid) var message = new IpcMessage(0x04, 0x01); Logger.logger.Log($"Sent: {message.ToString()}"); IpcMessage response = IpcClient.SendMessage(stream, message); Logger.logger.Log($"received: {response.ToString()}"); await Task.Delay(TimeSpan.FromSeconds(2)); Logger.logger.Log("Stopping EventPipeSession over standard connection"); EventPipeClient.StopTracing(pid, sessionId); await readerTask; Logger.logger.Log("Stopped EventPipeSession over standard connection"); } ); fSuccess &= await subprocessTask; memoryStream.Seek(0, SeekOrigin.Begin); using var source = new EventPipeEventSource(memoryStream); var parser = new ClrPrivateTraceEventParser(source); bool isStartupEventPresent = false; parser.StartupEEStartupStart += (eventData) => isStartupEventPresent = true; source.Process(); Logger.logger.Log($"isStartupEventPresent: {isStartupEventPresent}"); return(isStartupEventPresent && fSuccess); }
public bool Start(Action <TraceEvent> trigger, Func <TraceEvent, bool> filter = null) { if (IsStarted || Providers.Count == 0) { return(false); } this.Trigger = trigger ?? throw new ArgumentNullException(nameof(trigger)); this.Filter = filter; //foreach (var provider in Providers) //{ // var listener = new EventListener(); // EventListener.EnableEvents() //} Task.Run(() => { _session = _client.StartEventPipeSession(Providers, false); _source = new EventPipeEventSource(_session.EventStream); OnSubscribe(_source); _source.Dynamic.All += Dynamic_All; _source.Process(); }); IsStarted = true; return(true); }
public void V4EventPipeFileHasProcNumbers() { PrepareTestData(); const string eventPipeFileName = "eventpipe-dotnetcore3.0-win-x64-objver4.nettrace"; string eventPipeFilePath = Path.Combine(UnZippedDataDir, eventPipeFileName); using (var traceSource = new EventPipeEventSource(eventPipeFilePath)) { Assert.Equal(4, traceSource.NumberOfProcessors); int[] counts = new int[4]; Action <TraceEvent> handler = delegate(TraceEvent data) { Assert.True(data.ProcessorNumber >= 0 && data.ProcessorNumber < traceSource.NumberOfProcessors); counts[data.ProcessorNumber]++; }; var privateClr = new ClrPrivateTraceEventParser(traceSource); privateClr.All += handler; traceSource.Clr.All += handler; traceSource.Clr.MethodILToNativeMap -= handler; traceSource.Dynamic.All += handler; // Process traceSource.Process(); for (int i = 0; i < traceSource.NumberOfProcessors; i++) { Assert.NotEqual(0, counts[i]); } } }
public static async Task <bool> TEST_StandardConnectionStillWorksIfReverseConnectionIsBroken() { string serverName = ReverseServer.MakeServerAddress(); Logger.logger.Log($"Server name is '{serverName}'"); await RunSubprocess( serverName : serverName, duringExecution : async(int pid) => { var config = new SessionConfiguration( circularBufferSizeMB: 1000, format: EventPipeSerializationFormat.NetTrace, providers: new List <Provider> { new Provider("Microsoft-DotNETCore-SampleProfiler") }); Logger.logger.Log("Starting EventPipeSession over standard connection"); using Stream stream = EventPipeClient.CollectTracing(pid, config, out var sessionId); Logger.logger.Log($"Started EventPipeSession over standard connection with session id: 0x{sessionId:x}"); using var source = new EventPipeEventSource(stream); Task readerTask = Task.Run(() => source.Process()); await Task.Delay(500); Logger.logger.Log("Stopping EventPipeSession over standard connection"); EventPipeClient.StopTracing(pid, sessionId); await readerTask; Logger.logger.Log("Stopped EventPipeSession over standard connection"); } ); return(true); }
static void PrintRuntime(int processId) { var providers = new List <EventPipeProvider>() { new EventPipeProvider("Microsoft-Windows-DotNETRuntime", EventLevel.Informational, (long)ClrTraceEventParser.Keywords.GC) }; var client = new DiagnosticsClient(processId); using (var session = client.StartEventPipeSession(providers, false)) { var source = new EventPipeEventSource(session.EventStream); source.Clr.All += (TraceEvent obj) => { Console.WriteLine(obj.EventName); }; try { source.Process(); } catch (Exception e) { Console.WriteLine(e.ToString()); } } }
public bool Start(Action <TraceEvent> trigger, Action <EventPipeEventSource> onSubscribe, Func <TraceEvent, bool> filter = null) { if (IsStarted || Providers.Count == 0) { return(false); } this.Trigger = trigger; this.Filter = filter; Task.Run(() => { if (!StartSession()) { Console.WriteLine($"Could not start the session - aborting"); // TODO: better exit return; } // resuming remote process _client.ResumeRuntime(); _source = new EventPipeEventSource(_session.EventStream); onSubscribe(_source); _source.Dynamic.All += Dynamic_All; _source.Process(); }); IsStarted = true; return(true); }
private static void PrintRuntimeGCEvents(string file) { var source = new EventPipeEventSource(file); // https://devblogs.microsoft.com/dotnet/glad-part-2/ source.NeedLoadedDotNetRuntimes(); source.AddCallbackOnProcessStart(proc => { proc.AddCallbackOnDotNetRuntimeLoad(runtime => { runtime.GCEnd += RuntimeOnGCEnd; }); }); //source.Clr.All += (TraceEvent obj) => { Console.WriteLine(obj.EventName); }; try { source.Process(); } // NOTE: This exception does not currently exist. It is something that needs to be added to TraceEvent. catch (Exception e) { Console.WriteLine("Error encountered while processing events"); Console.WriteLine(e.ToString()); } }
public static async Task <bool> TEST_ReverseConnectionCanRecycleWhileTracing() { bool fSuccess = true; string serverName = ReverseServer.MakeServerAddress(); Logger.logger.Log($"Server name is '{serverName}'"); Task <bool> subprocessTask = Utils.RunSubprocess( currentAssembly: Assembly.GetExecutingAssembly(), environment: new Dictionary <string, string> { { Utils.DiagnosticsMonitorAddressEnvKey, serverName }, { Utils.DiagnosticsMonitorPauseOnStartEnvKey, "0" } }, duringExecution: async(int pid) => { ManualResetEvent mre = new ManualResetEvent(false); Task regularTask = Task.Run(async() => { try { var config = new SessionConfiguration( circularBufferSizeMB: 1000, format: EventPipeSerializationFormat.NetTrace, providers: new List <Provider> { new Provider("Microsoft-DotNETCore-SampleProfiler") }); Logger.logger.Log("Starting EventPipeSession over standard connection"); using Stream stream = EventPipeClient.CollectTracing(pid, config, out var sessionId); Logger.logger.Log($"Started EventPipeSession over standard connection with session id: 0x{sessionId:x}"); using var source = new EventPipeEventSource(stream); Task readerTask = Task.Run(() => source.Process()); await Task.Delay(500); Logger.logger.Log("Stopping EventPipeSession over standard connection"); EventPipeClient.StopTracing(pid, sessionId); await readerTask; Logger.logger.Log("Stopped EventPipeSession over standard connection"); } finally { mre.Set(); } }); Task reverseTask = Task.Run(async() => { while (!mre.WaitOne(0)) { var ad1 = await ReverseServer.CreateServerAndReceiveAdvertisement(serverName); Logger.logger.Log(ad1.ToString()); } }); await Task.WhenAll(reverseTask, regularTask); } ); fSuccess &= await subprocessTask; return(fSuccess); }
/// <summary> /// This uses CopyTo to copy the trace into a filesystem first, and then uses EventPipeEventSource /// on the file to post-process it and return the total # of events read. /// </summary> static Func <int, TestResult> UseFS(bool rundown, int bufferSize) { return((int pid) => { int eventsRead = 0; var totalTimeSw = new Stopwatch(); const string fileName = "./temp.nettrace"; EventPipeSession session = GetSession(pid, rundown, bufferSize); Console.WriteLine("Session created."); using (FileStream fs = new FileStream(fileName, FileMode.Create, FileAccess.Write)) { totalTimeSw.Start(); session.EventStream.CopyTo(fs); totalTimeSw.Stop(); } EventPipeEventSource epes = new EventPipeEventSource(fileName); epes.Dynamic.All += (TraceEvent data) => { eventsRead += 1; }; epes.Process(); Console.WriteLine("Read total: " + eventsRead.ToString()); Console.WriteLine("Dropped total: " + epes.EventsLost.ToString()); return new TestResult(eventsRead, epes.EventsLost, totalTimeSw.Elapsed); }); }
public Task StartAsync(CancellationToken cancellationToken) { m_RunningTask = Task.Factory.StartNew( () => m_EventSource.Process(), TaskCreationOptions.LongRunning); return(Task.CompletedTask); }
/// <summary> /// Verifies that an event stream does provide events. /// </summary> private Task VerifyEventStreamProvidesEventsAsync(IpcEndpointInfo info, EventPipeSession session, int sessionNumber) { Assert.NotNull(session); Assert.NotNull(session.EventStream); return(Task.Run(async() => { _outputHelper.WriteLine($"{info.RuntimeInstanceCookie}: Session #{sessionNumber} - Creating event source."); // This blocks for a while due to this bug: https://github.com/microsoft/perfview/issues/1172 using var eventSource = new EventPipeEventSource(session.EventStream); _outputHelper.WriteLine($"{info.RuntimeInstanceCookie}: Session #{sessionNumber} - Setup event handlers."); // Create task completion source that is completed when any events are provided; cancel it if cancellation is requested var receivedEventsSource = new TaskCompletionSource <object>(TaskCreationOptions.RunContinuationsAsynchronously); using var cancellation = new CancellationTokenSource(TimeSpan.FromMinutes(1)); using var _ = cancellation.Token.Register(() => { if (receivedEventsSource.TrySetCanceled()) { _outputHelper.WriteLine($"{info.RuntimeInstanceCookie}: Session #{sessionNumber} - Cancelled event processing."); } }); // Create continuation task that stops the session (which immediately stops event processing). Task stoppedProcessingTask = receivedEventsSource.Task .ContinueWith(_ => { _outputHelper.WriteLine($"{info.RuntimeInstanceCookie}: Session #{sessionNumber} - Stopping session."); session.Stop(); }); // Signal task source when an event is received. Action <TraceEvent> allEventsHandler = _ => { if (receivedEventsSource.TrySetResult(null)) { _outputHelper.WriteLine($"{info.RuntimeInstanceCookie}: Session #{sessionNumber} - Received an event and set result on completion source."); } }; _outputHelper.WriteLine($"{info.RuntimeInstanceCookie}: Session #{sessionNumber} - Start processing events."); eventSource.Dynamic.All += allEventsHandler; eventSource.Process(); eventSource.Dynamic.All -= allEventsHandler; _outputHelper.WriteLine($"{info.RuntimeInstanceCookie}: Session #{sessionNumber} - Stopped processing events."); // Wait on the task source to verify if it ran to completion or was cancelled. await receivedEventsSource.Task; _outputHelper.WriteLine($"{info.RuntimeInstanceCookie}: Session #{sessionNumber} - Waiting for session to stop."); await stoppedProcessingTask; })); }
public static void Main(string[] args) { WriteNetPerf(args[0]); var source = new EventPipeEventSource(args[0]); if (source.Process()) { Console.WriteLine("NetTrace file successfully written."); } }
public static async Task <bool> TEST_CanConnectServerAndClientAtSameTime() { bool fSuccess = true; string serverName = ReverseServer.MakeServerAddress(); Logger.logger.Log($"Server name is '{serverName}'"); var server = new ReverseServer(serverName); Task <bool> subprocessTask = Utils.RunSubprocess( currentAssembly: Assembly.GetExecutingAssembly(), environment: new Dictionary <string, string> { { Utils.DiagnosticsMonitorAddressEnvKey, serverName }, { Utils.DiagnosticsMonitorPauseOnStartEnvKey, "0" } }, duringExecution: async(int pid) => { Task reverseTask = Task.Run(async() => { Logger.logger.Log($"Waiting for reverse connection"); Stream reverseStream = await server.AcceptAsync(); Logger.logger.Log("Got reverse connection"); IpcAdvertise advertise = IpcAdvertise.Parse(reverseStream); Logger.logger.Log(advertise.ToString()); }); Task regularTask = Task.Run(async() => { var config = new SessionConfiguration( circularBufferSizeMB: 1000, format: EventPipeSerializationFormat.NetTrace, providers: new List <Provider> { new Provider("Microsoft-DotNETCore-SampleProfiler") }); Logger.logger.Log("Starting EventPipeSession over standard connection"); using Stream stream = EventPipeClient.CollectTracing(pid, config, out var sessionId); Logger.logger.Log($"Started EventPipeSession over standard connection with session id: 0x{sessionId:x}"); using var source = new EventPipeEventSource(stream); Task readerTask = Task.Run(() => source.Process()); await Task.Delay(500); Logger.logger.Log("Stopping EventPipeSession over standard connection"); EventPipeClient.StopTracing(pid, sessionId); await readerTask; Logger.logger.Log("Stopped EventPipeSession over standard connection"); }); await Task.WhenAll(reverseTask, regularTask); } ); fSuccess &= await Utils.WaitTillTimeout(subprocessTask, TimeSpan.FromMinutes(1)); server.Shutdown(); return(fSuccess); }
static void Main(string[] args) { // Find the process containing the target EventSource. var targetProcess = DiagnosticsClient.GetPublishedProcesses() .Select(Process.GetProcessById) .FirstOrDefault(process => process?.ProcessName == "Metrics"); if (targetProcess == null) { Console.WriteLine("No process named 'Metrics' found. Exiting."); return; } // Define what EventSource and events to listen to. var providers = new List <EventPipeProvider>() { new EventPipeProvider("My-CustomMetricsEventSource-Minimal", EventLevel.Informational, arguments: new Dictionary <string, string> { { "EventCounterIntervalSec", "1" } }) }; // Start listening session var client = new DiagnosticsClient(targetProcess.Id); using var session = client.StartEventPipeSession(providers, false); using var source = new EventPipeEventSource(session.EventStream); // Set up output writer source.Dynamic.All += obj => { if (obj.EventName == "EventCounters") { var payload = (IDictionary <string, object>)obj.PayloadValue(0); Console.WriteLine(string.Join(", ", payload.Select(p => $"{p.Key}: {p.Value}"))); } else { Console.WriteLine($"{obj.ProviderName}: {obj.EventName}"); } }; try { source.Process(); } catch (Exception e) { Console.WriteLine("Error encountered while processing events"); Console.WriteLine(e.ToString()); } Console.ReadKey(); }
private static void MonitorGCEvents(int processId) { var client = new DiagnosticsClient(processId); using var session = client.StartEventPipeSession(new EventPipeProvider("Microsoft-Windows-DotNETRuntime", EventLevel.Informational, 1)); EventPipeEventSource source = new EventPipeEventSource(session.EventStream); source.Clr.GCStart += Clr_GCStart; source.Process(); }
private static void Main(string[] args) { if (args.Length < 2) { Console.WriteLine("triggerdump <pid> <mem threshold in MB>"); } else { pid = Convert.ToInt32(args[0]); threshold = Convert.ToInt32(args[1]); Task monitorTask = new Task(() => { var prov = new List <Provider>(); prov.Add(new Provider("System.Runtime", filterData: "EventCounterIntervalSec=1")); var configuration = new SessionConfiguration( circularBufferSizeMB: 1000, outputPath: "", providers: prov); var binaryReader = EventPipeClient.CollectTracing(Int32.Parse(args[0]), configuration, out _sessionId); EventPipeEventSource source = new EventPipeEventSource(binaryReader); source.Dynamic.All += Dynamic_All; source.Process(); }); Task commandTask = new Task(() => { while (true) { while (!Console.KeyAvailable) { } ConsoleKey cmd = Console.ReadKey(true).Key; if (cmd == ConsoleKey.Q) { break; } } }); monitorTask.Start(); commandTask.Start(); commandTask.Wait(); try { EventPipeClient.StopTracing(Int32.Parse(args[0]), _sessionId); } catch (System.IO.EndOfStreamException) {} } }
// Use EventPipe CollectTracing command to start monitoring. This may throw. private void RequestTracingV1(string providerString) { var configuration = new SessionConfiguration( circularBufferSizeMB: 1000, format: EventPipeSerializationFormat.NetTrace, providers: Trace.Extensions.ToProviders(providerString)); var binaryReader = EventPipeClient.CollectTracing(_processId, configuration, out _sessionId); EventPipeEventSource source = new EventPipeEventSource(binaryReader); source.Dynamic.All += Dynamic_All; source.Process(); }
public void Start() { Task.Run(() => { try { var client = new DiagnosticsClient(_pid); _session = client.StartEventPipeSession(_providers, false); using var source = new EventPipeEventSource(_session.EventStream); source.NeedLoadedDotNetRuntimes(); source.AddCallbackOnProcessStart(proc => { if (proc.ProcessID != _pid) { return; } proc.AddCallbackOnDotNetRuntimeLoad(runtime => { runtime.GCEnd += (process, gc) => { var key = $"gen-{gc.Generation}-gc-collection-count"; _collectedStats.TryGetValue(key, out var collected); _collectedStats[key] = ++collected; }; }); }); source.Dynamic.All += obj => { if (obj.EventName.Equals("EventCounters")) { var payload = (IDictionary <string, object>)obj.PayloadValue(0); var pairs = (IDictionary <string, object>)(payload["Payload"]); var name = string.Intern(pairs["Name"].ToString()); var counterType = pairs["CounterType"]; if (counterType.Equals("Sum")) { _collectedStats[name] = double.Parse(pairs["Increment"].ToString()); } if (counterType.Equals("Mean")) { _collectedStats[name] = double.Parse(pairs["Mean"].ToString()); } } }; source.Process(); } catch (ObjectDisposedException) { // ignore exception on shutdown } catch (Exception exception) { Log.Warning(exception, "Error encountered while processing events"); } }); }
public void Start(int processId = 0) { selectedProcessId = processId == 0 ? Environment.ProcessId : processId; var client = new DiagnosticsClient(selectedProcessId); using var eventPipeSession = client.StartEventPipeSession(GetProvider()); using var source = new EventPipeEventSource(eventPipeSession.EventStream); RegisterListeners(source); // this is a blocking call source.Process(); }
public async Task Process(int pid, TimeSpan duration, CancellationToken token) { await await Task.Factory.StartNew(async() => { EventPipeEventSource source = null; DiagnosticsMonitor monitor = null; try { MonitoringSourceConfiguration config = null; if (_mode == PipeMode.Logs) { config = new LoggingSourceConfiguration(); } if (_mode == PipeMode.Metrics) { config = new MetricSourceConfiguration(); } monitor = new DiagnosticsMonitor(config); Stream sessionStream = await monitor.ProcessEvents(pid, duration, token); source = new EventPipeEventSource(sessionStream); if (_mode == PipeMode.Metrics) { // Metrics HandleEventCounters(source); } if (_mode == PipeMode.Logs) { // Logging HandleLoggingEvents(source); } source.Process(); } catch (DiagnosticsClientException ex) { throw new InvalidOperationException("Failed to start the event pipe session", ex); } finally { source?.Dispose(); if (monitor != null) { await monitor.DisposeAsync(); } } }, token, TaskCreationOptions.LongRunning, TaskScheduler.Default); }
private void ProcessEvents() { using var source = new EventPipeEventSource(_eventStream); source.Dynamic.AddCallbackForProviderEvent(_MicrosoftExtensionsLoggingProviderName, "FormattedMessage", (traceEvent) => { // Level, FactoryID, LoggerName, EventID, EventName, FormattedMessage var categoryName = (string)traceEvent.PayloadValue(2); var logger = _loggerFactory.CreateLogger(categoryName); var logLevel = (LogLevel)traceEvent.PayloadValue(0); var message = (string)traceEvent.PayloadValue(4); logger.Log(logLevel, message); }); source.Process(); }
public static async Task <bool> TEST_CanConnectServerAndClientAtSameTime() { string serverName = ReverseServer.MakeServerAddress(); Logger.logger.Log($"Server name is '{serverName}'"); var server = new ReverseServer(serverName); await RunSubprocess( serverName : serverName, duringExecution : async(int pid) => { Task reverseTask = Task.Run(async() => { Logger.logger.Log($"Waiting for reverse connection"); Stream reverseStream = await server.AcceptAsync(); Logger.logger.Log("Got reverse connection"); IpcAdvertise advertise = IpcAdvertise.Parse(reverseStream); Logger.logger.Log(advertise.ToString()); }); Task regularTask = Task.Run(async() => { var config = new SessionConfiguration( circularBufferSizeMB: 1000, format: EventPipeSerializationFormat.NetTrace, providers: new List <Provider> { new Provider("Microsoft-DotNETCore-SampleProfiler") }); Logger.logger.Log("Starting EventPipeSession over standard connection"); using Stream stream = EventPipeClient.CollectTracing(pid, config, out var sessionId); Logger.logger.Log($"Started EventPipeSession over standard connection with session id: 0x{sessionId:x}"); using var source = new EventPipeEventSource(stream); Task readerTask = Task.Run(() => source.Process()); await Task.Delay(500); Logger.logger.Log("Stopping EventPipeSession over standard connection"); EventPipeClient.StopTracing(pid, sessionId); await readerTask; Logger.logger.Log("Stopped EventPipeSession over standard connection"); }); await Task.WhenAll(reverseTask, regularTask); } ); server.Shutdown(); return(true); }
public void Start() { using (var session = client.StartEventPipeSession(providers, false)) using (var source = new EventPipeEventSource(session.EventStream)) { _session = session; _source = source; _source.Clr.All += Trigger; try { _source?.Process(); } catch (DiagnosticsClientException) { } } }