- Notifications
You must be signed in to change notification settings - Fork 32
Dotnet-trace (.netrace) support #95
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
ivberg wants to merge 9 commits into develop Choose a base branch from user/ivberg/DotNetTrace_NetTrace_Support
base: develop
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline, and old review comments may become outdated.
Open
Changes from 8 commits
Commits
Show all changes
9 commits Select commit Hold shift + click to select a range
ab48b31 Check in working prototype of .NET trace EventPipe parsing support (s…
ivberg a36fa9a Add support for Generic Events
ivberg 2bc897b Add Exceptions and GC Table
ivberg 6188397 Add support for calculating cpu % and add small Hello World dotnet-tr…
ivberg 3401409 Add event stats table
ivberg 6063c0b Small doc
ivberg 63ad24d Yaml build file
ivberg 51b9b73 Update docs
ivberg 0cd5b7c Upgrade to newer TraceEvent which fixes TraceLogEventSource not havi…
ivberg File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,63 @@ | ||
| // Copyright (c) Microsoft Corporation. | ||
| // Licensed under the MIT License. | ||
| using Microsoft.Diagnostics.Tracing; | ||
| using Microsoft.Diagnostics.Tracing.Etlx; | ||
| using Microsoft.Performance.SDK; | ||
| using System; | ||
| using Utilities; | ||
| | ||
| namespace DotNetEventPipe.DataOutputTypes | ||
| { | ||
| /// <summary> | ||
| /// A GenericEvent | ||
| /// </summary> | ||
| public class GenericEvent | ||
| { | ||
| public string EventName { get; } | ||
| public TraceEventID ID { get; } | ||
| public TraceEventKeyword Keywords { get; } | ||
| public TraceEventLevel Level { get; } | ||
| public TraceEventOpcode Opcode { get; } | ||
| public string OpcodeName { get; } | ||
| public string[] PayloadNames { get; } | ||
| public object[] PayloadValues { get; } | ||
| public Guid ProviderGuid { get; } | ||
| public string ProviderName { get; } | ||
| public int ProcessID { get; } | ||
| public string ProcessName { get; } | ||
| public int ProcessorNumber { get; } | ||
| public int ThreadID { get; } | ||
| public Timestamp Timestamp { get; } | ||
| public string[] CallStack { get; } | ||
| /// <summary> | ||
| /// filename of the binary / library for the instruction pointer | ||
| /// </summary> | ||
| public TraceModuleFile Module { get; } | ||
| /// <summary> | ||
| /// Functionname of the instruction pointer | ||
| /// </summary> | ||
| public string FullMethodName { get; } | ||
| | ||
| public GenericEvent(string eventName, TraceEventID id, TraceEventKeyword keywords, TraceEventLevel level, TraceEventOpcode opcode, string opcodeName, string[] payloadNames, object[] payloadValues, Guid providerGuid, string providerName, int processID, string processName, int processorNumber, int threadID, Timestamp timestamp, string[] callStack, TraceModuleFile module, string fullMethodName) | ||
| { | ||
| EventName = Common.StringIntern(eventName); | ||
| ID = id; | ||
| Keywords = keywords; | ||
| Level = level; | ||
| Opcode = opcode; | ||
| OpcodeName = Common.StringIntern(opcodeName); | ||
| PayloadNames = payloadNames; | ||
| PayloadValues = payloadValues; | ||
| ProviderGuid = providerGuid; | ||
| ProviderName = providerName; | ||
| ProcessID = processID; | ||
| ProcessName = Common.StringIntern(processName); | ||
| ProcessorNumber = processorNumber; | ||
| ThreadID = threadID; | ||
| Timestamp = timestamp; | ||
| CallStack = callStack; | ||
| Module = module; | ||
| FullMethodName = Common.StringIntern(fullMethodName); | ||
| } | ||
| } | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,51 @@ | ||
| // Copyright (c) Microsoft Corporation. | ||
| // Licensed under the MIT License. | ||
| using Microsoft.Diagnostics.Tracing.Etlx; | ||
| using Microsoft.Performance.SDK; | ||
| using Utilities; | ||
| | ||
| namespace DotNetEventPipe.DataOutputTypes | ||
| { | ||
| /// <summary> | ||
| /// A CPU sampling event that samples at some interval | ||
| /// Shows process and threads, and stacks that were running on which CPUs at specific times. | ||
| /// </summary> | ||
| public readonly struct ThreadSamplingEvent | ||
| { | ||
| public int ProcessID { get; } | ||
| public string ProcessName { get; } | ||
| public int ProcessorNumber { get; } | ||
| public int ThreadID { get; } | ||
| public Timestamp Timestamp { get; } | ||
| public string[] CallStack { get; } | ||
| /// <summary> | ||
| /// filename of the binary / library for the instruction pointer | ||
| /// </summary> | ||
| public TraceModuleFile Module { get; } | ||
| /// <summary> | ||
| /// Functionname of the instruction pointer | ||
| /// </summary> | ||
| public string FullMethodName { get; } | ||
| | ||
| public ThreadSamplingEvent( | ||
| int processID, | ||
| string processName, | ||
| int processorNumber, | ||
| int threadID, | ||
| Timestamp timestamp, | ||
| string[] callStack, | ||
| TraceModuleFile module, | ||
| string fullMethodName | ||
| ) | ||
| { | ||
| ProcessID = processID; | ||
| ProcessName = Common.StringIntern(processName); | ||
| ProcessorNumber = processorNumber; | ||
| ThreadID = threadID; | ||
| Timestamp = timestamp; | ||
| CallStack = callStack; // Cache whole common stack?? | ||
| Module = module; | ||
| FullMethodName = Common.StringIntern(fullMethodName); | ||
| } | ||
| } | ||
| } |
14 changes: 14 additions & 0 deletions 14 DotNetEventPipe/DataOutputTypes/TraceCallStackProcessed.cs
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,14 @@ | ||
| using Microsoft.Diagnostics.Tracing.Etlx; | ||
| using System; | ||
| using System.Collections.Generic; | ||
| using System.Text; | ||
| | ||
| namespace DotnetEventpipe.DataOutputTypes | ||
| { | ||
| public class TraceCallStackProcessed | ||
| { | ||
| public string[] CallStack { get; set; } | ||
| public TraceModuleFile Module { get; set; } | ||
| public string FullMethodName { get; set; } | ||
| } | ||
| } | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,52 @@ | ||
| <Project Sdk="Microsoft.NET.Sdk"> | ||
| | ||
| <PropertyGroup> | ||
| <TargetFramework>netstandard2.1</TargetFramework> | ||
| <Version>1.0.0</Version> | ||
| <PackageRequireLicenseAcceptance>true</PackageRequireLicenseAcceptance> | ||
| <Authors>Microsoft</Authors> | ||
| <Company>Microsoft Corp.</Company> | ||
| <Product>Performance ToolKit</Product> | ||
| <Description>Contains the .NET Trace datasource plugin.</Description> | ||
| <PackageId>Microsoft.Performance.Toolkit.Plugins.DotNetEvent</PackageId> | ||
| <Copyright>© Microsoft Corporation. All rights reserved.</Copyright> | ||
| <RepositoryUrl>https://github.com/microsoft/Microsoft-Performance-Tools-Linux-Android</RepositoryUrl> | ||
| <PackageProjectUrl>https://github.com/microsoft/Microsoft-Performance-Tools-Linux-Android</PackageProjectUrl> | ||
| <PackageLicenseFile>LICENSE.txt</PackageLicenseFile> | ||
| </PropertyGroup> | ||
| | ||
| <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'"> | ||
| <DefineConstants>TRACE</DefineConstants> | ||
| <AllowUnsafeBlocks>false</AllowUnsafeBlocks> | ||
| </PropertyGroup> | ||
| | ||
| <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'"> | ||
| <AllowUnsafeBlocks>false</AllowUnsafeBlocks> | ||
| </PropertyGroup> | ||
| | ||
| <ItemGroup> | ||
| <None Include="..\LICENSE.txt"> | ||
| <Pack>True</Pack> | ||
| <PackagePath></PackagePath> | ||
| </None> | ||
| </ItemGroup> | ||
| | ||
| <ItemGroup> | ||
| <PackageReference Include="Microsoft.Diagnostics.Tracing.TraceEvent" Version="3.0.0"> | ||
| <GeneratePathProperty>True</GeneratePathProperty> | ||
| </PackageReference> | ||
| <PackageReference Include="Microsoft.Performance.SDK" Version="1.0.16" /> | ||
| </ItemGroup> | ||
| | ||
| <ItemGroup> | ||
| <ProjectReference Include="..\Utilities\Utilities.csproj" /> | ||
| </ItemGroup> | ||
| | ||
| <ItemGroup> | ||
| <TraceEventWorkaround Include="$(PkgMicrosoft_Diagnostics_Tracing_Traceevent)\lib\netstandard2.0\Microsoft.Diagnostics.Tracing.TraceEvent.dll;$(PkgMicrosoft_Diagnostics_Tracing_Traceevent)\lib\netstandard2.0\Microsoft.Diagnostics.FastSerialization.dll" /> | ||
| </ItemGroup> | ||
| <Target Name="CopyRulesToTarget" AfterTargets="Build"> | ||
| <Copy SourceFiles="@(TraceEventWorkaround)" DestinationFolder="$(TargetDir)" /> | ||
| </Target> | ||
| | ||
| </Project> |
111 changes: 111 additions & 0 deletions 111 DotNetEventPipe/SourceDataCookers/DotnetTraceDataProcessor.cs
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,111 @@ | ||
| // Copyright (c) Microsoft Corporation. | ||
| // Licensed under the MIT License. | ||
| | ||
| using System; | ||
| using System.Collections.Generic; | ||
| using System.Collections.ObjectModel; | ||
| using System.IO; | ||
| using System.Threading; | ||
| using System.Threading.Tasks; | ||
| using DotNetEventPipe.Tables; | ||
| using Microsoft.Diagnostics.Tracing; | ||
| using Microsoft.Performance.SDK.Processing; | ||
| using Microsoft.Diagnostics.Tracing.EventPipe; | ||
| using Microsoft.Diagnostics.Tracing.Etlx; | ||
| | ||
| namespace DotNetEventPipe | ||
| { | ||
| public sealed class DotnetTraceDataProcessor | ||
| : CustomDataProcessor | ||
| { | ||
| private readonly string[] filePaths; | ||
| private IReadOnlyDictionary<string, TraceEventProcessor> fileContent; | ||
| private DataSourceInfo dataSourceInfo; | ||
| | ||
| public DotnetTraceDataProcessor( | ||
| string[] filePaths, | ||
| ProcessorOptions options, | ||
| IApplicationEnvironment applicationEnvironment, | ||
| IProcessorEnvironment processorEnvironment) | ||
| : base(options, applicationEnvironment, processorEnvironment) | ||
| { | ||
| // | ||
| // Assign the files array to a readonly backing field. | ||
| // | ||
| | ||
| this.filePaths = filePaths; | ||
| } | ||
| | ||
| public override DataSourceInfo GetDataSourceInfo() | ||
| { | ||
| // The DataSourceInfo is used to tell analzyer the time range of the data(if applicable) and any other relevant data for rendering / synchronizing. | ||
| | ||
| return this.dataSourceInfo; | ||
| | ||
| Contributor There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nit: extra line | ||
| } | ||
| | ||
| protected override Task ProcessAsyncCore( | ||
| IProgress<int> progress, | ||
| CancellationToken cancellationToken) | ||
| { | ||
| var contentDictionary = new Dictionary<string, TraceEventProcessor>(); | ||
| | ||
| foreach (var path in this.filePaths) | ||
| { | ||
| var traceStartTime = DateTime.UtcNow.Date; | ||
| Contributor There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. not needed? | ||
| | ||
| // EventPipeEventSource doesn't expose the callstacks - https://github.com/Microsoft/perfview/blob/main/src/TraceEvent/EventPipe/EventPipeFormat.md | ||
| // But currently it's SessionDuration, SessionStartTime are correct | ||
| // Can remove when when this is released - https://github.com/microsoft/perfview/pull/1635 | ||
| var dotnetFileStream = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read); | ||
| ||
| using (var traceSource = new EventPipeEventSource(dotnetFileStream)) | ||
| { | ||
| traceSource.Process(); | ||
| this.dataSourceInfo = new DataSourceInfo(0, traceSource.SessionDuration.Ticks * 100, traceSource.SessionStartTime.ToUniversalTime()); | ||
| } | ||
| | ||
| var tmpEtlx = Path.Combine(Path.GetTempPath(), Path.GetFileName(path) + ".etlx"); | ||
| | ||
| string traceLogPath = TraceLog.CreateFromEventPipeDataFile(path, tmpEtlx); | ||
| using (TraceLog traceLog = new TraceLog(traceLogPath)) | ||
| { | ||
| TraceLogEventSource source = traceLog.Events.GetSource(); | ||
| | ||
| var traceEventProcessor = new TraceEventProcessor(); | ||
| contentDictionary[path] = traceEventProcessor; | ||
| source.AllEvents += traceEventProcessor.ProcessTraceEvent; | ||
| source.Process(); | ||
| // Below will work when this is released - https://github.com/microsoft/perfview/pull/1635 | ||
| //this.dataSourceInfo = new DataSourceInfo(0, source.SessionDuration.Ticks * 100, source.SessionStartTime.ToUniversalTime()); | ||
| } | ||
| File.Delete(tmpEtlx); | ||
| } | ||
| | ||
| this.fileContent = new ReadOnlyDictionary<string, TraceEventProcessor>(contentDictionary); | ||
| | ||
| return Task.CompletedTask; | ||
| } | ||
| | ||
| protected override void BuildTableCore( | ||
| TableDescriptor tableDescriptor, | ||
| ITableBuilder tableBuilder) | ||
| { | ||
| // | ||
| // Instantiate the table, and pass the tableBuilder to it. | ||
| // | ||
| | ||
| var table = this.InstantiateTable(tableDescriptor.Type); | ||
| table.Build(tableBuilder); | ||
| } | ||
| | ||
| private TraceEventTableBase InstantiateTable(Type tableType) | ||
| { | ||
| // | ||
| // This private method is added to activate the given table type and pass in the file content. | ||
| // | ||
| | ||
| var instance = Activator.CreateInstance(tableType, new[] { this.fileContent, }); | ||
| return (TraceEventTableBase)instance; | ||
| } | ||
| } | ||
| } | ||
73 changes: 73 additions & 0 deletions 73 DotNetEventPipe/SourceDataCookers/DotnetTraceProcessingSource.cs
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,73 @@ | ||
| // Copyright (c) Microsoft Corporation. | ||
| // Licensed under the MIT License. | ||
| | ||
| using System; | ||
| using System.Collections.Generic; | ||
| using System.IO; | ||
| using System.Linq; | ||
| using Microsoft.Performance.SDK.Processing; | ||
| | ||
| namespace DotNetEventPipe | ||
| { | ||
| [ProcessingSource( | ||
| "{890C0A11-011E-43E1-AE28-7E1A903A6633}", // The GUID must be unique for your Custom Data Source. You can use Visual Studio's Tools -> Create Guid… tool to create a new GUID | ||
| ".NET (dotnet-trace)", // The Custom Data Source MUST have a name | ||
| @".net trace EventPipe")] // The Custom Data Source MUST have a description | ||
| [FileDataSource( | ||
| ".nettrace", // A file extension is REQUIRED | ||
| "dotnet-trace")] // A description is OPTIONAL. The description is what appears in the file open menu to help users understand what the file type actually is. | ||
| | ||
| // | ||
| // There are two methods to creating a Custom Data Source that is recognized by UI: | ||
| // 1. Using the helper abstract base classes | ||
| // 2. Implementing the raw interfaces | ||
| // This sample demonstrates method 1 where the ProcessingSource abstract class | ||
| // helps provide a public parameterless constructor and implement the IProcessingSource interface | ||
| // | ||
| | ||
| public class DotnetTraceProcessingSource | ||
| : ProcessingSource | ||
| { | ||
| private IApplicationEnvironment applicationEnvironment; | ||
| | ||
| public override ProcessingSourceInfo GetAboutInfo() | ||
| { | ||
| return new ProcessingSourceInfo() | ||
| { | ||
| ProjectInfo = new ProjectInfo() { Uri = "https://aka.ms/linuxperftools" }, | ||
| }; | ||
| } | ||
| | ||
| protected override void SetApplicationEnvironmentCore(IApplicationEnvironment applicationEnvironment) | ||
| { | ||
| // | ||
| // Saves the given application environment into this instance | ||
| // | ||
| | ||
| this.applicationEnvironment = applicationEnvironment; | ||
| } | ||
| | ||
| protected override bool IsDataSourceSupportedCore(IDataSource dataSource) | ||
| { | ||
| return dataSource.IsFile() && Path.GetExtension(dataSource.Uri.LocalPath) == ".nettrace"; | ||
| } | ||
| | ||
| protected override ICustomDataProcessor CreateProcessorCore( | ||
| IEnumerable<IDataSource> dataSources, | ||
| IProcessorEnvironment processorEnvironment, | ||
| ProcessorOptions options) | ||
| { | ||
| // | ||
| // Create a new instance implementing ICustomDataProcessor here to process the specified data sources. | ||
| // Note that you can have more advanced logic here to create different processors if you would like based on the file, or any other criteria. | ||
| // You are not restricted to always returning the same type from this method. | ||
| // | ||
| | ||
| return new DotnetTraceDataProcessor( | ||
| dataSources.Select(x => x.Uri.LocalPath).ToArray(), | ||
| options, | ||
| this.applicationEnvironment, | ||
| processorEnvironment); | ||
| } | ||
| } | ||
| } |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit. This suggestion is invalid because no changes were made to the code. Suggestions cannot be applied while the pull request is closed. Suggestions cannot be applied while viewing a subset of changes. Only one suggestion per line can be applied in a batch. Add this suggestion to a batch that can be applied as a single commit. Applying suggestions on deleted lines is not supported. You must change the existing code in this line in order to create a valid suggestion. Outdated suggestions cannot be applied. This suggestion has been applied or marked resolved. Suggestions cannot be applied from pending reviews. Suggestions cannot be applied on multi-line comments. Suggestions cannot be applied while the pull request is queued to merge. Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe make readonly?