示例#1
0
        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();
        }
示例#2
0
        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);
        }
示例#3
0
        /// <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());
        }
示例#4
0
        /// <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);
        }
示例#5
0
        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();
        }
示例#6
0
        public IDisposable Attach(EventPipeEventSource source, ReplicaInfo replicaInfo)
        {
            var store = replicaInfo.Metrics;

            source.Dynamic.All += traceEvent =>
            {
                try
                {
                    // Metrics
                    if (traceEvent.EventName.Equals("EventCounters"))
                    {
                        var value        = (IDictionary <string, object>)traceEvent.PayloadValue(0);
                        var eventPayload = (IDictionary <string, object>)value["Payload"];

                        var payload = CounterPayload.FromPayload(eventPayload);

                        store[traceEvent.ProviderName + "/" + payload.Name] = payload.Value;
                    }
                }
                catch (Exception ex)
                {
                    _logger.LogError(ex, "Error processing counter for {ProviderName}:{EventName}", traceEvent.ProviderName, traceEvent.EventName);
                }
            };

            return(new NullDisposable());
        }
示例#7
0
        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();
        }
示例#8
0
        public MonitorService(MetricFactory metricFactory)
        {
            m_MetricFactory = metricFactory ?? throw new ArgumentNullException(nameof(metricFactory));

            var pid    = 1;
            var client = new DiagnosticsClient(pid);

            var providerArguments = new Dictionary <string, string>
            {
                ["EventCounterIntervalSec"] = "10"
            };

            var provider = new EventPipeProvider(
                "System.Runtime",
                System.Diagnostics.Tracing.EventLevel.Verbose,
                0xffffffff,
                providerArguments);
            var customEventProvider = new EventPipeProvider(
                "Sample",
                System.Diagnostics.Tracing.EventLevel.Verbose,
                0xffffffff,
                providerArguments);

            var session = client.StartEventPipeSession(new[] { provider, customEventProvider });

            m_EventSource = new EventPipeEventSource(session.EventStream);

            m_EventSource.Dynamic.All += ProcessEvents;
        }
示例#9
0
        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);
        }
示例#10
0
        public IDisposable Attach(EventPipeEventSource source, ReplicaInfo replicaInfo)
        {
            var loggerFactory = LoggerFactory.Create(builder => ConfigureLogging(replicaInfo.Service, replicaInfo.Replica, builder));

            var lastFormattedMessage = "";

            var logActivities = new Dictionary <Guid, LogActivityItem>();
            var stack         = new Stack <Guid>();

            source.Dynamic.AddCallbackForProviderEvent(MicrosoftExtensionsLoggingProviderName, "ActivityJsonStart/Start", (traceEvent) =>
            {
                var factoryId    = (int)traceEvent.PayloadByName("FactoryID");
                var categoryName = (string)traceEvent.PayloadByName("LoggerName");
                var argsJson     = (string)traceEvent.PayloadByName("ArgumentsJson");

                // TODO: Store this information by logger factory id
                var item = new LogActivityItem(traceEvent.ActivityID, new LogObject(JsonDocument.Parse(argsJson).RootElement));
                if (stack.TryPeek(out var parentId) && logActivities.TryGetValue(parentId, out var parentItem))
                {
                    item.Parent = parentItem;
                }

                stack.Push(traceEvent.ActivityID);
                logActivities[traceEvent.ActivityID] = item;
            });
示例#11
0
        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 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()
                           } });
        }
示例#13
0
        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]);
                }
            }
        }
示例#14
0
        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());
                }
            }
        }
示例#15
0
        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 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");
             *                  }
             *              }
             *          }
             *      }
             */
        }
示例#17
0
        /// <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);
            });
        }
示例#18
0
        protected override async Task OnEventSourceAvailable(EventPipeEventSource eventSource, Func <Task> stopSessionAsync, CancellationToken token)
        {
            ExecuteCounterLoggerAction((metricLogger) => metricLogger.PipelineStarted());

            eventSource.Dynamic.All += traceEvent =>
            {
                try
                {
                    if (traceEvent.TryGetCounterPayload(_filter, out ICounterPayload counterPayload))
                    {
                        ExecuteCounterLoggerAction((metricLogger) => metricLogger.Log(counterPayload));
                    }
                }
                catch (Exception)
                {
                }
            };

            using var sourceCompletedTaskSource = new EventTaskSource <Action>(
                      taskComplete => taskComplete,
                      handler => eventSource.Completed += handler,
                      handler => eventSource.Completed -= handler,
                      token);

            await sourceCompletedTaskSource.Task;

            ExecuteCounterLoggerAction((metricLogger) => metricLogger.PipelineStopped());
        }
示例#19
0
        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);
        }
示例#20
0
        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);
        }
