diff --git a/src/OpenTelemetry/Internal/SelfDiagnosticsConfigParser.cs b/src/OpenTelemetry/Internal/SelfDiagnosticsConfigParser.cs index 8e102fe0645..3253122cf91 100644 --- a/src/OpenTelemetry/Internal/SelfDiagnosticsConfigParser.cs +++ b/src/OpenTelemetry/Internal/SelfDiagnosticsConfigParser.cs @@ -24,7 +24,7 @@ namespace OpenTelemetry.Internal { internal class SelfDiagnosticsConfigParser { - private const string ConfigFileName = "DiagnosticsConfiguration.json"; + private const string ConfigFileName = "OTEL_DIAGNOSTICS.json"; private const int FileSizeLowerLimit = 1024; // Lower limit for log file size in KB: 1MB private const int FileSizeUpperLimit = 128 * 1024; // Upper limit for log file size in KB: 128MB @@ -39,19 +39,19 @@ internal class SelfDiagnosticsConfigParser private static readonly Regex FileSizeRegex = new Regex( @"""FileSize""\s*:\s*(?\d+)", RegexOptions.IgnoreCase | RegexOptions.Compiled); - private static readonly Regex EventLevelRegex = new Regex( - @"""EventLevel""\s*:\s*""(?.*?)""", RegexOptions.IgnoreCase | RegexOptions.Compiled); + private static readonly Regex LogLevelRegex = new Regex( + @"""LogLevel""\s*:\s*""(?.*?)""", RegexOptions.IgnoreCase | RegexOptions.Compiled); // This class is called in SelfDiagnosticsConfigRefresher.UpdateMemoryMappedFileFromConfiguration // in both main thread and the worker thread. // In theory the variable won't be access at the same time because worker thread first Task.Delay for a few seconds. private byte[] configBuffer; - public bool TryGetConfiguration(out string logDirectory, out int fileSizeInKB, out EventLevel eventLevel) + public bool TryGetConfiguration(out string logDirectory, out int fileSizeInKB, out EventLevel logLevel) { logDirectory = null; fileSizeInKB = 0; - eventLevel = EventLevel.LogAlways; + logLevel = EventLevel.LogAlways; try { using FileStream file = File.Open(ConfigFileName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite | FileShare.Delete); @@ -84,12 +84,12 @@ public bool TryGetConfiguration(out string logDirectory, out int fileSizeInKB, o fileSizeInKB = FileSizeUpperLimit; } - if (!TryParseEventLevel(configJson, out var eventLevelString)) + if (!TryParseLogLevel(configJson, out var logLevelString)) { return false; } - eventLevel = (EventLevel)Enum.Parse(typeof(EventLevel), eventLevelString); + logLevel = (EventLevel)Enum.Parse(typeof(EventLevel), logLevelString); return true; } catch (Exception) @@ -114,11 +114,11 @@ internal static bool TryParseFileSize(string configJson, out int fileSizeInKB) return fileSizeResult.Success && int.TryParse(fileSizeResult.Groups["FileSize"].Value, out fileSizeInKB); } - internal static bool TryParseEventLevel(string configJson, out string eventLevel) + internal static bool TryParseLogLevel(string configJson, out string logLevel) { - var eventLevelResult = EventLevelRegex.Match(configJson); - eventLevel = eventLevelResult.Groups["EventLevel"].Value; - return eventLevelResult.Success && !string.IsNullOrWhiteSpace(eventLevel); + var logLevelResult = LogLevelRegex.Match(configJson); + logLevel = logLevelResult.Groups["LogLevel"].Value; + return logLevelResult.Success && !string.IsNullOrWhiteSpace(logLevel); } } } diff --git a/src/OpenTelemetry/README.md b/src/OpenTelemetry/README.md index 2d8d682789b..c6113287ed0 100644 --- a/src/OpenTelemetry/README.md +++ b/src/OpenTelemetry/README.md @@ -84,6 +84,54 @@ using var otel = Sdk.CreateTracerProvider(b => b * [Building your own Processor](../../docs/trace/extending-the-sdk/README.md#processor) * [Building your own Sampler](../../docs/trace/extending-the-sdk/README.md#sampler) +### Troubleshooting + +Self diagnostics module is provided to help troubleshooting. When enabled, +internal events generated by OpenTelemetry will be written to a log file. +These events contain important debugging information and error messages. + +To enable self diagnostics, go to the current directory of your process and +create a configuration file named `OTEL_DIAGNOSTICS.json` with the following +content: + +```json +{ + "LogDirectory": ".", + "FileSize": 1024, + "LogLevel": "Error" +} +``` + +`LogDirectory` is the directory of the output file. It can be an absolute path +or a relative path to the current directory. `FileSize` is a positive integer, +which specifies the log file size in +[KiB](https://en.wikipedia.org/wiki/Kibibyte). +`LogLevel` is the lowest level of the events to be captured. +It has to be one of the +[values](https://docs.microsoft.com/dotnet/api/system.diagnostics.tracing.eventlevel#fields) +of the [`EventLevel` +enum](https://docs.microsoft.com/dotnet/api/system.diagnostics.tracing.eventlevel). +(The level signifies the severity of an event. Lower severity levels encompass +higher severity levels. For example, `Warning` includes the `Error` and +`Critical` levels, which are higher in severity. See +[here](https://docs.microsoft.com/dotnet/api/system.diagnostics.tracing.eventlevel) +for more.) + +The SDK will attempt to open the configuration file in non-exclusive read-only +mode, read the file and parse it as the configuration file every 3 seconds. If +the SDK fails to parse the `LogDirectory`, `FileSize` or `LogLevel` fields as +the specified format, the configuration file will be treated as invalid and no +log file would be generated. Otherwise, it will create or overwrite a +`FileSize`-KiB file at the specific directory `LogDirectory` with the log file +named as `ExecutableName.ProcessId.log` (e.g. `foobar.exe.12345.log`). + +Note that the `FileSize` has to be between 1 MiB and 128 MiB (inclusive), or it +will be rounded to the closest upper or lower limit. When the `LogDirectory` or +`FileSize` is found to be changed, the SDK will create or overwrite a file with +new logs according to the new configuration. The configuration file has to be +no more than 4 KiB. In case the file is larger than 4 KiB, only the first 4 KiB +of content will be read. + ## References * [OpenTelemetry Project](https://opentelemetry.io/) diff --git a/test/OpenTelemetry.Tests/Internal/SelfDiagnosticsConfigParserTest.cs b/test/OpenTelemetry.Tests/Internal/SelfDiagnosticsConfigParserTest.cs index 7cf15fbde4c..0380d7afb4a 100644 --- a/test/OpenTelemetry.Tests/Internal/SelfDiagnosticsConfigParserTest.cs +++ b/test/OpenTelemetry.Tests/Internal/SelfDiagnosticsConfigParserTest.cs @@ -81,15 +81,15 @@ public void SelfDiagnosticsConfigParser_TryParseFileSize_MissingField() [Fact] [Trait("Platform", "Any")] - public void SelfDiagnosticsConfigParser_TryParseEventLevel() + public void SelfDiagnosticsConfigParser_TryParseLogLevel() { string configJson = @"{ ""LogDirectory"": ""Diagnostics"", ""FileSize"": 1024, - ""EventLevel"": ""Error"" + ""LogLevel"": ""Error"" }"; - Assert.True(SelfDiagnosticsConfigParser.TryParseEventLevel(configJson, out string eventLevelString)); - Assert.Equal("Error", eventLevelString); + Assert.True(SelfDiagnosticsConfigParser.TryParseLogLevel(configJson, out string logLevelString)); + Assert.Equal("Error", logLevelString); } } }