Skip to content
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

Refactor Logging.Console configure options #82254

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -16,34 +16,16 @@ namespace Microsoft.Extensions.Logging
/// Doesn't use ConfigurationBinder in order to allow ConfigurationBinder, and all its dependencies,
/// to be trimmed. This improves app size and startup.
/// </remarks>
[UnsupportedOSPlatform("browser")]
internal sealed class ConsoleFormatterConfigureOptions : IConfigureOptions<ConsoleFormatterOptions>
{
private readonly IConfiguration _configuration;

[UnsupportedOSPlatform("browser")]
public ConsoleFormatterConfigureOptions(ILoggerProviderConfiguration<ConsoleLoggerProvider> providerConfiguration)
{
_configuration = providerConfiguration.GetFormatterOptionsSection();
}

public void Configure(ConsoleFormatterOptions options) => Bind(_configuration, options);

public static void Bind(IConfiguration configuration, ConsoleFormatterOptions options)
{
if (ConsoleLoggerConfigureOptions.ParseBool(configuration, "IncludeScopes", out bool includeScopes))
{
options.IncludeScopes = includeScopes;
}

if (configuration["TimestampFormat"] is string timestampFormat)
{
options.TimestampFormat = timestampFormat;
}

if (ConsoleLoggerConfigureOptions.ParseBool(configuration, "UseUtcTimestamp", out bool useUtcTimestamp))
{
options.UseUtcTimestamp = useUtcTimestamp;
}
}
public void Configure(ConsoleFormatterOptions options) => options.Configure(_configuration);
}
}
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using System;
using System.Diagnostics.CodeAnalysis;
using System.Text;
using Microsoft.Extensions.Configuration;

