private static ScenarioBenchmark AddEtwData( ScenarioBenchmark scenarioBenchmark, ScenarioExecutionResult scenarioExecutionResult, IReadOnlyCollection <string> processesOfInterest, IReadOnlyCollection <string> modulesOfInterest) { var metricModels = scenarioExecutionResult.PerformanceMonitorCounters .Select(pmc => new MetricModel { DisplayName = pmc.DisplayName, Name = pmc.Name, Unit = pmc.Unit, }); // Get the list of processes of interest. Console.WriteLine($"Parsing: {scenarioExecutionResult.EventLogFileName}"); var processes = new SimpleTraceEventParser().GetProfileData(scenarioExecutionResult); // Extract the Pmc data for each one of the processes. foreach (var process in processes) { if (!processesOfInterest.Any(p => p.Equals(process.Name, StringComparison.OrdinalIgnoreCase))) { continue; } var processTest = scenarioBenchmark.Tests .SingleOrDefault(t => t.Name == process.Name && t.Namespace == ""); if (processTest == null) { processTest = new ScenarioTestModel(process.Name) { Namespace = "", }; scenarioBenchmark.Tests.Add(processTest); // Add metrics definitions. processTest.Performance.Metrics.Add(ElapsedTimeMilliseconds); processTest.Performance.Metrics.AddRange(metricModels); } var processIterationModel = new IterationModel { Iteration = new Dictionary <string, double>() }; processTest.Performance.IterationModels.Add(processIterationModel); processIterationModel.Iteration.Add( ElapsedTimeMilliseconds.Name, process.LifeSpan.Duration.TotalMilliseconds); // Add process metrics values. foreach (var pmcData in process.PerformanceMonitorCounterData) { processIterationModel.Iteration.Add(pmcData.Key.Name, pmcData.Value); } foreach (var module in process.Modules) { var moduleName = Path.GetFileName(module.FullName); if (modulesOfInterest.Any(m => m.Equals(moduleName, StringComparison.OrdinalIgnoreCase))) { var moduleTestName = $"{moduleName}"; var moduleTest = scenarioBenchmark.Tests .SingleOrDefault(t => t.Name == moduleTestName && t.Namespace == process.Name); if (moduleTest == null) { moduleTest = new ScenarioTestModel(moduleTestName) { Namespace = process.Name, Separator = "!", }; scenarioBenchmark.Tests.Add(moduleTest); // Add metrics definitions. moduleTest.Performance.Metrics.AddRange(metricModels); } var moduleIterationModel = new IterationModel { Iteration = new Dictionary <string, double>() }; moduleTest.Performance.IterationModels.Add(moduleIterationModel); // 5. Add module metrics values. foreach (var pmcData in module.PerformanceMonitorCounterData) { moduleIterationModel.Iteration.Add(pmcData.Key.Name, pmcData.Value); } } } } return(scenarioBenchmark); }
protected static void AddEtwData( IterationResult iteration, ScenarioExecutionResult scenarioExecutionResult, ITestOutputHelper output) { string[] modulesOfInterest = new string[] { "Anonymously Hosted DynamicMethods Assembly", "clrjit.dll", "coreclr.dll", "dotnet.exe", "MusicStore.dll", "AllReady.dll", "Word2VecScenario.dll", "ntoskrnl.exe", "System.Private.CoreLib.dll", "Unknown", }; // Get the list of processes of interest. try { var processes = new SimpleTraceEventParser().GetProfileData(scenarioExecutionResult); // Extract the Pmc data for each one of the processes. foreach (var process in processes) { if (process.Id != scenarioExecutionResult.ProcessExitInfo.ProcessId) { continue; } iteration.Measurements.Add(new Metric($"PMC/{process.Name}/Duration", "ms"), process.LifeSpan.Duration.TotalMilliseconds); // Add process metrics values. foreach (var pmcData in process.PerformanceMonitorCounterData) { iteration.Measurements.Add(new Metric($"PMC/{process.Name}/{pmcData.Key.Name}", pmcData.Key.Unit), pmcData.Value); } foreach (var module in process.Modules) { var moduleName = Path.GetFileName(module.FullName); if (modulesOfInterest.Any(m => m.Equals(moduleName, StringComparison.OrdinalIgnoreCase))) { foreach (var pmcData in module.PerformanceMonitorCounterData) { Metric m = new Metric($"PMC/{process.Name}!{moduleName}/{pmcData.Key.Name}", pmcData.Key.Unit); // Sometimes the etw parser gives duplicate module entries which leads to duplicate keys // but I haven't hunted down the reason. For now it is first one wins. if (!iteration.Measurements.ContainsKey(m)) { iteration.Measurements.Add(m, pmcData.Value); } } } } } } catch (InvalidOperationException e) { output.WriteLine("Error while processing ETW log: " + scenarioExecutionResult.EventLogFileName); output.WriteLine(e.ToString()); } }