Provider format: KnownProviderName[:Keywords[:Level][:KeyValueArgs]]
KnownProviderName - The provider's name
Keywords - 8 character hex number bit mask
- Level - A number in the range [0, 5]
+ Level - A number in the range [0, 5], or their corresponding text values (refer to https://docs.microsoft.com/en-us/dotnet/api/system.diagnostics.tracing.eventlevel?view=netframework-4.8).
KeyValueArgs - A semicolon separated list of key=value
KeyValueArgs format: '[key1=value1][;key2=value2]'
Examples:
+
+ To perform a default `cpu-tracing` profiling:
+
> dotnet trace collect --process-id 1902
No profile or providers specified, defaulting to trace profile 'cpu-sampling'
Recording trace 38MB
's' - stop tracing
+
+ To collect just the GC keyword events from the .NET runtime at informational level:
+
+ > dotnet trace collect --process-id 1902 --providers Microsoft-Windows-DotNETRuntime:0x1:Informational
+
+
+
CONVERT
dotnet-trace convert [-h|--help]
{
internal static class Extensions
{
+ private static EventLevel defaultEventLevel = EventLevel.Verbose;
+
public static List<Provider> ToProviders(string providers)
{
if (providers == null)
new List<Provider>() : providers.Split(',').Select(ToProvider).ToList();
}
+ private static EventLevel GetEventLevel(string token)
+ {
+ if (Int32.TryParse(token, out int level) && level >= 0)
+ {
+ return level > (int)EventLevel.Verbose ? EventLevel.Verbose : (EventLevel)level;
+ }
+
+ else
+ {
+ switch (token.ToLower())
+ {
+ case "critical":
+ return EventLevel.Critical;
+ case "error":
+ return EventLevel.Error;
+ case "informational":
+ return EventLevel.Informational;
+ case "logalways":
+ return EventLevel.LogAlways;
+ case "verbose":
+ return EventLevel.Verbose;
+ case "warning":
+ return EventLevel.Warning;
+ default:
+ throw new ArgumentException($"Unknown EventLevel: {token}");
+ }
+ }
+ }
+
private static Provider ToProvider(string provider)
{
if (string.IsNullOrWhiteSpace(provider))
Convert.ToUInt64(tokens[1], 16) : ulong.MaxValue;
// Level
- uint level = tokens.Length > 2 && !string.IsNullOrWhiteSpace(tokens[2]) ?
- Convert.ToUInt32(tokens[2]) : (uint)EventLevel.Verbose;
- EventLevel eventLevel = level > (uint)EventLevel.Verbose ?
- EventLevel.Verbose : (EventLevel)level; // TODO: Should we throw here?
+ EventLevel eventLevel = tokens.Length > 2 && !string.IsNullOrWhiteSpace(tokens[2]) ?
+ GetEventLevel(tokens[2]) : defaultEventLevel;
// Event counters
string filterData = tokens.Length > 3 ? tokens[3] : null;
Assert.True(providerThree.EventLevel == System.Diagnostics.Tracing.EventLevel.Warning);
Assert.True(providerThree.FilterData == "FilterAndPayloadSpecs=\"QuotedValue:-\r\nQuoted/Value:-A=B;C=D;\"");
}
+
+ [Theory]
+ [InlineData("ProviderOne:0x1:Verbose")]
+ [InlineData("ProviderOne:0x1:verbose")]
+ public void TextLevelProviderSpecVerbose_CorrectlyParse(string providerToParse)
+ {
+ List<Provider> parsedProviders = Extensions.ToProviders(providerToParse);
+ Assert.True(parsedProviders.Count == 1);
+ Assert.True(parsedProviders[0].Name == "ProviderOne");
+ Assert.True(parsedProviders[0].Keywords == 1);
+ Assert.True(parsedProviders[0].EventLevel == System.Diagnostics.Tracing.EventLevel.Verbose);
+ }
+
+ [Theory]
+ [InlineData("ProviderOne:0x1:Informational")]
+ [InlineData("ProviderOne:0x1:INFORMATIONAL")]
+ public void TextLevelProviderSpecInformational_CorrectlyParse(string providerToParse)
+ {
+ List<Provider> parsedProviders = Extensions.ToProviders(providerToParse);
+ Assert.True(parsedProviders.Count == 1);
+ Assert.True(parsedProviders[0].Name == "ProviderOne");
+ Assert.True(parsedProviders[0].Keywords == 1);
+ Assert.True(parsedProviders[0].EventLevel == System.Diagnostics.Tracing.EventLevel.Informational);
+ }
+
+ [Theory]
+ [InlineData("ProviderOne:0x1:LogAlways")]
+ [InlineData("ProviderOne:0x1:LogAlwayS")]
+ public void TextLevelProviderSpecLogAlways_CorrectlyParse(string providerToParse)
+ {
+ List<Provider> parsedProviders = Extensions.ToProviders(providerToParse);
+ Assert.True(parsedProviders.Count == 1);
+ Assert.True(parsedProviders[0].Name == "ProviderOne");
+ Assert.True(parsedProviders[0].Keywords == 1);
+ Assert.True(parsedProviders[0].EventLevel == System.Diagnostics.Tracing.EventLevel.LogAlways);
+ }
+
+ [Theory]
+ [InlineData("ProviderOne:0x1:Error")]
+ [InlineData("ProviderOne:0x1:ERRor")]
+ public void TextLevelProviderSpecError_CorrectlyParse(string providerToParse)
+ {
+ List<Provider> parsedProviders = Extensions.ToProviders(providerToParse);
+ Assert.True(parsedProviders.Count == 1);
+ Assert.True(parsedProviders[0].Name == "ProviderOne");
+ Assert.True(parsedProviders[0].Keywords == 1);
+ Assert.True(parsedProviders[0].EventLevel == System.Diagnostics.Tracing.EventLevel.Error);
+ }
+
+ [Theory]
+ [InlineData("ProviderOne:0x1:Critical")]
+ [InlineData("ProviderOne:0x1:CRITICAL")]
+ public void TextLevelProviderSpecCritical_CorrectlyParse(string providerToParse)
+ {
+ List<Provider> parsedProviders = Extensions.ToProviders(providerToParse);
+ Assert.True(parsedProviders.Count == 1);
+ Assert.True(parsedProviders[0].Name == "ProviderOne");
+ Assert.True(parsedProviders[0].Keywords == 1);
+ Assert.True(parsedProviders[0].EventLevel == System.Diagnostics.Tracing.EventLevel.Critical);
+ }
+
+ [Theory]
+ [InlineData("ProviderOne:0x1:Warning")]
+ [InlineData("ProviderOne:0x1:warning")]
+ public void TextLevelProviderSpecWarning_CorrectlyParse(string providerToParse)
+ {
+ List<Provider> parsedProviders = Extensions.ToProviders(providerToParse);
+ Assert.True(parsedProviders.Count == 1);
+ Assert.True(parsedProviders[0].Name == "ProviderOne");
+ Assert.True(parsedProviders[0].Keywords == 1);
+ Assert.True(parsedProviders[0].EventLevel == System.Diagnostics.Tracing.EventLevel.Warning);
+ }
+
+ [Theory]
+ [InlineData("ProviderOne:0x1:UnknownLevel")]
+ public void TextLevelProviderSpec_CorrectlyThrows(string providerToParse)
+ {
+ Assert.Throws<ArgumentException>(() => Extensions.ToProviders(providerToParse));
+ }
}
}
\ No newline at end of file