namespace Microsoft.Extensions.Logging.Console
{
Expand Down Expand Up @@ -32,5 +31,23 @@ public ConsoleFormatterOptions() { }
/// Gets or sets indication whether or not UTC timezone should be used to format timestamps in logging messages. Defaults to <c>false</c>.
/// </summary>
public bool UseUtcTimestamp { get; set; }

internal virtual void Configure(IConfiguration configuration)
{
if (ConsoleLoggerOptions.ParseBool(configuration, nameof(IncludeScopes), out bool includeScopes))
{
IncludeScopes = includeScopes;
}

if (configuration[nameof(TimestampFormat)] is string timestampFormat)
{
TimestampFormat = timestampFormat;
}

if (ConsoleLoggerOptions.ParseBool(configuration, nameof(UseUtcTimestamp), out bool useUtcTimestamp))
{
UseUtcTimestamp = useUtcTimestamp;
}
}
}
}
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using System;
using System.Globalization;
using System.Runtime.Versioning;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Logging.Configuration;
Expand All @@ -18,155 +16,16 @@ namespace Microsoft.Extensions.Logging
/// Doesn't use ConfigurationBinder in order to allow ConfigurationBinder, and all its dependencies,
/// to be trimmed. This improves app size and startup.
/// </remarks>
[UnsupportedOSPlatform("browser")]
internal sealed class ConsoleLoggerConfigureOptions : IConfigureOptions<ConsoleLoggerOptions>
{
private readonly IConfiguration _configuration;

[UnsupportedOSPlatform("browser")]
public ConsoleLoggerConfigureOptions(ILoggerProviderConfiguration<ConsoleLoggerProvider> providerConfiguration)
{
_configuration = providerConfiguration.Configuration;
}

public void Configure(ConsoleLoggerOptions options)
{
if (ParseBool(_configuration, "DisableColors", out bool disableColors))
{
#pragma warning disable CS0618 // Type or member is obsolete
options.DisableColors = disableColors;
#pragma warning restore CS0618 // Type or member is obsolete
}

#pragma warning disable CS0618 // Type or member is obsolete
if (ParseEnum(_configuration, "Format", out ConsoleLoggerFormat format))
{
options.Format = format;
}
#pragma warning restore CS0618 // Type or member is obsolete

if (_configuration["FormatterName"] is string formatterName)
{
options.FormatterName = formatterName;
}

if (ParseBool(_configuration, "IncludeScopes", out bool includeScopes))
{
#pragma warning disable CS0618 // Type or member is obsolete
options.IncludeScopes = includeScopes;
#pragma warning restore CS0618 // Type or member is obsolete
}

if (ParseEnum(_configuration, "LogToStandardErrorThreshold", out LogLevel logToStandardErrorThreshold))
{
options.LogToStandardErrorThreshold = logToStandardErrorThreshold;
}

if (ParseInt(_configuration, "MaxQueueLength", out int maxQueueLength))
{
options.MaxQueueLength = maxQueueLength;
}

if (ParseEnum(_configuration, "QueueFullMode", out ConsoleLoggerQueueFullMode queueFullMode))
{
options.QueueFullMode = queueFullMode;
}

if (_configuration["TimestampFormat"] is string timestampFormat)
{
#pragma warning disable CS0618 // Type or member is obsolete
options.TimestampFormat = timestampFormat;
#pragma warning restore CS0618 // Type or member is obsolete
}

if (ParseBool(_configuration, "UseUtcTimestamp", out bool useUtcTimestamp))
{
#pragma warning disable CS0618 // Type or member is obsolete
options.UseUtcTimestamp = useUtcTimestamp;
#pragma warning restore CS0618 // Type or member is obsolete
}
}

/// <summary>
/// Parses the configuration value at the specified key into a bool.
/// </summary>
/// <returns>true if the value was successfully found and parsed. false if the key wasn't found.</returns>
/// <exception cref="InvalidOperationException">Thrown when invalid data was found at the specified configuration key.</exception>
public static bool ParseBool(IConfiguration configuration, string key, out bool value)
{
if (configuration[key] is string valueString)
{
try
{
value = bool.Parse(valueString);
return true;
}
catch (Exception e)
{
ThrowInvalidConfigurationException(configuration, key, typeof(bool), e);
}
}

value = default;
return false;
}

/// <summary>
/// Parses the configuration value at the specified key into an enum.
/// </summary>
/// <returns>true if the value was successfully found and parsed. false if the key wasn't found.</returns>
/// <exception cref="InvalidOperationException">Thrown when invalid data was found at the specified configuration key.</exception>
public static bool ParseEnum<T>(IConfiguration configuration, string key, out T value) where T : struct
{
if (configuration[key] is string valueString)
{
try
{
value =
#if NETFRAMEWORK || NETSTANDARD2_0
(T)Enum.Parse(typeof(T), valueString, ignoreCase: true);
#else
Enum.Parse<T>(valueString, ignoreCase: true);
#endif
return true;
}
catch (Exception e)
{
ThrowInvalidConfigurationException(configuration, key, typeof(T), e);
}
}

value = default;
return false;
}

/// <summary>
/// Parses the configuration value at the specified key into an int.
/// </summary>
/// <returns>true if the value was successfully found and parsed. false if the key wasn't found.</returns>
/// <exception cref="InvalidOperationException">Thrown when invalid data was found at the specified configuration key.</exception>
public static bool ParseInt(IConfiguration configuration, string key, out int value)
{
if (configuration[key] is string valueString)
{
try
{
value = int.Parse(valueString, NumberStyles.Integer, NumberFormatInfo.InvariantInfo);
return true;
}
catch (Exception e)
{
ThrowInvalidConfigurationException(configuration, key, typeof(int), e);
}
}

value = default;
return false;
}

private static void ThrowInvalidConfigurationException(IConfiguration configuration, string key, Type valueType, Exception innerException)
{
IConfigurationSection section = configuration.GetSection(key);
throw new InvalidOperationException(SR.Format(SR.InvalidConfigurationData, section.Path, valueType), innerException);
}
public void Configure(ConsoleLoggerOptions options) => options.Configure(_configuration);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
using System;
using System.Diagnostics.CodeAnalysis;
using System.Runtime.Versioning;
using System.Text.Json;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection.Extensions;
Expand All @@ -29,9 +28,9 @@ public static ILoggingBuilder AddConsole(this ILoggingBuilder builder)
{
builder.AddConfiguration();

builder.AddConsoleFormatter<JsonConsoleFormatter, JsonConsoleFormatterOptions, JsonConsoleFormatterConfigureOptions>();
builder.AddConsoleFormatter<JsonConsoleFormatter, JsonConsoleFormatterOptions, ConsoleFormatterConfigureOptions>();
builder.AddConsoleFormatter<SystemdConsoleFormatter, ConsoleFormatterOptions, ConsoleFormatterConfigureOptions>();
builder.AddConsoleFormatter<SimpleConsoleFormatter, SimpleConsoleFormatterOptions, SimpleConsoleFormatterConfigureOptions>();
builder.AddConsoleFormatter<SimpleConsoleFormatter, SimpleConsoleFormatterOptions, ConsoleFormatterConfigureOptions>();

builder.Services.TryAddEnumerable(ServiceDescriptor.Singleton<ILoggerProvider, ConsoleLoggerProvider>());

Expand Down
Loading