示例#21
0
        private async Task HandleProcessInfo(EventPipeEventSource source, Func <Task> stopFunc, CancellationToken token)
        {
            string commandLine = null;
            Action <TraceEvent, Action> processInfoHandler = (TraceEvent traceEvent, Action taskComplete) =>
            {
                commandLine = (string)traceEvent.PayloadByName("CommandLine");
                taskComplete();
            };

            // Completed when the ProcessInfo event of the Microsoft-DotNETCore-EventPipe event provider is handled
            using var processInfoTaskSource = new EventTaskSource <Action <TraceEvent> >(
                      taskComplete => traceEvent => processInfoHandler(traceEvent, taskComplete),
                      handler => source.Dynamic.AddCallbackForProviderEvent(MonitoringSourceConfiguration.EventPipeProviderName, "ProcessInfo", handler),
                      handler => source.Dynamic.RemoveCallback(handler),
                      token);

            // Completed when any trace event is handled
            using var anyEventTaskSource = new EventTaskSource <Action <TraceEvent> >(
                      taskComplete => traceEvent => taskComplete(),
                      handler => source.Dynamic.All += handler,
                      handler => source.Dynamic.All -= handler,
                      token);

            // Wait for any trace event to be processed
            await anyEventTaskSource.Task;

            // Stop the event pipe session
            await stopFunc();

            // Wait for the ProcessInfo event to be processed
            await processInfoTaskSource.Task;

            // Notify of command line information
            await _processInfoCallback(commandLine, token);
        }
示例#22
0
        private void HandleLoggingEvents(EventPipeEventSource source, ILoggerFactory loggerFactory, string replicaName)
        {
            var lastFormattedMessage = "";

            var logActivities = new Dictionary <Guid, LogActivityItem>();
            var stack         = new Stack <Guid>();

            source.Dynamic.AddCallbackForProviderEvent(MicrosoftExtensionsLoggingProviderName, "ActivityJsonStart/Start", (traceEvent) =>
            {
                var factoryId    = (int)traceEvent.PayloadByName("FactoryID");
                var categoryName = (string)traceEvent.PayloadByName("LoggerName");
                var argsJson     = (string)traceEvent.PayloadByName("ArgumentsJson");

                // TODO: Store this information by logger factory id
                var item = new LogActivityItem
                {
                    ActivityID   = traceEvent.ActivityID,
                    ScopedObject = new LogObject(JsonDocument.Parse(argsJson).RootElement),
                };

                if (stack.TryPeek(out var parentId) && logActivities.TryGetValue(parentId, out var parentItem))
                {
                    item.Parent = parentItem;
                }

                stack.Push(traceEvent.ActivityID);
                logActivities[traceEvent.ActivityID] = item;
            });
示例#23
0
 public EventPipeSessionController(int pid, List <EventPipeProvider> providers, bool requestRundown = true)
 {
     _pid       = pid;
     _providers = providers;
     _client    = new DiagnosticsClient(pid);
     _session   = _client.StartEventPipeSession(providers, requestRundown, 1024);
     _source    = new EventPipeEventSource(_session.EventStream);
 }
        protected override async Task OnEventSourceAvailable(EventPipeEventSource eventSource, Func <Task> stopSessionAsync, CancellationToken token)
        {
            _trigger = Settings.TriggerFactory.Create(Settings.TriggerSettings);

            _pipeline = new TraceEventTriggerPipeline(eventSource, _trigger, _callback);

            await _pipeline.RunAsync(token).ConfigureAwait(false);
        }
示例#25
0
        private void HandleEventCounters(EventPipeEventSource source)
        {
            source.Dynamic.All += traceEvent =>
            {
                try
                {
                    // Metrics
                    if (traceEvent.EventName.Equals("EventCounters"))
                    {
                        IDictionary <string, object> payloadVal    = (IDictionary <string, object>)(traceEvent.PayloadValue(0));
                        IDictionary <string, object> payloadFields = (IDictionary <string, object>)(payloadVal["Payload"]);

                        //Make sure we are part of the requested series. If multiple clients request metrics, all of them get the metrics.
                        string series = payloadFields["Series"].ToString();
                        if (GetInterval(series) != _metricIntervalSeconds * 1000)
                        {
                            return;
                        }

                        float      intervalSec  = (float)payloadFields["IntervalSec"];
                        string     counterName  = payloadFields["Name"].ToString();
                        string     displayName  = payloadFields["DisplayName"].ToString();
                        string     displayUnits = payloadFields["DisplayUnits"].ToString();
                        double     value        = 0;
                        MetricType metricType   = MetricType.Avg;

                        if (payloadFields["CounterType"].Equals("Mean"))
                        {
                            value = (double)payloadFields["Mean"];
                        }
                        else if (payloadFields["CounterType"].Equals("Sum"))
                        {
                            metricType = MetricType.Sum;
                            value      = (double)payloadFields["Increment"];
                            if (string.IsNullOrEmpty(displayUnits))
                            {
                                displayUnits = "count";
                            }
                            //TODO Should we make these /sec like the dotnet-counters tool?
                        }

                        // Note that dimensional data such as pod and namespace are automatically added in prometheus and azure monitor scenarios.
                        // We no longer added it here.
                        PostMetric(new Metric(traceEvent.TimeStamp,
                                              traceEvent.ProviderName,
                                              counterName, displayName,
                                              displayUnits,
                                              value,
                                              metricType,
                                              intervalSec,
                                              dimNames: new List <string>(0), dimValues: new List <string>(0)));
                    }
                }
                catch (Exception)
                {
                }
            };
        }
        /// <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;
            }));
        }
示例#27
0
        public static void Main(string[] args)
        {
            WriteNetPerf(args[0]);
            var source = new EventPipeEventSource(args[0]);

            if (source.Process())
            {
                Console.WriteLine("NetTrace file successfully written.");
            }
        }
示例#28
0
        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);
        }
示例#29
0
        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();
        }