diff --git a/src/OpenTelemetry/Internal/SelfDiagnosticsConfigParser.cs b/src/OpenTelemetry/Internal/SelfDiagnosticsConfigParser.cs
index 13ba5fc4df7..abdcef84e0d 100644
--- a/src/OpenTelemetry/Internal/SelfDiagnosticsConfigParser.cs
+++ b/src/OpenTelemetry/Internal/SelfDiagnosticsConfigParser.cs
@@ -8,7 +8,10 @@
namespace OpenTelemetry.Internal;
-internal sealed class SelfDiagnosticsConfigParser
+///
+/// Parses the self-diagnostics configuration file.
+///
+internal sealed partial class SelfDiagnosticsConfigParser
{
public const string ConfigFileName = "OTEL_DIAGNOSTICS.json";
private const int FileSizeLowerLimit = 1024; // Lower limit for log file size in KB: 1MB
@@ -19,17 +22,20 @@ internal sealed class SelfDiagnosticsConfigParser
///
private const int ConfigBufferSize = 4 * 1024;
- private static readonly Regex LogDirectoryRegex = new(
- @"""LogDirectory""\s*:\s*""(?.*?)""", RegexOptions.IgnoreCase | RegexOptions.Compiled);
+ private const string LogDirectoryRegexPattern = @"""LogDirectory""\s*:\s*""(?.*?)""";
+ private const string FileSizeRegexPattern = @"""FileSize""\s*:\s*(?\d+)";
+ private const string LogLevelRegexPattern = @"""LogLevel""\s*:\s*""(?.*?)""";
+ private const string FormatMessageRegexPattern = @"""FormatMessage""\s*:\s*(?:""(?.*?)""|(?true|false))";
- private static readonly Regex FileSizeRegex = new(
- @"""FileSize""\s*:\s*(?\d+)", RegexOptions.IgnoreCase | RegexOptions.Compiled);
+#if !NET
+ private static readonly Regex LogDirectoryRegex = new(LogDirectoryRegexPattern, RegexOptions.IgnoreCase | RegexOptions.Compiled);
- private static readonly Regex LogLevelRegex = new(
- @"""LogLevel""\s*:\s*""(?.*?)""", RegexOptions.IgnoreCase | RegexOptions.Compiled);
+ private static readonly Regex FileSizeRegex = new(FileSizeRegexPattern, RegexOptions.IgnoreCase | RegexOptions.Compiled);
- private static readonly Regex FormatMessageRegex = new(
- @"""FormatMessage""\s*:\s*(?:""(?.*?)""|(?true|false))", RegexOptions.IgnoreCase | RegexOptions.Compiled);
+ private static readonly Regex LogLevelRegex = new(LogLevelRegexPattern, RegexOptions.IgnoreCase | RegexOptions.Compiled);
+
+ private static readonly Regex FormatMessageRegex = new(FormatMessageRegexPattern, RegexOptions.IgnoreCase | RegexOptions.Compiled);
+#endif
// This class is called in SelfDiagnosticsConfigRefresher.UpdateMemoryMappedFileFromConfiguration
// in both main thread and the worker thread.
@@ -128,7 +134,7 @@ internal static bool TryParseLogDirectory(
string configJson,
out string logDirectory)
{
- var logDirectoryResult = LogDirectoryRegex.Match(configJson);
+ var logDirectoryResult = GetLogDirectoryRegex().Match(configJson);
logDirectory = logDirectoryResult.Groups["LogDirectory"].Value;
return logDirectoryResult.Success && !string.IsNullOrWhiteSpace(logDirectory);
}
@@ -136,7 +142,7 @@ internal static bool TryParseLogDirectory(
internal static bool TryParseFileSize(string configJson, out int fileSizeInKB)
{
fileSizeInKB = 0;
- var fileSizeResult = FileSizeRegex.Match(configJson);
+ var fileSizeResult = GetFileSizeRegex().Match(configJson);
return fileSizeResult.Success && int.TryParse(fileSizeResult.Groups["FileSize"].Value, out fileSizeInKB);
}
@@ -145,7 +151,7 @@ internal static bool TryParseLogLevel(
[NotNullWhen(true)]
out string? logLevel)
{
- var logLevelResult = LogLevelRegex.Match(configJson);
+ var logLevelResult = GetLogLevelRegex().Match(configJson);
logLevel = logLevelResult.Groups["LogLevel"].Value;
return logLevelResult.Success && !string.IsNullOrWhiteSpace(logLevel);
}
@@ -153,7 +159,7 @@ internal static bool TryParseLogLevel(
internal static bool TryParseFormatMessage(string configJson, out bool formatMessage)
{
formatMessage = false;
- var formatMessageResult = FormatMessageRegex.Match(configJson);
+ var formatMessageResult = GetFormatMessageRegex().Match(configJson);
if (formatMessageResult.Success)
{
var formatMessageValue = formatMessageResult.Groups["FormatMessage"].Value;
@@ -162,4 +168,26 @@ internal static bool TryParseFormatMessage(string configJson, out bool formatMes
return true;
}
+
+#if NET
+ [GeneratedRegex(LogDirectoryRegexPattern, RegexOptions.IgnoreCase)]
+ private static partial Regex GetLogDirectoryRegex();
+
+ [GeneratedRegex(FileSizeRegexPattern, RegexOptions.IgnoreCase)]
+ private static partial Regex GetFileSizeRegex();
+
+ [GeneratedRegex(LogLevelRegexPattern, RegexOptions.IgnoreCase)]
+ private static partial Regex GetLogLevelRegex();
+
+ [GeneratedRegex(FormatMessageRegexPattern, RegexOptions.IgnoreCase)]
+ private static partial Regex GetFormatMessageRegex();
+#else
+ private static Regex GetLogDirectoryRegex() => LogDirectoryRegex;
+
+ private static Regex GetFileSizeRegex() => FileSizeRegex;
+
+ private static Regex GetLogLevelRegex() => LogLevelRegex;
+
+ private static Regex GetFormatMessageRegex() => FormatMessageRegex;
+#endif
}
diff --git a/src/OpenTelemetry/Metrics/Builder/MeterProviderBuilderSdk.cs b/src/OpenTelemetry/Metrics/Builder/MeterProviderBuilderSdk.cs
index 11084ec7f0d..c29bf3238ae 100644
--- a/src/OpenTelemetry/Metrics/Builder/MeterProviderBuilderSdk.cs
+++ b/src/OpenTelemetry/Metrics/Builder/MeterProviderBuilderSdk.cs
@@ -13,11 +13,12 @@ namespace OpenTelemetry.Metrics;
///
/// Stores state used to build a .
///
-internal sealed class MeterProviderBuilderSdk : MeterProviderBuilder, IMeterProviderBuilder
+internal sealed partial class MeterProviderBuilderSdk : MeterProviderBuilder, IMeterProviderBuilder
{
public const int DefaultMetricLimit = 1000;
public const int DefaultCardinalityLimit = 2000;
private const string DefaultInstrumentationVersion = "1.0.0.0";
+ private const string InstrumentNameRegexPattern = @"^[a-z][a-z0-9-._/]{0,254}$";
private readonly IServiceProvider serviceProvider;
private MeterProviderSdk? meterProvider;
@@ -32,10 +33,9 @@ public MeterProviderBuilderSdk(IServiceProvider serviceProvider)
// fields. See: https://github.com/dotnet/runtime/issues/11571.
// Customers: This is not guaranteed to work forever. We may change this
// mechanism in the future do this at your own risk.
- public static Regex InstrumentNameRegex { get; set; } = new(
- @"^[a-z][a-z0-9-._/]{0,254}$", RegexOptions.IgnoreCase | RegexOptions.Compiled);
+ public static Regex InstrumentNameRegex { get; set; } = GetInstrumentNameRegex();
- public List Instrumentation { get; } = new();
+ public List Instrumentation { get; } = [];
public ResourceBuilder? ResourceBuilder { get; private set; }
@@ -43,11 +43,11 @@ public MeterProviderBuilderSdk(IServiceProvider serviceProvider)
public MeterProvider? Provider => this.meterProvider;
- public List Readers { get; } = new();
+ public List Readers { get; } = [];
- public List MeterSources { get; } = new();
+ public List MeterSources { get; } = [];
- public List> ViewConfigs { get; } = new();
+ public List> ViewConfigs { get; } = [];
public int MetricLimit { get; private set; } = DefaultMetricLimit;
@@ -60,14 +60,7 @@ public MeterProviderBuilderSdk(IServiceProvider serviceProvider)
/// The instrument name.
/// Boolean indicating if the instrument is valid.
public static bool IsValidInstrumentName(string instrumentName)
- {
- if (string.IsNullOrWhiteSpace(instrumentName))
- {
- return false;
- }
-
- return InstrumentNameRegex.IsMatch(instrumentName);
- }
+ => !string.IsNullOrWhiteSpace(instrumentName) && InstrumentNameRegex.IsMatch(instrumentName);
///
/// Returns whether the given custom view name is valid according to the specification.
@@ -75,16 +68,9 @@ public static bool IsValidInstrumentName(string instrumentName)
/// See specification: .
/// The view name.
/// Boolean indicating if the instrument is valid.
- public static bool IsValidViewName(string customViewName)
- {
- // Only validate the view name in case it's not null. In case it's null, the view name will be the instrument name as per the spec.
- if (customViewName == null)
- {
- return true;
- }
-
- return InstrumentNameRegex.IsMatch(customViewName);
- }
+ public static bool IsValidViewName(string customViewName) =>
+ /* Only validate the view name in case it's not null. In case it's null, the view name will be the instrument name as per the spec. */
+ customViewName == null || InstrumentNameRegex.IsMatch(customViewName);
public void RegisterProvider(MeterProviderSdk meterProvider)
{
@@ -208,13 +194,18 @@ public MeterProviderBuilder ConfigureBuilder(Action configure)
- {
- throw new NotSupportedException("Services cannot be configured after ServiceProvider has been created.");
- }
+ => throw new NotSupportedException("Services cannot be configured after ServiceProvider has been created.");
MeterProviderBuilder IDeferredMeterProviderBuilder.Configure(Action configure)
=> this.ConfigureBuilder(configure);
+#if NET
+ [GeneratedRegex(InstrumentNameRegexPattern, RegexOptions.IgnoreCase)]
+ private static partial Regex GetInstrumentNameRegex();
+#else
+ private static Regex GetInstrumentNameRegex() => new(InstrumentNameRegexPattern, RegexOptions.IgnoreCase | RegexOptions.Compiled);
+#endif
+
internal readonly struct InstrumentationRegistration
{
public readonly string Name;