public static async Task <int> GetActivePorts(IConsole console) { try { var processes = EventPipeClient.ListAvailablePorts() .Select(GetProcessById) .Where(process => process != null) .OrderBy(process => process.ProcessName) .ThenBy(process => process.Id); foreach (var process in processes) { try { Console.Out.WriteLine($"{process.Id, 10} {process.ProcessName, -10} {process.MainModule.FileName}"); } catch (Exception) { Console.Out.WriteLine($"{process.Id, 10} {process.ProcessName, -10} [Elevated process - cannot determine path]"); } } await Task.FromResult(0); return(0); } catch (Exception ex) { Console.Error.WriteLine($"[ERROR] {ex.ToString()}"); return(1); } }
/// <summary> /// Print the current list of available .NET core processes for diagnosis and their statuses /// </summary> public static void PrintProcessStatus(IConsole console) { try { StringBuilder sb = new StringBuilder(); var processes = EventPipeClient.ListAvailablePorts() .Select(GetProcessById) .Where(process => process != null) .OrderBy(process => process.ProcessName) .ThenBy(process => process.Id); foreach (var process in processes) { try { sb.Append($"{process.Id, 10} {process.ProcessName, -10} {process.MainModule.FileName}\n"); } catch (InvalidOperationException) { sb.Append($"{process.Id, 10} {process.ProcessName, -10} [Elevated process - cannot determine path]\n"); } } console.Out.WriteLine(sb.ToString()); } catch (InvalidOperationException ex) { console.Out.WriteLine(ex.ToString()); } }
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(); }
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); }
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); }
private void StopMonitor() { try { EventPipeClient.StopTracing(_processId, _sessionId); } catch (EndOfStreamException ex) { // If the app we're monitoring exits abruptly, this may throw in which case we just swallow the exception and exit gracefully. Debug.WriteLine($"[ERROR] {ex.ToString()}"); } // We may time out if the process ended before we sent StopTracing command. We can just exit in that case. catch (TimeoutException) { } // On Unix platforms, we may actually get a PNSE since the pipe is gone with the process, and Runtime Client Library // does not know how to distinguish a situation where there is no pipe to begin with, or where the process has exited // before dotnet-counters and got rid of a pipe that once existed. // Since we are catching this in StopMonitor() we know that the pipe once existed (otherwise the exception would've // been thrown in StartMonitor directly) catch (PlatformNotSupportedException) { } _renderer.Stop(); }
public async Task <int> Monitor(CancellationToken ct, List <string> counter_list, IConsole console, int processId, int refreshInterval) { try { _ct = ct; _counterList = counter_list; // NOTE: This variable name has an underscore because that's the "name" that the CLI displays. System.CommandLine doesn't like it if we change the variable to camelcase. _console = console; _processId = processId; _interval = refreshInterval; return(await StartMonitor()); } catch (OperationCanceledException) { try { EventPipeClient.StopTracing(_processId, _sessionId); } catch (Exception) {} // Swallow all exceptions for now. console.Out.WriteLine($"Complete"); return(1); } }
private static void SendInvalidDiagnosticsMessageTypeCommand() { Console.WriteLine("Send a wrong message type as the diagnostic header header."); ulong sessionId = 0; try { byte[] bytes; using (var stream = new MemoryStream()) { using (var bw = new BinaryWriter(stream)) { bw.Write(uint.MaxValue); bw.Write(ThisProcess.Id); bw.Flush(); stream.Position = 0; bytes = new byte[stream.Length]; stream.Read(bytes, 0, bytes.Length); } } sessionId = EventPipeClient.SendCommand(ThisProcess.Id, bytes); } catch (EndOfStreamException) { Assert.Equal("EventPipe Session Id", sessionId, (ulong)0); } catch { Assert.True("Send command threw unexpected exception", false); } }
private static void SendSmallerHeaderCommand() { Console.WriteLine("Send a small payload as header."); ulong sessionId = 0; try { byte[] bytes; using (var stream = new MemoryStream()) { using (var bw = new BinaryWriter(stream)) { bw.Write((uint)DiagnosticsMessageType.StartEventPipeTracing); bw.Flush(); stream.Position = 0; bytes = new byte[stream.Length]; stream.Read(bytes, 0, bytes.Length); } } sessionId = EventPipeClient.SendCommand(ThisProcess.Id, bytes); } catch (EndOfStreamException) { Assert.Equal("EventPipe Session Id", sessionId, (ulong)0); } catch { Assert.True("Send command threw unexpected exception", false); } }
private static void SendInvalidPayloadToCollectCommand() { Console.WriteLine("Send Invalid Payload To Collect Command."); ulong sessionId = 0; try { uint circularBufferSizeMB = 64; var filePath = Path.Combine( Directory.GetCurrentDirectory(), $"dotnetcore-eventpipe-{ThisProcess.Id}.nettrace"); var providers = new[] { new Provider(name: "Microsoft-Windows-DotNETRuntime"), }; var configuration = new SessionConfiguration(circularBufferSizeMB, filePath, providers); // Start session #1. sessionId = EventPipeClient.StartTracingToFile( processId: ThisProcess.Id, configuration: configuration); // Check that a session was created. Assert.Equal("EventPipe Session Id", sessionId, (ulong)0); } finally { if (sessionId != 0) { EventPipeClient.StopTracing(ThisProcess.Id, sessionId); } } }
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); }
public void Stop() { if (_sessionId == EmptySession) { throw new InvalidOperationException("Start() must be called to start the session"); } EventPipeClient.StopTracing(Process.GetCurrentProcess().Id, _sessionId); }
// Use EventPipe CollectTracing command to start monitoring. This may throw. private EventPipeEventSource 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); return(new EventPipeEventSource(binaryReader)); }
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); }
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) {} } }
private void StopMonitor() { try { EventPipeClient.StopTracing(_processId, _sessionId); } catch (EndOfStreamException ex) { // If the app we're monitoring exits abruptly, this may throw in which case we just swallow the exception and exit gracefully. Debug.WriteLine($"[ERROR] {ex.ToString()}"); } }
// Use EventPipe CollectTracing2 command to start monitoring. This may throw. private void RequestTracingV2(string providerString) { var configuration = new SessionConfigurationV2( circularBufferSizeMB: 1000, format: EventPipeSerializationFormat.NetTrace, requestRundown: false, providers: Trace.Extensions.ToProviders(providerString)); var binaryReader = EventPipeClient.CollectTracing2(_processId, configuration, out _sessionId); EventPipeEventSource source = new EventPipeEventSource(binaryReader); source.Dynamic.All += Dynamic_All; source.Process(); }
public EventPipeSession(int pid, List <Provider> providers, bool requestRundown = true) { _pid = pid; _providers = providers; var config = new SessionConfigurationV2( circularBufferSizeMB: 1024, format: EventPipeSerializationFormat.NetTrace, requestRundown: requestRundown, providers ); _eventPipeStream = EventPipeClient.CollectTracing2(pid, config, out _sessionId); _source = new EventPipeEventSource(_eventPipeStream); }
private static int ListProcesses(IConsole console) { var processes = EventPipeClient.ListAvailablePorts() .Select(System.Diagnostics.Process.GetProcessById) .Where(process => process != null) .OrderBy(process => process.ProcessName) .ThenBy(process => process.Id); foreach (var process in processes) { console.Out.WriteLine($"{process.Id, 10} {process.ProcessName, -10} {process.MainModule.FileName}"); } return(0); }
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); }
private void ProcessEventPipeEvents() { var configuration = new SessionConfiguration( circularBufferSizeMB: 1000, format: EventPipeSerializationFormat.NetTrace, providers: GetProviders() ); var binaryReader = EventPipeClient.CollectTracing(_processId, configuration, out var sessionId); EventPipeEventSource source = new EventPipeEventSource(binaryReader); RegisterListeners(source); // this is a blocking call source.Process(); }
public void Start() { var configuration = new SessionConfiguration( circularBufferSizeMB: 1000, format: EventPipeSerializationFormat.NetTrace, providers: _providers ); var binaryReader = EventPipeClient.CollectTracing(_pid, configuration, out _sessionId); EventPipeEventSource source = new EventPipeEventSource(binaryReader); source.Dynamic.All += ProcessEvents; // this is a blocking call source.Process(); }
public static async Task <int> Stop(IConsole console, int processId, ulong sessionId) { try { EventPipeClient.StopTracing(processId, sessionId); await Task.FromResult(0); return(sessionId != 0 ? 0 : 1); } catch (Exception ex) { Console.Error.WriteLine($"[ERROR] {ex.ToString()}"); return(1); } }
public static async Task <bool> TEST_ReverseConnectionCanRecycleWhileTracing() { string serverName = ReverseServer.MakeServerAddress(); Logger.logger.Log($"Server name is '{serverName}'"); await RunSubprocess( serverName : serverName, duringExecution : async(int pid) => { 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"); }); Task reverseTask = Task.Run(async() => { var ad1 = await WaitTillTimeout(ReverseServer.CreateServerAndReceiveAdvertisement(serverName), TimeSpan.FromMilliseconds(_maxPollTimeMS)); Logger.logger.Log(ad1.ToString()); var ad2 = await WaitTillTimeout(ReverseServer.CreateServerAndReceiveAdvertisement(serverName), TimeSpan.FromMilliseconds(_maxPollTimeMS)); Logger.logger.Log(ad2.ToString()); var ad3 = await WaitTillTimeout(ReverseServer.CreateServerAndReceiveAdvertisement(serverName), TimeSpan.FromMilliseconds(_maxPollTimeMS)); Logger.logger.Log(ad3.ToString()); var ad4 = await WaitTillTimeout(ReverseServer.CreateServerAndReceiveAdvertisement(serverName), TimeSpan.FromMilliseconds(_maxPollTimeMS)); Logger.logger.Log(ad4.ToString()); }); await Task.WhenAll(reverseTask, regularTask); } ); return(true); }
public void Start(ILogger logger) { var configuration = new SessionConfiguration( circularBufferSizeMB: 1000, format: EventPipeSerializationFormat.NetTrace, providers: GetProviders() ); var ports = EventPipeClient.ListAvailablePorts(); logger.LogDebug($"IPC available ports for the performance monitoring session: {string.Join("-", ports)}."); using var binaryReader = EventPipeClient.CollectTracing(Process.GetCurrentProcess().Id, configuration, out _sessionId); using var source = new EventPipeEventSource(binaryReader); source.Dynamic.All += ProcessEvents; source.Process(); }
public static async Task <bool> TEST_ServerIsResilientToNoBufferAgent() { bool fSuccess = true; // N.B. - this test is only testing behavior on Windows since Unix Domain Sockets get their buffer size from the // system configuration and isn't set here. Tests passing on Windows should indicate it would pass on Unix systems as well. string serverName = ReverseServer.MakeServerAddress(); Logger.logger.Log($"Server name is '{serverName}'"); var server = new ReverseServer(serverName, 0); Task <bool> subprocessTask = Utils.RunSubprocess( currentAssembly: Assembly.GetExecutingAssembly(), environment: new Dictionary <string, string> { { Utils.DiagnosticsMonitorAddressEnvKey, serverName }, { Utils.DiagnosticsMonitorPauseOnStartEnvKey, "0" } }, duringExecution: async(int pid) => { var config = new SessionConfiguration( circularBufferSizeMB: 10, 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"); } ); fSuccess &= await Utils.WaitTillTimeout(subprocessTask, TimeSpan.FromMinutes(1)); server.Shutdown(); return(fSuccess); }
public void Start() { // single exe publishing not happy with trace package -- wait on https://github.com/dotnet/sdk/issues/3510 //return; var configuration = new SessionConfiguration( circularBufferSizeMB: 1000, format: EventPipeSerializationFormat.NetTrace, providers: _providers ); var binaryReader = EventPipeClient.CollectTracing(_pid, configuration, out _sessionId); EventPipeEventSource source = new EventPipeEventSource(binaryReader); source.Dynamic.All += ProcessEvents; // this is a blocking call source.Process(); }
public static async Task RunSubprocess(string serverName, Func <Task> beforeExecution = null, Func <int, Task> duringExecution = null, Func <Task> afterExecution = null) { using (var process = new Process()) { if (beforeExecution != null) { await beforeExecution(); } process.StartInfo.UseShellExecute = false; process.StartInfo.CreateNoWindow = true; process.StartInfo.Environment.Add("DOTNET_DiagnosticsMonitorAddress", serverName); process.StartInfo.FileName = Process.GetCurrentProcess().MainModule.FileName; process.StartInfo.Arguments = new Uri(Assembly.GetExecutingAssembly().CodeBase).LocalPath + " 0"; Logger.logger.Log($"running sub-process: {process.StartInfo.FileName} {process.StartInfo.Arguments}"); bool fSuccess = process.Start(); Logger.logger.Log($"subprocess started: {fSuccess}"); Logger.logger.Log($"subprocess PID: {process.Id}"); while (!EventPipeClient.ListAvailablePorts().Contains(process.Id)) { await Task.Delay(100); } try { if (duringExecution != null) { await duringExecution(process.Id); } } finally { process.Kill(); } if (afterExecution != null) { await afterExecution(); } } }
protected override async Task ExecuteAsync(CancellationToken cancellationToken) { cancellationToken.Register(() => { _optionsReloadToken?.Dispose(); EventPipeClient.StopTracing(_logViewerOptions.ProcessId, _sessionId); }); while (!cancellationToken.IsCancellationRequested) { BuildConfiguration(); _eventStream = EventPipeClient.CollectTracing2(_logViewerOptions.ProcessId, _configuration, out _sessionId); await Task.Run(() => ProcessEvents()); } if (!cancellationToken.IsCancellationRequested) { _lifetime.StopApplication(); } }
public static async Task <bool> TEST_ServerWorksIfClientDoesntAccept() { 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) => { var config = new SessionConfiguration( circularBufferSizeMB: 10, 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"); } ); fSuccess &= await subprocessTask; server.Shutdown(); return(true); }