diff --git a/src/Sentry/BuiltInSystemDiagnosticsMeters.cs b/src/Sentry/BuiltInSystemDiagnosticsMeters.cs index d631557531..145546897f 100644 --- a/src/Sentry/BuiltInSystemDiagnosticsMeters.cs +++ b/src/Sentry/BuiltInSystemDiagnosticsMeters.cs @@ -24,10 +24,15 @@ public static partial class BuiltInSystemDiagnosticsMeters /// /// Matches the built-in Microsoft.AspNetCore.Hosting metrics /// -#if NET8_0_OR_GREATER +#if NET9_0_OR_GREATER + public static readonly StringOrRegex MicrosoftAspNetCoreHosting = MicrosoftAspNetCoreHostingRegex; + + [GeneratedRegex(MicrosoftAspNetCoreHostingPattern)] + private static partial Regex MicrosoftAspNetCoreHostingRegex { get; } +#elif NET8_0 public static readonly StringOrRegex MicrosoftAspNetCoreHosting = MicrosoftAspNetCoreHostingRegex(); - [GeneratedRegex(MicrosoftAspNetCoreHostingPattern, RegexOptions.Compiled)] + [GeneratedRegex(MicrosoftAspNetCoreHostingPattern)] private static partial Regex MicrosoftAspNetCoreHostingRegex(); #else public static readonly StringOrRegex MicrosoftAspNetCoreHosting = new Regex(MicrosoftAspNetCoreHostingPattern, RegexOptions.Compiled); @@ -36,10 +41,15 @@ public static partial class BuiltInSystemDiagnosticsMeters /// /// Matches the built-in Microsoft.AspNetCore.Routing metrics /// -#if NET8_0_OR_GREATER +#if NET9_0_OR_GREATER + public static readonly StringOrRegex MicrosoftAspNetCoreRouting = MicrosoftAspNetCoreRoutingRegex; + + [GeneratedRegex(MicrosoftAspNetCoreRoutingPattern)] + private static partial Regex MicrosoftAspNetCoreRoutingRegex { get; } +#elif NET8_0 public static readonly StringOrRegex MicrosoftAspNetCoreRouting = MicrosoftAspNetCoreRoutingRegex(); - [GeneratedRegex(MicrosoftAspNetCoreRoutingPattern, RegexOptions.Compiled)] + [GeneratedRegex(MicrosoftAspNetCoreRoutingPattern)] private static partial Regex MicrosoftAspNetCoreRoutingRegex(); #else public static readonly StringOrRegex MicrosoftAspNetCoreRouting = new Regex(MicrosoftAspNetCoreRoutingPattern, RegexOptions.Compiled); @@ -48,10 +58,15 @@ public static partial class BuiltInSystemDiagnosticsMeters /// /// Matches the built-in Microsoft.AspNetCore.Diagnostics metrics /// -#if NET8_0_OR_GREATER +#if NET9_0_OR_GREATER + public static readonly StringOrRegex MicrosoftAspNetCoreDiagnostics = MicrosoftAspNetCoreDiagnosticsRegex; + + [GeneratedRegex(MicrosoftAspNetCoreDiagnosticsPattern)] + private static partial Regex MicrosoftAspNetCoreDiagnosticsRegex { get; } +#elif NET8_0 public static readonly StringOrRegex MicrosoftAspNetCoreDiagnostics = MicrosoftAspNetCoreDiagnosticsRegex(); - [GeneratedRegex(MicrosoftAspNetCoreDiagnosticsPattern, RegexOptions.Compiled)] + [GeneratedRegex(MicrosoftAspNetCoreDiagnosticsPattern)] private static partial Regex MicrosoftAspNetCoreDiagnosticsRegex(); #else public static readonly StringOrRegex MicrosoftAspNetCoreDiagnostics = new Regex(MicrosoftAspNetCoreDiagnosticsPattern, RegexOptions.Compiled); @@ -60,10 +75,15 @@ public static partial class BuiltInSystemDiagnosticsMeters /// /// Matches the built-in Microsoft.AspNetCore.RateLimiting metrics /// -#if NET8_0_OR_GREATER +#if NET9_0_OR_GREATER + public static readonly StringOrRegex MicrosoftAspNetCoreRateLimiting = MicrosoftAspNetCoreRateLimitingRegex; + + [GeneratedRegex(MicrosoftAspNetCoreRateLimitingPattern)] + private static partial Regex MicrosoftAspNetCoreRateLimitingRegex { get; } +#elif NET8_0 public static readonly StringOrRegex MicrosoftAspNetCoreRateLimiting = MicrosoftAspNetCoreRateLimitingRegex(); - [GeneratedRegex(MicrosoftAspNetCoreRateLimitingPattern, RegexOptions.Compiled)] + [GeneratedRegex(MicrosoftAspNetCoreRateLimitingPattern)] private static partial Regex MicrosoftAspNetCoreRateLimitingRegex(); #else public static readonly StringOrRegex MicrosoftAspNetCoreRateLimiting = new Regex(MicrosoftAspNetCoreRateLimitingPattern, RegexOptions.Compiled); @@ -72,10 +92,15 @@ public static partial class BuiltInSystemDiagnosticsMeters /// /// Matches the built-in Microsoft.AspNetCore.HeaderParsing metrics /// -#if NET8_0_OR_GREATER +#if NET9_0_OR_GREATER + public static readonly StringOrRegex MicrosoftAspNetCoreHeaderParsing = MicrosoftAspNetCoreHeaderParsingRegex; + + [GeneratedRegex(MicrosoftAspNetCoreHeaderParsingPattern)] + private static partial Regex MicrosoftAspNetCoreHeaderParsingRegex { get; } +#elif NET8_0 public static readonly StringOrRegex MicrosoftAspNetCoreHeaderParsing = MicrosoftAspNetCoreHeaderParsingRegex(); - [GeneratedRegex(MicrosoftAspNetCoreHeaderParsingPattern, RegexOptions.Compiled)] + [GeneratedRegex(MicrosoftAspNetCoreHeaderParsingPattern)] private static partial Regex MicrosoftAspNetCoreHeaderParsingRegex(); #else public static readonly StringOrRegex MicrosoftAspNetCoreHeaderParsing = new Regex(MicrosoftAspNetCoreHeaderParsingPattern, RegexOptions.Compiled); @@ -84,10 +109,15 @@ public static partial class BuiltInSystemDiagnosticsMeters /// /// Matches the built-in Microsoft.AspNetCore.Server.Kestrel metrics /// -#if NET8_0_OR_GREATER +#if NET9_0_OR_GREATER + public static readonly StringOrRegex MicrosoftAspNetCoreServerKestrel = MicrosoftAspNetCoreServerKestrelRegex; + + [GeneratedRegex(MicrosoftAspNetCoreServerKestrelPattern)] + private static partial Regex MicrosoftAspNetCoreServerKestrelRegex { get; } +#elif NET8_0 public static readonly StringOrRegex MicrosoftAspNetCoreServerKestrel = MicrosoftAspNetCoreServerKestrelRegex(); - [GeneratedRegex(MicrosoftAspNetCoreServerKestrelPattern, RegexOptions.Compiled)] + [GeneratedRegex(MicrosoftAspNetCoreServerKestrelPattern)] private static partial Regex MicrosoftAspNetCoreServerKestrelRegex(); #else public static readonly StringOrRegex MicrosoftAspNetCoreServerKestrel = new Regex(MicrosoftAspNetCoreServerKestrelPattern, RegexOptions.Compiled); @@ -96,10 +126,15 @@ public static partial class BuiltInSystemDiagnosticsMeters /// /// Matches the built-in Microsoft.AspNetCore.Http.Connections metrics /// -#if NET8_0_OR_GREATER +#if NET9_0_OR_GREATER + public static readonly StringOrRegex MicrosoftAspNetCoreHttpConnections = MicrosoftAspNetCoreHttpConnectionsRegex; + + [GeneratedRegex(MicrosoftAspNetCoreHttpConnectionsPattern)] + private static partial Regex MicrosoftAspNetCoreHttpConnectionsRegex { get; } +#elif NET8_0 public static readonly StringOrRegex MicrosoftAspNetCoreHttpConnections = MicrosoftAspNetCoreHttpConnectionsRegex(); - [GeneratedRegex(MicrosoftAspNetCoreHttpConnectionsPattern, RegexOptions.Compiled)] + [GeneratedRegex(MicrosoftAspNetCoreHttpConnectionsPattern)] private static partial Regex MicrosoftAspNetCoreHttpConnectionsRegex(); #else public static readonly StringOrRegex MicrosoftAspNetCoreHttpConnections = new Regex(MicrosoftAspNetCoreHttpConnectionsPattern, RegexOptions.Compiled); @@ -108,10 +143,15 @@ public static partial class BuiltInSystemDiagnosticsMeters /// /// Matches the built-in Microsoft.Extensions.Diagnostics.HealthChecks metrics /// -#if NET8_0_OR_GREATER +#if NET9_0_OR_GREATER + public static readonly StringOrRegex MicrosoftExtensionsDiagnosticsHealthChecks = MicrosoftExtensionsDiagnosticsHealthChecksRegex; + + [GeneratedRegex(MicrosoftExtensionsDiagnosticsHealthChecksPattern)] + private static partial Regex MicrosoftExtensionsDiagnosticsHealthChecksRegex { get; } +#elif NET8_0 public static readonly StringOrRegex MicrosoftExtensionsDiagnosticsHealthChecks = MicrosoftExtensionsDiagnosticsHealthChecksRegex(); - [GeneratedRegex(MicrosoftExtensionsDiagnosticsHealthChecksPattern, RegexOptions.Compiled)] + [GeneratedRegex(MicrosoftExtensionsDiagnosticsHealthChecksPattern)] private static partial Regex MicrosoftExtensionsDiagnosticsHealthChecksRegex(); #else public static readonly StringOrRegex MicrosoftExtensionsDiagnosticsHealthChecks = new Regex(MicrosoftExtensionsDiagnosticsHealthChecksPattern, RegexOptions.Compiled); @@ -120,10 +160,15 @@ public static partial class BuiltInSystemDiagnosticsMeters /// /// Matches the built-in Microsoft.Extensions.Diagnostics.ResourceMonitoring metrics /// -#if NET8_0_OR_GREATER +#if NET9_0_OR_GREATER + public static readonly StringOrRegex MicrosoftExtensionsDiagnosticsResourceMonitoring = MicrosoftExtensionsDiagnosticsResourceMonitoringRegex; + + [GeneratedRegex(MicrosoftExtensionsDiagnosticsResourceMonitoringPattern)] + private static partial Regex MicrosoftExtensionsDiagnosticsResourceMonitoringRegex { get; } +#elif NET8_0 public static readonly StringOrRegex MicrosoftExtensionsDiagnosticsResourceMonitoring = MicrosoftExtensionsDiagnosticsResourceMonitoringRegex(); - [GeneratedRegex(MicrosoftExtensionsDiagnosticsResourceMonitoringPattern, RegexOptions.Compiled)] + [GeneratedRegex(MicrosoftExtensionsDiagnosticsResourceMonitoringPattern)] private static partial Regex MicrosoftExtensionsDiagnosticsResourceMonitoringRegex(); #else public static readonly StringOrRegex MicrosoftExtensionsDiagnosticsResourceMonitoring = new Regex(MicrosoftExtensionsDiagnosticsResourceMonitoringPattern, RegexOptions.Compiled); @@ -132,10 +177,15 @@ public static partial class BuiltInSystemDiagnosticsMeters /// /// Matches the built-in System.Net.NameResolution metrics /// -#if NET8_0_OR_GREATER +#if NET9_0_OR_GREATER + public static readonly StringOrRegex OpenTelemetryInstrumentationRuntime = OpenTelemetryInstrumentationRuntimeRegex; + + [GeneratedRegex(OpenTelemetryInstrumentationRuntimePattern)] + private static partial Regex OpenTelemetryInstrumentationRuntimeRegex { get; } +#elif NET8_0 public static readonly StringOrRegex OpenTelemetryInstrumentationRuntime = OpenTelemetryInstrumentationRuntimeRegex(); - [GeneratedRegex(OpenTelemetryInstrumentationRuntimePattern, RegexOptions.Compiled)] + [GeneratedRegex(OpenTelemetryInstrumentationRuntimePattern)] private static partial Regex OpenTelemetryInstrumentationRuntimeRegex(); #else public static readonly StringOrRegex OpenTelemetryInstrumentationRuntime = new Regex(OpenTelemetryInstrumentationRuntimePattern, RegexOptions.Compiled); @@ -144,10 +194,15 @@ public static partial class BuiltInSystemDiagnosticsMeters /// /// Matches the built-in System.Net.NameResolution metrics /// -#if NET8_0_OR_GREATER +#if NET9_0_OR_GREATER + public static readonly StringOrRegex SystemNetNameResolution = SystemNetNameResolutionRegex; + + [GeneratedRegex(SystemNetNameResolutionPattern)] + private static partial Regex SystemNetNameResolutionRegex { get; } +#elif NET8_0 public static readonly StringOrRegex SystemNetNameResolution = SystemNetNameResolutionRegex(); - [GeneratedRegex(SystemNetNameResolutionPattern, RegexOptions.Compiled)] + [GeneratedRegex(SystemNetNameResolutionPattern)] private static partial Regex SystemNetNameResolutionRegex(); #else public static readonly StringOrRegex SystemNetNameResolution = new Regex(SystemNetNameResolutionPattern, RegexOptions.Compiled); @@ -156,10 +211,15 @@ public static partial class BuiltInSystemDiagnosticsMeters /// /// Matches the built-in metrics /// -#if NET8_0_OR_GREATER +#if NET9_0_OR_GREATER + public static readonly StringOrRegex SystemNetHttp = SystemNetHttpRegex; + + [GeneratedRegex(SystemNetHttpPattern)] + private static partial Regex SystemNetHttpRegex { get; } +#elif NET8_0 public static readonly StringOrRegex SystemNetHttp = SystemNetHttpRegex(); - [GeneratedRegex(SystemNetHttpPattern, RegexOptions.Compiled)] + [GeneratedRegex(SystemNetHttpPattern)] private static partial Regex SystemNetHttpRegex(); #else public static readonly StringOrRegex SystemNetHttp = new Regex(SystemNetHttpPattern, RegexOptions.Compiled); diff --git a/src/Sentry/Internal/OriginHelper.cs b/src/Sentry/Internal/OriginHelper.cs index c3be3e95c9..0bd0aa0957 100644 --- a/src/Sentry/Internal/OriginHelper.cs +++ b/src/Sentry/Internal/OriginHelper.cs @@ -5,12 +5,15 @@ internal static partial class OriginHelper internal const string Manual = "manual"; private const string ValidOriginPattern = @"^(auto|manual)(\.[\w]+){0,3}$"; -#if NET8_0_OR_GREATER - [GeneratedRegex(ValidOriginPattern, RegexOptions.Compiled)] - private static partial Regex ValidOriginRegEx(); - private static readonly Regex ValidOrigin = ValidOriginRegEx(); +#if NET9_0_OR_GREATER + [GeneratedRegex(ValidOriginPattern)] + private static partial Regex ValidOrigin { get; } +#elif NET8_0 + [GeneratedRegex(ValidOriginPattern)] + private static partial Regex ValidOriginRegex(); + private static readonly Regex ValidOrigin = ValidOriginRegex(); #else - private static readonly Regex ValidOrigin = new (ValidOriginPattern, RegexOptions.Compiled); + private static readonly Regex ValidOrigin = new(ValidOriginPattern, RegexOptions.Compiled); #endif public static bool IsValidOrigin(string? value) => value == null || ValidOrigin.IsMatch(value); diff --git a/src/Sentry/MetricHelper.cs b/src/Sentry/MetricHelper.cs index d9d2d0743e..f05b20e6c6 100644 --- a/src/Sentry/MetricHelper.cs +++ b/src/Sentry/MetricHelper.cs @@ -18,6 +18,40 @@ internal static partial class MetricHelper private static readonly DateTimeOffset UnixEpoch = new DateTimeOffset(1970, 1, 1, 0, 0, 0, 0, TimeSpan.Zero); #endif +#if NET9_0_OR_GREATER + [GeneratedRegex(InvalidMetricKeyOrNameCharactersPattern)] + private static partial Regex InvalidMetricKeyOrNameCharacters { get; } + + [GeneratedRegex(InvalidTagKeyCharactersPattern)] + private static partial Regex InvalidTagKeyCharacters { get; } + + [GeneratedRegex(InvalidMetricUnitCharactersPattern)] + private static partial Regex InvalidMetricUnitCharacters { get; } +#elif NET8_0 + [GeneratedRegex(InvalidMetricKeyOrNameCharactersPattern)] + private static partial Regex InvalidMetricKeyOrNameCharacters(); + + [GeneratedRegex(InvalidTagKeyCharactersPattern)] + private static partial Regex InvalidTagKeyCharacters(); + + [GeneratedRegex(InvalidMetricUnitCharactersPattern)] + private static partial Regex InvalidMetricUnitCharacters(); +#else + private static readonly Regex InvalidMetricKeyOrNameCharacters = new(InvalidMetricKeyOrNameCharactersPattern, RegexOptions.Compiled); + private static readonly Regex InvalidTagKeyCharacters = new(InvalidTagKeyCharactersPattern, RegexOptions.Compiled); + private static readonly Regex InvalidMetricUnitCharacters = new(InvalidMetricUnitCharactersPattern, RegexOptions.Compiled); +#endif + +#if NET8_0 + internal static string SanitizeMetricKeyOrName(string input) => InvalidMetricKeyOrNameCharacters().Replace(input, "_"); + internal static string SanitizeTagKey(string input) => InvalidTagKeyCharacters().Replace(input, ""); + internal static string SanitizeMetricUnit(string input) => InvalidMetricUnitCharacters().Replace(input, ""); +#else + internal static string SanitizeMetricKeyOrName(string input) => InvalidMetricKeyOrNameCharacters.Replace(input, "_"); + internal static string SanitizeTagKey(string input) => InvalidTagKeyCharacters.Replace(input, ""); + internal static string SanitizeMetricUnit(string input) => InvalidMetricUnitCharacters.Replace(input, ""); +#endif + internal static long GetDayBucketKey(this DateTimeOffset timestamp) { var utc = timestamp.ToUniversalTime(); @@ -43,29 +77,6 @@ internal static DateTimeOffset GetCutoff() => DateTimeOffset.UtcNow .Subtract(TimeSpan.FromSeconds(RollupInSeconds)) .Subtract(TimeSpan.FromMilliseconds(FlushShift)); -#if NET7_0_OR_GREATER - [GeneratedRegex(InvalidMetricKeyOrNameCharactersPattern, RegexOptions.Compiled)] - private static partial Regex InvalidMetricKeyOrNameCharacters(); - internal static string SanitizeMetricKeyOrName(string input) => InvalidMetricKeyOrNameCharacters().Replace(input, "_"); - - [GeneratedRegex(InvalidTagKeyCharactersPattern, RegexOptions.Compiled)] - private static partial Regex InvalidTagKeyCharacters(); - internal static string SanitizeTagKey(string input) => InvalidTagKeyCharacters().Replace(input, ""); - - [GeneratedRegex(InvalidMetricUnitCharactersPattern, RegexOptions.Compiled)] - private static partial Regex InvalidMetricUnitCharacters(); - internal static string SanitizeMetricUnit(string input) => InvalidMetricUnitCharacters().Replace(input, ""); -#else - private static readonly Regex InvalidMetricKeyOrNameCharacters = new(InvalidMetricKeyOrNameCharactersPattern, RegexOptions.Compiled); - internal static string SanitizeMetricKeyOrName(string input) => InvalidMetricKeyOrNameCharacters.Replace(input, "_"); - - private static readonly Regex InvalidTagKeyCharacters = new(InvalidTagKeyCharactersPattern, RegexOptions.Compiled); - internal static string SanitizeTagKey(string input) => InvalidTagKeyCharacters.Replace(input, ""); - - private static readonly Regex InvalidMetricUnitCharacters = new(InvalidMetricUnitCharactersPattern, RegexOptions.Compiled); - internal static string SanitizeMetricUnit(string input) => InvalidMetricUnitCharacters.Replace(input, ""); -#endif - private static readonly Lazy[]> LazyTagValueReplacements = new(() => [ new KeyValuePair("\n", @"\n"), diff --git a/src/Sentry/SentryMonitorOptions.cs b/src/Sentry/SentryMonitorOptions.cs index 91d6d7dbeb..c61aa7e4ab 100644 --- a/src/Sentry/SentryMonitorOptions.cs +++ b/src/Sentry/SentryMonitorOptions.cs @@ -51,11 +51,6 @@ public enum SentryMonitorInterval /// public partial class SentryMonitorOptions : ISentryJsonSerializable { - private SentryMonitorScheduleType _type = SentryMonitorScheduleType.None; - private string? _crontab; - private int? _interval; - private SentryMonitorInterval? _unit; - // Breakdown of the validation // ^(\*|([0-5]?\d)) Minute 0 - 59 // (\s+)(\*|([01]?\d|2[0-3])) Hour 0 - 23 @@ -63,18 +58,22 @@ public partial class SentryMonitorOptions : ISentryJsonSerializable // (\s+)(\*|([1-9]|1[0-2])) Month 1 - 12 // (\s+)(\*|([0-7])) Weekday 0 - 7 // $ End of string -#if NET7_0_OR_GREATER - [GeneratedRegex(@"^(\*|([0-5]?\d))(\s+)(\*|([01]?\d|2[0-3]))(\s+)(\*|([1-9]|[12]\d|3[01]))(\s+)(\*|([1-9]|1[0-2]))(\s+)(\*|([0-7]))$", RegexOptions.IgnoreCase)] - private static partial Regex CrontabValidation(); -#else - private static Regex? CrontabValidationInstance; + private const string ValidCrontabPattern = @"^(\*|([0-5]?\d))(\s+)(\*|([01]?\d|2[0-3]))(\s+)(\*|([1-9]|[12]\d|3[01]))(\s+)(\*|([1-9]|1[0-2]))(\s+)(\*|([0-7]))$"; - private static Regex CrontabValidation() - { - return CrontabValidationInstance ??= new Regex( - @"^(\*|([0-5]?\d))(\s+)(\*|([01]?\d|2[0-3]))(\s+)(\*|([1-9]|[12]\d|3[01]))(\s+)(\*|([1-9]|1[0-2]))(\s+)(\*|([0-7]))$", - RegexOptions.Compiled | RegexOptions.CultureInvariant); - } + private SentryMonitorScheduleType _type = SentryMonitorScheduleType.None; + private string? _crontab; + private int? _interval; + private SentryMonitorInterval? _unit; + +#if NET9_0_OR_GREATER + [GeneratedRegex(ValidCrontabPattern, RegexOptions.IgnoreCase)] + private static partial Regex ValidCrontab { get; } +#elif NET8_0 + [GeneratedRegex(ValidCrontabPattern, RegexOptions.IgnoreCase)] + private static partial Regex ValidCrontabRegex(); + private static readonly Regex ValidCrontab = ValidCrontabRegex(); +#else + private static readonly Regex ValidCrontab = new(ValidCrontabPattern, RegexOptions.Compiled | RegexOptions.CultureInvariant); #endif /// @@ -88,7 +87,7 @@ public void Interval(string crontab) throw new ArgumentException("You tried to set the interval twice. The Check-Ins interval is supposed to be set only once."); } - if (!CrontabValidation().IsMatch(crontab)) + if (!ValidCrontab.IsMatch(crontab)) { throw new ArgumentException("The provided crontab does not match the expected format of '* * * * *' " + "translating to 'minute', 'hour', 'day of the month', 'month', and 'day of the week'.");