From 13bfeaa64fd3e8f520512645bce92af40020f03b Mon Sep 17 00:00:00 2001 From: Maryam Ariyan Date: Tue, 12 May 2020 12:34:47 -0700 Subject: [PATCH 01/15] New APIs for Structured Log Formatting - [x] Allow using both Format and Formatter - [x] Can use Compact and Json Formatter => has option to indent but from ConsoleLoggerOptions => Scopes would print but kvp not properly setup yet - [x] Can use any custom developed ILogFormatter TODO: - [ ] Learn how to configure formatter options - [ ] Add AddCustomLogger(ILoggingBuilder ..) --- .../Microsoft.Extensions.Logging.Console.cs | 33 +- ...icrosoft.Extensions.Logging.Console.csproj | 1 + .../src/ConsoleLogger.cs | 13 +- .../src/ConsoleLoggerFactoryExtensions.cs | 16 + .../src/ConsoleLoggerFormat.cs | 2 +- .../src/ConsoleLoggerOptions.cs | 26 +- .../src/ConsoleLoggerProcessor.cs | 14 +- .../src/ConsoleLoggerProvider.cs | 26 +- .../src/Formatter/CompactLogFormatter.cs | 215 ++++++++++ .../src/Formatter/DefaultLogFormatter.cs | 50 ++- .../Formatter/DefaultLogFormatterOptions.cs | 6 +- .../src/Formatter/ILogFormatter.cs | 7 +- .../src/Formatter/JsonLogFormatter.cs | 405 ++++++++++++++++++ .../src/Formatter/JsonLogFormatterOptions.cs | 17 + .../src/Formatter/SystemdLogFormatter.cs | 48 ++- .../Formatter/SystemdLogFormatterOptions.cs | 5 + .../src/IConsole.cs | 2 +- .../src/LogMessageEntry.cs | 4 +- ...icrosoft.Extensions.Logging.Console.csproj | 3 + 19 files changed, 823 insertions(+), 70 deletions(-) create mode 100644 src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/CompactLogFormatter.cs create mode 100644 src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/JsonLogFormatter.cs create mode 100644 src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/JsonLogFormatterOptions.cs diff --git a/src/libraries/Microsoft.Extensions.Logging.Console/ref/Microsoft.Extensions.Logging.Console.cs b/src/libraries/Microsoft.Extensions.Logging.Console/ref/Microsoft.Extensions.Logging.Console.cs index 7fc8b1d56fd271..78c244d5692399 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Console/ref/Microsoft.Extensions.Logging.Console.cs +++ b/src/libraries/Microsoft.Extensions.Logging.Console/ref/Microsoft.Extensions.Logging.Console.cs @@ -27,6 +27,7 @@ public ConsoleLoggerOptions() { } public Microsoft.Extensions.Logging.Console.ConsoleLoggerFormat Format { get { throw null; } set { } } public string Formatter { get { throw null; } set { } } public bool IncludeScopes { get { throw null; } set { } } + public System.Text.Json.JsonWriterOptions JsonWriterOptions { get { throw null; } set { } } public Microsoft.Extensions.Logging.LogLevel LogToStandardErrorThreshold { get { throw null; } set { } } public string TimestampFormat { get { throw null; } set { } } public bool UseUtcTimestamp { get { throw null; } set { } } @@ -42,17 +43,37 @@ public void SetScopeProvider(Microsoft.Extensions.Logging.IExternalScopeProvider public partial class DefaultLogFormatter : Microsoft.Extensions.Logging.Console.ILogFormatter { public DefaultLogFormatter() { } + public Microsoft.Extensions.Logging.Console.DefaultLogFormatterOptions FormatterOptions { get { throw null; } set { } } public string Name { get { throw null; } } - public Microsoft.Extensions.Logging.Console.LogMessageEntry Format(Microsoft.Extensions.Logging.LogLevel logLevel, string logName, int eventId, string message, System.Exception exception) { throw null; } + public Microsoft.Extensions.Logging.Console.LogMessageEntry Format(Microsoft.Extensions.Logging.LogLevel logLevel, string logName, int eventId, string message, System.Exception exception, Microsoft.Extensions.Logging.Console.ConsoleLoggerOptions options, Microsoft.Extensions.Logging.IExternalScopeProvider scopeProvider) { throw null; } } public partial class DefaultLogFormatterOptions { public DefaultLogFormatterOptions() { } } + public partial interface IConsole + { + void Flush(); + void Write(string message, System.ConsoleColor? background, System.ConsoleColor? foreground); + void WriteLine(string message, System.ConsoleColor? background, System.ConsoleColor? foreground); + } public partial interface ILogFormatter { string Name { get; } - Microsoft.Extensions.Logging.Console.LogMessageEntry Format(Microsoft.Extensions.Logging.LogLevel logLevel, string logName, int eventId, string message, System.Exception exception); + Microsoft.Extensions.Logging.Console.LogMessageEntry Format(Microsoft.Extensions.Logging.LogLevel logLevel, string logName, int eventId, string message, System.Exception exception, Microsoft.Extensions.Logging.Console.ConsoleLoggerOptions options, Microsoft.Extensions.Logging.IExternalScopeProvider scopeProvider); + } + public partial class JsonConsoleLogFormatter : Microsoft.Extensions.Logging.Console.ILogFormatter, System.IDisposable + { + public JsonConsoleLogFormatter(Microsoft.Extensions.Options.IOptionsMonitor options) { } + public Microsoft.Extensions.Logging.Console.JsonLogFormatterOptions FormatterOptions { get { throw null; } set { } } + public string Name { get { throw null; } } + public void Dispose() { } + public Microsoft.Extensions.Logging.Console.LogMessageEntry Format(Microsoft.Extensions.Logging.LogLevel logLevel, string logName, int eventId, string message, System.Exception exception, Microsoft.Extensions.Logging.Console.ConsoleLoggerOptions options, Microsoft.Extensions.Logging.IExternalScopeProvider scopeProvider) { throw null; } + } + public partial class JsonLogFormatterOptions + { + public JsonLogFormatterOptions() { } + public System.Text.Json.JsonWriterOptions JsonWriterOptions { get { throw null; } set { } } } public readonly partial struct LogMessageEntry { @@ -63,13 +84,15 @@ public readonly partial struct LogMessageEntry public readonly string Message; public readonly System.ConsoleColor? MessageColor; public readonly string TimeStamp; - public LogMessageEntry(string message, string timeStamp = null, string levelString = null, System.ConsoleColor? levelBackground = default(System.ConsoleColor?), System.ConsoleColor? levelForeground = default(System.ConsoleColor?), System.ConsoleColor? messageColor = default(System.ConsoleColor?), bool logAsError = false) { throw null; } + public readonly System.Action WriteCallback; + public LogMessageEntry(string message, string timeStamp = null, string levelString = null, System.ConsoleColor? levelBackground = default(System.ConsoleColor?), System.ConsoleColor? levelForeground = default(System.ConsoleColor?), System.ConsoleColor? messageColor = default(System.ConsoleColor?), bool logAsError = false, System.Action writeCallback = null) { throw null; } } public partial class SystemdLogFormatter : Microsoft.Extensions.Logging.Console.ILogFormatter { - public SystemdLogFormatter() { } + public SystemdLogFormatter(Microsoft.Extensions.Options.IOptionsMonitor options) { } + public Microsoft.Extensions.Logging.Console.SystemdLogFormatterOptions FormatterOptions { get { throw null; } set { } } public string Name { get { throw null; } } - public Microsoft.Extensions.Logging.Console.LogMessageEntry Format(Microsoft.Extensions.Logging.LogLevel logLevel, string logName, int eventId, string message, System.Exception exception) { throw null; } + public Microsoft.Extensions.Logging.Console.LogMessageEntry Format(Microsoft.Extensions.Logging.LogLevel logLevel, string logName, int eventId, string message, System.Exception exception, Microsoft.Extensions.Logging.Console.ConsoleLoggerOptions options, Microsoft.Extensions.Logging.IExternalScopeProvider scopeProvider) { throw null; } } public partial class SystemdLogFormatterOptions { diff --git a/src/libraries/Microsoft.Extensions.Logging.Console/ref/Microsoft.Extensions.Logging.Console.csproj b/src/libraries/Microsoft.Extensions.Logging.Console/ref/Microsoft.Extensions.Logging.Console.csproj index 17f4ef6d337e9a..0756d569fde5c5 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Console/ref/Microsoft.Extensions.Logging.Console.csproj +++ b/src/libraries/Microsoft.Extensions.Logging.Console/ref/Microsoft.Extensions.Logging.Console.csproj @@ -5,6 +5,7 @@ + diff --git a/src/libraries/Microsoft.Extensions.Logging.Console/src/ConsoleLogger.cs b/src/libraries/Microsoft.Extensions.Logging.Console/src/ConsoleLogger.cs index ed845afa8299e6..65f6e63d6326b1 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Console/src/ConsoleLogger.cs +++ b/src/libraries/Microsoft.Extensions.Logging.Console/src/ConsoleLogger.cs @@ -3,19 +3,20 @@ // See the LICENSE file in the project root for more information. using System; +using System.CodeDom; using System.Collections.Generic; +using System.Diagnostics; using System.Linq; namespace Microsoft.Extensions.Logging.Console { internal class ConsoleLogger : ILogger { - private readonly IEnumerable _formatters; private readonly string _name; private readonly ConsoleLoggerProcessor _queueProcessor; - internal ConsoleLogger(string name, ConsoleLoggerProcessor loggerProcessor, IEnumerable formatters) + internal ConsoleLogger(string name, ConsoleLoggerProcessor loggerProcessor) { if (name == null) { @@ -24,13 +25,16 @@ internal ConsoleLogger(string name, ConsoleLoggerProcessor loggerProcessor, IEnu _name = name; _queueProcessor = loggerProcessor; - _formatters = formatters; + ScopeProvider = new LoggerExternalScopeProvider(); + } internal IExternalScopeProvider ScopeProvider { get; set; } internal ConsoleLoggerOptions Options { get; set; } + internal ILogFormatter Formatter { get; set; } + public void Log(LogLevel logLevel, EventId eventId, TState state, Exception exception, Func formatter) { if (!IsEnabled(logLevel)) @@ -53,8 +57,7 @@ public void Log(LogLevel logLevel, EventId eventId, TState state, Except public virtual void WriteMessage(LogLevel logLevel, string logName, int eventId, string message, Exception exception) { - var formatter = _formatters.Single(f => f.Name == (Options.Formatter ?? Options.Format.ToString())); - var entry = formatter.Format(logLevel, logName, eventId, message, exception); + var entry = Formatter.Format(logLevel, logName, eventId, message, exception, Options, ScopeProvider); _queueProcessor.EnqueueMessage(entry); } diff --git a/src/libraries/Microsoft.Extensions.Logging.Console/src/ConsoleLoggerFactoryExtensions.cs b/src/libraries/Microsoft.Extensions.Logging.Console/src/ConsoleLoggerFactoryExtensions.cs index 27d2e4872627bd..75441fa6fa97c3 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Console/src/ConsoleLoggerFactoryExtensions.cs +++ b/src/libraries/Microsoft.Extensions.Logging.Console/src/ConsoleLoggerFactoryExtensions.cs @@ -5,8 +5,16 @@ using System; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection.Extensions; +using Microsoft.Extensions.Logging.Abstractions; using Microsoft.Extensions.Logging.Configuration; using Microsoft.Extensions.Logging.Console; +using Microsoft.Extensions.Options; +using System.Collections.Generic; +using System.Collections.Concurrent; +using System.IO; +using System.Linq; +using System.Text; +using System.Threading.Tasks; namespace Microsoft.Extensions.Logging { @@ -20,10 +28,18 @@ public static ILoggingBuilder AddConsole(this ILoggingBuilder builder) { builder.AddConfiguration(); + builder.Services.TryAddEnumerable(ServiceDescriptor.Singleton()); + LoggerProviderOptions.RegisterProviderOptions(builder.Services); + builder.Services.TryAddEnumerable(ServiceDescriptor.Singleton()); + LoggerProviderOptions.RegisterProviderOptions(builder.Services); + builder.Services.TryAddEnumerable(ServiceDescriptor.Singleton()); + LoggerProviderOptions.RegisterProviderOptions(builder.Services); + builder.Services.TryAddEnumerable(ServiceDescriptor.Singleton()); LoggerProviderOptions.RegisterProviderOptions(builder.Services); + return builder; } diff --git a/src/libraries/Microsoft.Extensions.Logging.Console/src/ConsoleLoggerFormat.cs b/src/libraries/Microsoft.Extensions.Logging.Console/src/ConsoleLoggerFormat.cs index df7234ea1cf8a8..5ab4e865c3bfd5 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Console/src/ConsoleLoggerFormat.cs +++ b/src/libraries/Microsoft.Extensions.Logging.Console/src/ConsoleLoggerFormat.cs @@ -16,6 +16,6 @@ public enum ConsoleLoggerFormat /// /// Produces messages in a format suitable for console output to the systemd journal. /// - Systemd + Systemd, } } diff --git a/src/libraries/Microsoft.Extensions.Logging.Console/src/ConsoleLoggerOptions.cs b/src/libraries/Microsoft.Extensions.Logging.Console/src/ConsoleLoggerOptions.cs index 001a01b2e22b45..194bd554d08c45 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Console/src/ConsoleLoggerOptions.cs +++ b/src/libraries/Microsoft.Extensions.Logging.Console/src/ConsoleLoggerOptions.cs @@ -3,6 +3,7 @@ // See the LICENSE file in the project root for more information. using System; +using System.Text.Json; namespace Microsoft.Extensions.Logging.Console { @@ -11,8 +12,6 @@ namespace Microsoft.Extensions.Logging.Console /// public class ConsoleLoggerOptions { - private ConsoleLoggerFormat _format = ConsoleLoggerFormat.Default; - /// /// Includes scopes when . /// @@ -28,14 +27,25 @@ public class ConsoleLoggerOptions /// public ConsoleLoggerFormat Format { - get => _format; + get + { + try { + return (ConsoleLoggerFormat) Enum.Parse(typeof(ConsoleLoggerFormat), Formatter); + } + catch (ArgumentException) { + return ConsoleLoggerFormat.Default; + } + } set { - if (value < ConsoleLoggerFormat.Default || value > ConsoleLoggerFormat.Systemd) + if (value == ConsoleLoggerFormat.Systemd) { - throw new ArgumentOutOfRangeException(nameof(value)); + Formatter = Enum.GetName(typeof(ConsoleLoggerFormat), ConsoleLoggerFormat.Systemd); + } + else + { + Formatter = Enum.GetName(typeof(ConsoleLoggerFormat), ConsoleLoggerFormat.Default); } - _format = value; } } @@ -43,7 +53,7 @@ public ConsoleLoggerFormat Format /// /// public string Formatter { get; set; } - + /// /// Gets or sets value indicating the minimum level of messaged that would get written to Console.Error. /// @@ -58,5 +68,7 @@ public ConsoleLoggerFormat Format /// Gets or sets indication whether or not UTC timezone should be used to for timestamps in logging messages. Defaults to false. /// public bool UseUtcTimestamp { get; set; } + + public JsonWriterOptions JsonWriterOptions { get; set; } } } diff --git a/src/libraries/Microsoft.Extensions.Logging.Console/src/ConsoleLoggerProcessor.cs b/src/libraries/Microsoft.Extensions.Logging.Console/src/ConsoleLoggerProcessor.cs index c7d370e9c30364..988aa5c2fe23de 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Console/src/ConsoleLoggerProcessor.cs +++ b/src/libraries/Microsoft.Extensions.Logging.Console/src/ConsoleLoggerProcessor.cs @@ -53,19 +53,7 @@ public virtual void EnqueueMessage(LogMessageEntry message) internal virtual void WriteMessage(LogMessageEntry message) { var console = message.LogAsError ? ErrorConsole : Console; - - if (message.TimeStamp != null) - { - console.Write(message.TimeStamp, message.MessageColor, message.MessageColor); - } - - if (message.LevelString != null) - { - console.Write(message.LevelString, message.LevelBackground, message.LevelForeground); - } - - console.Write(message.Message, message.MessageColor, message.MessageColor); - console.Flush(); + message.WriteCallback(console); } private void ProcessLogQueue() diff --git a/src/libraries/Microsoft.Extensions.Logging.Console/src/ConsoleLoggerProvider.cs b/src/libraries/Microsoft.Extensions.Logging.Console/src/ConsoleLoggerProvider.cs index 3c19c95db5fdb1..ba495275139625 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Console/src/ConsoleLoggerProvider.cs +++ b/src/libraries/Microsoft.Extensions.Logging.Console/src/ConsoleLoggerProvider.cs @@ -5,6 +5,7 @@ using System; using System.Collections.Concurrent; using System.Collections.Generic; +using System.Linq; using System.Runtime.InteropServices; using Microsoft.Extensions.Options; @@ -18,8 +19,8 @@ public class ConsoleLoggerProvider : ILoggerProvider, ISupportExternalScope { private readonly IOptionsMonitor _options; private readonly ConcurrentDictionary _loggers; + private readonly ConcurrentDictionary _formatters; private readonly ConsoleLoggerProcessor _messageQueue; - private readonly IEnumerable _formatters; private IDisposable _optionsReloadToken; private IExternalScopeProvider _scopeProvider = NullExternalScopeProvider.Instance; @@ -33,7 +34,7 @@ public ConsoleLoggerProvider(IOptionsMonitor options, IEnu { _options = options; _loggers = new ConcurrentDictionary(); - _formatters = formatters; + _formatters = new ConcurrentDictionary(formatters.ToDictionary(f => f.Name)); ReloadLoggerOptions(options.CurrentValue); _optionsReloadToken = _options.OnChange(ReloadLoggerOptions); @@ -51,21 +52,38 @@ public ConsoleLoggerProvider(IOptionsMonitor options, IEnu } } + // warning: ReloadLoggerOptions can be called before the ctor completed,... before registering all of the state used in this method need to be initialized private void ReloadLoggerOptions(ConsoleLoggerOptions options) { + string nameFromFormat = Enum.GetName(typeof(ConsoleLoggerFormat), options?.Format); + _formatters.TryGetValue(options?.Formatter ?? nameFromFormat, out ILogFormatter logFormatter); + if (logFormatter == null) + { + logFormatter = _formatters[nameFromFormat]; + } + foreach (var logger in _loggers) { logger.Value.Options = options; + logger.Value.Formatter = logFormatter; } } /// public ILogger CreateLogger(string name) { - return _loggers.GetOrAdd(name, loggerName => new ConsoleLogger(name, _messageQueue, _formatters) + string nameFromFormat = Enum.GetName(typeof(ConsoleLoggerFormat), _options.CurrentValue.Format); + _formatters.TryGetValue(_options.CurrentValue.Formatter ?? nameFromFormat, out ILogFormatter logFormatter); + if (logFormatter == null) + { + logFormatter = _formatters[nameFromFormat]; + } + + return _loggers.GetOrAdd(name, loggerName => new ConsoleLogger(name, _messageQueue) { Options = _options.CurrentValue, - ScopeProvider = _scopeProvider + ScopeProvider = _scopeProvider, + Formatter = logFormatter }); } diff --git a/src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/CompactLogFormatter.cs b/src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/CompactLogFormatter.cs new file mode 100644 index 00000000000000..ff9ec830349177 --- /dev/null +++ b/src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/CompactLogFormatter.cs @@ -0,0 +1,215 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using System.Text; + +namespace Microsoft.Extensions.Logging.Console +{ + internal class CompactLogFormatter : ILogFormatter + { + private static readonly string _loglevelPadding = ": "; + private static readonly string _messagePadding; + private static readonly string _newLineWithMessagePadding; + + // ConsoleColor does not have a value to specify the 'Default' color + private readonly ConsoleColor? DefaultConsoleColor = null; + + [ThreadStatic] + private static StringBuilder _logBuilder; + + static CompactLogFormatter() + { + var logLevelString = GetLogLevelString(LogLevel.Information); + _messagePadding = new string(' ', logLevelString.Length + _loglevelPadding.Length); + _newLineWithMessagePadding = Environment.NewLine + _messagePadding; + } + + public CompactLogFormatter() { } + + public string Name => "Compact"; + + public LogMessageEntry Format(LogLevel logLevel, string logName, int eventId, string message, Exception exception, ConsoleLoggerOptions options, IExternalScopeProvider scopeProvider) + { + // todo fix later: + var logBuilder = _logBuilder; + _logBuilder = null; + + if (logBuilder == null) + { + logBuilder = new StringBuilder(); + } + + // Example: + // INFO: ConsoleApp.Program[10] + // Request received + + var logLevelColors = GetLogLevelConsoleColors(logLevel, options); + var logLevelString = GetLogLevelString(logLevel); + // category and event id + logBuilder.Append(_loglevelPadding); + logBuilder.Append(logName); + logBuilder.Append("["); + logBuilder.Append(eventId); + logBuilder.Append("]"); + // logBuilder.AppendLine("]"); + + // scope information + GetScopeInformation(logBuilder, options, scopeProvider); + + if (!string.IsNullOrEmpty(message)) + { + // message + logBuilder.Append(_messagePadding); + + var len = logBuilder.Length; + logBuilder.AppendLine(message); + } + + // Example: + // System.InvalidOperationException + // at Namespace.Class.Function() in File:line X + if (exception != null) + { + // exception message + logBuilder.Append(exception.ToString()); + // logBuilder.AppendLine(exception.ToString()); + } + + string timestamp = null; + var timestampFormat = options.TimestampFormat; + if (timestampFormat != null) + { + var dateTime = GetCurrentDateTime(options); + timestamp = dateTime.ToString(timestampFormat); + } + + var formattedMessage = logBuilder.ToString(); + logBuilder.Clear(); + if (logBuilder.Capacity > 1024) + { + logBuilder.Capacity = 1024; + } + _logBuilder = logBuilder; + + return new LogMessageEntry( + message: formattedMessage, + timeStamp: timestamp, + levelString: logLevelString, + levelBackground: logLevelColors.Background, + levelForeground: logLevelColors.Foreground, + messageColor: DefaultConsoleColor, + logAsError: logLevel >= options.LogToStandardErrorThreshold, + writeCallback : console => + { + if (timestamp != null) + { + console.Write(timestamp, DefaultConsoleColor, DefaultConsoleColor); + } + + if (logLevelString != null) + { + console.Write(logLevelString, logLevelColors.Background, logLevelColors.Foreground); + } + + console.Write(formattedMessage, DefaultConsoleColor, DefaultConsoleColor); + console.Flush(); + } + ); + } + + private DateTime GetCurrentDateTime(ConsoleLoggerOptions options) + { + return options.UseUtcTimestamp ? DateTime.UtcNow : DateTime.Now; + } + + private static string GetLogLevelString(LogLevel logLevel) + { + switch (logLevel) + { + case LogLevel.Trace: + return "compact_trce"; + case LogLevel.Debug: + return "compact_dbug"; + case LogLevel.Information: + return "compact_info"; + case LogLevel.Warning: + return "compact_warn"; + case LogLevel.Error: + return "compact_fail"; + case LogLevel.Critical: + return "compact_crit"; + default: + throw new ArgumentOutOfRangeException(nameof(logLevel)); + } + } + + private ConsoleColors GetLogLevelConsoleColors(LogLevel logLevel, ConsoleLoggerOptions options) + { + if (options.DisableColors) + { + return new ConsoleColors(null, null); + } + + // We must explicitly set the background color if we are setting the foreground color, + // since just setting one can look bad on the users console. + switch (logLevel) + { + case LogLevel.Critical: + return new ConsoleColors(ConsoleColor.White, ConsoleColor.Red); + case LogLevel.Error: + return new ConsoleColors(ConsoleColor.Black, ConsoleColor.Red); + case LogLevel.Warning: + return new ConsoleColors(ConsoleColor.Yellow, ConsoleColor.Black); + case LogLevel.Information: + return new ConsoleColors(ConsoleColor.DarkGreen, ConsoleColor.Black); + case LogLevel.Debug: + return new ConsoleColors(ConsoleColor.Gray, ConsoleColor.Black); + case LogLevel.Trace: + return new ConsoleColors(ConsoleColor.Gray, ConsoleColor.Black); + default: + return new ConsoleColors(DefaultConsoleColor, DefaultConsoleColor); + } + } + + private void GetScopeInformation(StringBuilder stringBuilder, ConsoleLoggerOptions options, IExternalScopeProvider scopeProvider) + { + if (options.IncludeScopes && scopeProvider != null) + { + var initialLength = stringBuilder.Length; + + scopeProvider.ForEachScope((scope, state) => + { + var (builder, paddAt) = state; + var padd = paddAt == builder.Length; + if (padd) + { + builder.Append(_messagePadding); + } + builder.Append("=> "); + builder.Append(scope); + builder.Append(" "); + }, (stringBuilder, initialLength)); + + if (stringBuilder.Length > initialLength) + { + // stringBuilder.AppendLine(); + } + } + } + + private readonly struct ConsoleColors + { + public ConsoleColors(ConsoleColor? foreground, ConsoleColor? background) + { + Foreground = foreground; + Background = background; + } + + public ConsoleColor? Foreground { get; } + + public ConsoleColor? Background { get; } + } + } +} diff --git a/src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/DefaultLogFormatter.cs b/src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/DefaultLogFormatter.cs index 69819ee86ebda5..b8526d69ebb8cb 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/DefaultLogFormatter.cs +++ b/src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/DefaultLogFormatter.cs @@ -1,3 +1,7 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + using System; using System.Text; @@ -22,13 +26,13 @@ static DefaultLogFormatter() _newLineWithMessagePadding = Environment.NewLine + _messagePadding; } - public string Name => "Default"; + public DefaultLogFormatter() { } - internal IExternalScopeProvider ScopeProvider { get; set; } + public string Name => "Default"; - internal ConsoleLoggerOptions Options { get; set; } + public DefaultLogFormatterOptions FormatterOptions { get; set; } - public LogMessageEntry Format(LogLevel logLevel, string logName, int eventId, string message, Exception exception) + public LogMessageEntry Format(LogLevel logLevel, string logName, int eventId, string message, Exception exception, ConsoleLoggerOptions options, IExternalScopeProvider scopeProvider) { var logBuilder = _logBuilder; _logBuilder = null; @@ -42,7 +46,7 @@ public LogMessageEntry Format(LogLevel logLevel, string logName, int eventId, st // INFO: ConsoleApp.Program[10] // Request received - var logLevelColors = GetLogLevelConsoleColors(logLevel); + var logLevelColors = GetLogLevelConsoleColors(logLevel, options); var logLevelString = GetLogLevelString(logLevel); // category and event id logBuilder.Append(_loglevelPadding); @@ -52,7 +56,7 @@ public LogMessageEntry Format(LogLevel logLevel, string logName, int eventId, st logBuilder.AppendLine("]"); // scope information - GetScopeInformation(logBuilder); + GetScopeInformation(logBuilder, options, scopeProvider); if (!string.IsNullOrEmpty(message)) { @@ -74,10 +78,10 @@ public LogMessageEntry Format(LogLevel logLevel, string logName, int eventId, st } string timestamp = null; - var timestampFormat = Options.TimestampFormat; + var timestampFormat = options.TimestampFormat; if (timestampFormat != null) { - var dateTime = GetCurrentDateTime(); + var dateTime = GetCurrentDateTime(options); timestamp = dateTime.ToString(timestampFormat); } @@ -96,13 +100,28 @@ public LogMessageEntry Format(LogLevel logLevel, string logName, int eventId, st levelBackground: logLevelColors.Background, levelForeground: logLevelColors.Foreground, messageColor: DefaultConsoleColor, - logAsError: logLevel >= Options.LogToStandardErrorThreshold + logAsError: logLevel >= options.LogToStandardErrorThreshold, + writeCallback : console => + { + if (timestamp != null) + { + console.Write(timestamp, DefaultConsoleColor, DefaultConsoleColor); + } + + if (logLevelString != null) + { + console.Write(logLevelString, logLevelColors.Background, logLevelColors.Foreground); + } + + console.Write(formattedMessage, DefaultConsoleColor, DefaultConsoleColor); + console.Flush(); + } ); } - private DateTime GetCurrentDateTime() + private DateTime GetCurrentDateTime(ConsoleLoggerOptions options) { - return Options.UseUtcTimestamp ? DateTime.UtcNow : DateTime.Now; + return options.UseUtcTimestamp ? DateTime.UtcNow : DateTime.Now; } private static string GetLogLevelString(LogLevel logLevel) @@ -126,9 +145,9 @@ private static string GetLogLevelString(LogLevel logLevel) } } - private ConsoleColors GetLogLevelConsoleColors(LogLevel logLevel) + private ConsoleColors GetLogLevelConsoleColors(LogLevel logLevel, ConsoleLoggerOptions options) { - if (Options.DisableColors) + if (options.DisableColors) { return new ConsoleColors(null, null); } @@ -154,10 +173,9 @@ private ConsoleColors GetLogLevelConsoleColors(LogLevel logLevel) } } - private void GetScopeInformation(StringBuilder stringBuilder) + private void GetScopeInformation(StringBuilder stringBuilder, ConsoleLoggerOptions options, IExternalScopeProvider scopeProvider) { - var scopeProvider = ScopeProvider; - if (Options.IncludeScopes && scopeProvider != null) + if (options.IncludeScopes && scopeProvider != null) { var initialLength = stringBuilder.Length; diff --git a/src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/DefaultLogFormatterOptions.cs b/src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/DefaultLogFormatterOptions.cs index 1fb63f7f0abc39..60699c0e8b2398 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/DefaultLogFormatterOptions.cs +++ b/src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/DefaultLogFormatterOptions.cs @@ -1,3 +1,7 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + using System; using System.Collections.Generic; using System.Text; @@ -6,6 +10,6 @@ namespace Microsoft.Extensions.Logging.Console { public class DefaultLogFormatterOptions { - + public DefaultLogFormatterOptions() { } } } diff --git a/src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/ILogFormatter.cs b/src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/ILogFormatter.cs index 120b8e5ba24e5e..c8cc438c4db1fe 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/ILogFormatter.cs +++ b/src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/ILogFormatter.cs @@ -1,5 +1,6 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. using System; @@ -8,6 +9,6 @@ namespace Microsoft.Extensions.Logging.Console public interface ILogFormatter { string Name { get; } - LogMessageEntry Format(LogLevel logLevel, string logName, int eventId, string message, Exception exception); + LogMessageEntry Format(LogLevel logLevel, string logName, int eventId, string message, Exception exception, ConsoleLoggerOptions options, IExternalScopeProvider scopeProvider); } } diff --git a/src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/JsonLogFormatter.cs b/src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/JsonLogFormatter.cs new file mode 100644 index 00000000000000..8a072974a1baf5 --- /dev/null +++ b/src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/JsonLogFormatter.cs @@ -0,0 +1,405 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using System.Buffers; +using System.Collections.Concurrent; +using System.Collections.Generic; +using System.Diagnostics; +using System.IO; +using System.Linq; +using System.Linq.Expressions; +using System.Reflection; +using System.Text; +using System.Text.Json; +using System.Text.Json.Serialization; +using System.Text.RegularExpressions; +using System.Threading; +using System.Threading.Tasks; +using Microsoft.Extensions.Options; + +namespace Microsoft.Extensions.Logging.Console +{ + internal sealed class PooledByteBufferWriter : IBufferWriter, IDisposable + { + private byte[] _rentedBuffer; + private int _index; + + private const int MinimumBufferSize = 256; + + public PooledByteBufferWriter(int initialCapacity) + { + Debug.Assert(initialCapacity > 0); + + _rentedBuffer = ArrayPool.Shared.Rent(initialCapacity); + _index = 0; + } + + public ReadOnlyMemory WrittenMemory + { + get + { + Debug.Assert(_rentedBuffer != null); + Debug.Assert(_index <= _rentedBuffer.Length); + return _rentedBuffer.AsMemory(0, _index); + } + } + + public int WrittenCount + { + get + { + Debug.Assert(_rentedBuffer != null); + return _index; + } + } + + public int Capacity + { + get + { + Debug.Assert(_rentedBuffer != null); + return _rentedBuffer.Length; + } + } + + public int FreeCapacity + { + get + { + Debug.Assert(_rentedBuffer != null); + return _rentedBuffer.Length - _index; + } + } + + public void Clear() + { + ClearHelper(); + } + + private void ClearHelper() + { + Debug.Assert(_rentedBuffer != null); + Debug.Assert(_index <= _rentedBuffer.Length); + + _rentedBuffer.AsSpan(0, _index).Clear(); + _index = 0; + } + + // Returns the rented buffer back to the pool + public void Dispose() + { + if (_rentedBuffer == null) + { + return; + } + + ClearHelper(); + ArrayPool.Shared.Return(_rentedBuffer); + _rentedBuffer = null!; + } + + public void Advance(int count) + { + Debug.Assert(_rentedBuffer != null); + Debug.Assert(count >= 0); + Debug.Assert(_index <= _rentedBuffer.Length - count); + + _index += count; + } + + public Memory GetMemory(int sizeHint = 0) + { + CheckAndResizeBuffer(sizeHint); + return _rentedBuffer.AsMemory(_index); + } + + public Span GetSpan(int sizeHint = 0) + { + CheckAndResizeBuffer(sizeHint); + return _rentedBuffer.AsSpan(_index); + } + +#if BUILDING_INBOX_LIBRARY + internal ValueTask WriteToStreamAsync(Stream destination, CancellationToken cancellationToken) + { + return destination.WriteAsync(WrittenMemory, cancellationToken); + } +#else + internal Task WriteToStreamAsync(Stream destination, CancellationToken cancellationToken) + { + return destination.WriteAsync(_rentedBuffer, 0, _index, cancellationToken); + } +#endif + + private void CheckAndResizeBuffer(int sizeHint) + { + Debug.Assert(_rentedBuffer != null); + Debug.Assert(sizeHint >= 0); + + if (sizeHint == 0) + { + sizeHint = MinimumBufferSize; + } + + int availableSpace = _rentedBuffer.Length - _index; + + if (sizeHint > availableSpace) + { + int currentLength = _rentedBuffer.Length; + int growBy = Math.Max(sizeHint, currentLength); + + int newSize = currentLength + growBy; + + if ((uint)newSize > int.MaxValue) + { + newSize = currentLength + sizeHint; + if ((uint)newSize > int.MaxValue) + { + throw new OutOfMemoryException("(uint)newSize _BufferMaximumSizeExceeded"); + } + } + + byte[] oldBuffer = _rentedBuffer; + + _rentedBuffer = ArrayPool.Shared.Rent(newSize); + + Debug.Assert(oldBuffer.Length >= _index); + Debug.Assert(_rentedBuffer.Length >= _index); + + Span previousBuffer = oldBuffer.AsSpan(0, _index); + previousBuffer.CopyTo(_rentedBuffer); + previousBuffer.Clear(); + ArrayPool.Shared.Return(oldBuffer); + } + + Debug.Assert(_rentedBuffer.Length - _index > 0); + Debug.Assert(_rentedBuffer.Length - _index >= sizeHint); + } + } + + public class JsonConsoleLogFormatter : ILogFormatter, IDisposable + { + private readonly IOptionsMonitor _options; + private IDisposable _optionsReloadToken; + + private static readonly string _loglevelPadding = ": "; + private static readonly string _messagePadding; + private static readonly string _newLineWithMessagePadding; + + [ThreadStatic] + private static StringBuilder _logBuilder; + [ThreadStatic] + private static IDictionary _xBuilder; + + static JsonConsoleLogFormatter() + { + var logLevelString = GetLogLevelString(LogLevel.Information); + _messagePadding = new string(' ', logLevelString.Length + _loglevelPadding.Length); + _newLineWithMessagePadding = Environment.NewLine + _messagePadding; + } + + public JsonLogFormatterOptions FormatterOptions { get; set; } + + public JsonConsoleLogFormatter(IOptionsMonitor options) + { + _options = options; + ReloadLoggerOptions(options.CurrentValue); + _optionsReloadToken = _options.OnChange(ReloadLoggerOptions); + } + + private void ReloadLoggerOptions(JsonLogFormatterOptions options) + { + FormatterOptions = options; + } + + public string Name => "Json"; + + internal IDictionary Scope { get; } = new Dictionary(StringComparer.Ordinal); + + /// + public void Dispose() + { + _optionsReloadToken?.Dispose(); + } + + public LogMessageEntry Format(LogLevel logLevel, string logName, int eventId, string message, Exception exception, ConsoleLoggerOptions options, IExternalScopeProvider scopeProvider) + { + var logBuilder = _logBuilder; + var xBuilder = _xBuilder; + _logBuilder = null; + _xBuilder = null; + + if (logBuilder == null) + { + logBuilder = new StringBuilder(); + xBuilder = new Dictionary(); + } + + // Example: + // INFO: ConsoleApp.Program[10] + // Request received + + var logLevelString = GetLogLevelString(logLevel); + + if (!string.IsNullOrEmpty(message)) + { + const int DefaultBufferSize = 16384; + + using (var output = new PooledByteBufferWriter(DefaultBufferSize)) + { + using (var writer = new Utf8JsonWriter(output, options.JsonWriterOptions)) + { + writer.WriteStartObject(); + // TimeStamp + writer.WriteNumber("EventId", eventId); + writer.WriteString("LogLevel", logLevelString); + writer.WriteString("Category", logName); + writer.WriteString("Message", message); + + GetScopeInformation(writer, options, scopeProvider); + + writer.WriteEndObject(); + } + logBuilder.AppendLine(Encoding.UTF8.GetString(output.WrittenMemory.Span)); + } + } + + // Example: + // System.InvalidOperationException + // at Namespace.Class.Function() in File:line X + if (exception != null) + { + // exception message + // logBuilder.AppendLine(exception.ToString()); + const int DefaultBufferSize = 16384; + + using (var output = new PooledByteBufferWriter(DefaultBufferSize)) + { + using (var writer = new Utf8JsonWriter(output, FormatterOptions.JsonWriterOptions)) + { + writer.WriteStartObject(); + writer.WriteString("Message", exception.Message.ToString()); + writer.WriteString("Type", exception.GetType().ToString()); + writer.WriteStartArray("StackTrace"); + foreach (var xx in exception?.StackTrace?.Split(Environment.NewLine)) + { + JsonSerializer.Serialize(writer, xx); + } + writer.WriteEndArray(); + writer.WriteNumber("HResult", exception.HResult); + writer.WriteEndObject(); + } + + logBuilder.AppendLine(Encoding.UTF8.GetString(output.WrittenMemory.Span)); + } + } + + string timestamp = null; + var timestampFormat = options.TimestampFormat; + if (timestampFormat != null) + { + var dateTime = GetCurrentDateTime(options); + timestamp = dateTime.ToString(timestampFormat); + } + + var formattedMessage = logBuilder.ToString(); + logBuilder.Clear(); + if (logBuilder.Capacity > 1024) + { + logBuilder.Capacity = 1024; + } + _logBuilder = logBuilder; + _xBuilder = xBuilder; + + return new LogMessageEntry( + message: formattedMessage, + timeStamp: timestamp, + levelString: string.Empty, + levelBackground: null, + levelForeground: null, + messageColor: null, + logAsError: logLevel >= options.LogToStandardErrorThreshold, + writeCallback : console => + { + if (timestamp != null) + { + console.Write(timestamp, null, null); + } + + console.Write(formattedMessage, null, null); + console.Flush(); + } + ); + } + + private DateTime GetCurrentDateTime(ConsoleLoggerOptions options) + { + return options.UseUtcTimestamp ? DateTime.UtcNow : DateTime.Now; + } + + private static string GetLogLevelString(LogLevel logLevel) + { + switch (logLevel) + { + case LogLevel.Trace: + return "json_trce"; + case LogLevel.Debug: + return "json_dbug"; + case LogLevel.Information: + return "json_info"; + case LogLevel.Warning: + return "json_warn"; + case LogLevel.Error: + return "json_fail"; + case LogLevel.Critical: + return "json_crit"; + default: + throw new ArgumentOutOfRangeException(nameof(logLevel)); + } + } + + private void GetScopeInformation(Utf8JsonWriter writer, ConsoleLoggerOptions options, IExternalScopeProvider scopeProvider) + { + try + { + if (options.IncludeScopes && scopeProvider != null) + { + writer.WriteStartArray("Scopes"); + scopeProvider.ForEachScope((scope, state) => + { + if (scope is IReadOnlyList>)// kvps) + { + //foreach (var kvp in kvps) + //{ + // //state.WritePropertyName(kvp.Key); + // JsonSerializer.Serialize(kvp.Value); + //} + //state is the writer + JsonSerializer.Serialize(state, scope); + } + }, (writer)); + writer.WriteEndArray(); + } + } + catch (Exception ex) + { + System.Console.WriteLine("Something went wrong" + ex.Message); + } + } + + private readonly struct ConsoleColors + { + public ConsoleColors(ConsoleColor? foreground, ConsoleColor? background) + { + Foreground = foreground; + Background = background; + } + + public ConsoleColor? Foreground { get; } + + public ConsoleColor? Background { get; } + } + } +} diff --git a/src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/JsonLogFormatterOptions.cs b/src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/JsonLogFormatterOptions.cs new file mode 100644 index 00000000000000..d1845d9e0ca747 --- /dev/null +++ b/src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/JsonLogFormatterOptions.cs @@ -0,0 +1,17 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using System.Text; +using System.Text.Json; + +namespace Microsoft.Extensions.Logging.Console +{ + public class JsonLogFormatterOptions + { + public JsonLogFormatterOptions() { } + public JsonWriterOptions JsonWriterOptions { get; set; } + // or public JsonSerializerOptions JsonSerializerOptions { get; set; } + } +} diff --git a/src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/SystemdLogFormatter.cs b/src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/SystemdLogFormatter.cs index 4d63e1a10d846c..10e690e89e0a4a 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/SystemdLogFormatter.cs +++ b/src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/SystemdLogFormatter.cs @@ -1,10 +1,18 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + using System; using System.Text; +using Microsoft.Extensions.Options; namespace Microsoft.Extensions.Logging.Console { public class SystemdLogFormatter : ILogFormatter { + private readonly IOptionsMonitor _options; + private IDisposable _optionsReloadToken; + private static readonly string _loglevelPadding = ": "; private static readonly string _messagePadding; @@ -17,13 +25,23 @@ static SystemdLogFormatter() _messagePadding = new string(' ', logLevelString.Length + _loglevelPadding.Length); } - public string Name => "Systemd"; + public SystemdLogFormatter(IOptionsMonitor options) + { + _options = options; + ReloadLoggerOptions(options.CurrentValue); + _optionsReloadToken = _options.OnChange(ReloadLoggerOptions); + } - internal IExternalScopeProvider ScopeProvider { get; set; } + private void ReloadLoggerOptions(SystemdLogFormatterOptions options) + { + FormatterOptions = options; + } - internal ConsoleLoggerOptions Options { get; set; } + public string Name => "Systemd"; - public LogMessageEntry Format(LogLevel logLevel, string logName, int eventId, string message, Exception exception) + public SystemdLogFormatterOptions FormatterOptions { get; set; } + + public LogMessageEntry Format(LogLevel logLevel, string logName, int eventId, string message, Exception exception, ConsoleLoggerOptions options, IExternalScopeProvider scopeProvider) { var logBuilder = _logBuilder; _logBuilder = null; @@ -44,10 +62,10 @@ public LogMessageEntry Format(LogLevel logLevel, string logName, int eventId, st logBuilder.Append(logLevelString); // timestamp - var timestampFormat = Options.TimestampFormat; + var timestampFormat = options.TimestampFormat; if (timestampFormat != null) { - var dateTime = GetCurrentDateTime(); + var dateTime = GetCurrentDateTime(options); logBuilder.Append(dateTime.ToString(timestampFormat)); } @@ -58,7 +76,7 @@ public LogMessageEntry Format(LogLevel logLevel, string logName, int eventId, st logBuilder.Append("]"); // scope information - GetScopeInformation(logBuilder); + GetScopeInformation(logBuilder, options, scopeProvider); // message if (!string.IsNullOrEmpty(message)) @@ -90,7 +108,12 @@ public LogMessageEntry Format(LogLevel logLevel, string logName, int eventId, st return new LogMessageEntry( message: formattedMessage, - logAsError: logLevel >= Options.LogToStandardErrorThreshold + logAsError: logLevel >= options.LogToStandardErrorThreshold, + writeCallback : console => + { + console.Write(formattedMessage, null, null); + console.Flush(); + } ); static void AppendAndReplaceNewLine(StringBuilder sb, string message) @@ -101,9 +124,9 @@ static void AppendAndReplaceNewLine(StringBuilder sb, string message) } } - private DateTime GetCurrentDateTime() + private DateTime GetCurrentDateTime(ConsoleLoggerOptions options) { - return Options.UseUtcTimestamp ? DateTime.UtcNow : DateTime.Now; + return options.UseUtcTimestamp ? DateTime.UtcNow : DateTime.Now; } private static string GetSyslogSeverityString(LogLevel logLevel) @@ -127,10 +150,9 @@ private static string GetSyslogSeverityString(LogLevel logLevel) } } - private void GetScopeInformation(StringBuilder stringBuilder) + private void GetScopeInformation(StringBuilder stringBuilder, ConsoleLoggerOptions options, IExternalScopeProvider scopeProvider) { - var scopeProvider = ScopeProvider; - if (Options.IncludeScopes && scopeProvider != null) + if (options.IncludeScopes && scopeProvider != null) { var initialLength = stringBuilder.Length; diff --git a/src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/SystemdLogFormatterOptions.cs b/src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/SystemdLogFormatterOptions.cs index 7bf9a1edc15731..89b282a627f8f6 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/SystemdLogFormatterOptions.cs +++ b/src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/SystemdLogFormatterOptions.cs @@ -1,3 +1,7 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + using System; using System.Text; @@ -5,5 +9,6 @@ namespace Microsoft.Extensions.Logging.Console { public class SystemdLogFormatterOptions { + public SystemdLogFormatterOptions() { } } } diff --git a/src/libraries/Microsoft.Extensions.Logging.Console/src/IConsole.cs b/src/libraries/Microsoft.Extensions.Logging.Console/src/IConsole.cs index a9975b0105b17f..88500ecf16f374 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Console/src/IConsole.cs +++ b/src/libraries/Microsoft.Extensions.Logging.Console/src/IConsole.cs @@ -6,7 +6,7 @@ namespace Microsoft.Extensions.Logging.Console { - internal interface IConsole + public interface IConsole { void Write(string message, ConsoleColor? background, ConsoleColor? foreground); void WriteLine(string message, ConsoleColor? background, ConsoleColor? foreground); diff --git a/src/libraries/Microsoft.Extensions.Logging.Console/src/LogMessageEntry.cs b/src/libraries/Microsoft.Extensions.Logging.Console/src/LogMessageEntry.cs index 1ff205a686c118..ad57f9480e8866 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Console/src/LogMessageEntry.cs +++ b/src/libraries/Microsoft.Extensions.Logging.Console/src/LogMessageEntry.cs @@ -8,7 +8,7 @@ namespace Microsoft.Extensions.Logging.Console { public readonly struct LogMessageEntry { - public LogMessageEntry(string message, string timeStamp = null, string levelString = null, ConsoleColor? levelBackground = null, ConsoleColor? levelForeground = null, ConsoleColor? messageColor = null, bool logAsError = false) + public LogMessageEntry(string message, string timeStamp = null, string levelString = null, ConsoleColor? levelBackground = null, ConsoleColor? levelForeground = null, ConsoleColor? messageColor = null, bool logAsError = false, Action writeCallback = null) { TimeStamp = timeStamp; LevelString = levelString; @@ -17,6 +17,7 @@ public LogMessageEntry(string message, string timeStamp = null, string levelStri MessageColor = messageColor; Message = message; LogAsError = logAsError; + WriteCallback = writeCallback; } public readonly string TimeStamp; @@ -26,5 +27,6 @@ public LogMessageEntry(string message, string timeStamp = null, string levelStri public readonly ConsoleColor? MessageColor; public readonly string Message; public readonly bool LogAsError; + public readonly Action WriteCallback; } } diff --git a/src/libraries/Microsoft.Extensions.Logging.Console/src/Microsoft.Extensions.Logging.Console.csproj b/src/libraries/Microsoft.Extensions.Logging.Console/src/Microsoft.Extensions.Logging.Console.csproj index 9e75fa86106f55..d235bf2d2f1fe5 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Console/src/Microsoft.Extensions.Logging.Console.csproj +++ b/src/libraries/Microsoft.Extensions.Logging.Console/src/Microsoft.Extensions.Logging.Console.csproj @@ -24,7 +24,10 @@ + + + From 7c40da6a18e58e7d77716776f9048fb368601acf Mon Sep 17 00:00:00 2001 From: Maryam Ariyan Date: Thu, 14 May 2020 15:33:06 -0700 Subject: [PATCH 02/15] Apply review feedback - *FormatterOptions - add AddFormatter helper TODO: - WriteCallback on LogMessageEntry - Update tests --- .../Microsoft.Extensions.Logging.Console.cs | 49 ++- .../src/ConsoleLogger.cs | 4 +- .../src/ConsoleLoggerFactoryExtensions.cs | 58 ++- .../src/ConsoleLoggerOptions.cs | 27 -- .../src/ConsoleLoggerProvider.cs | 2 - .../src/Formatter/CompactLogFormatter.cs | 47 ++- .../Formatter/CompactLogFormatterOptions.cs | 40 ++ .../src/Formatter/DefaultLogFormatter.cs | 45 ++- .../Formatter/DefaultLogFormatterOptions.cs | 25 ++ .../src/Formatter/ILogFormatter.cs | 2 +- .../src/Formatter/JsonLogFormatter.cs | 371 ++++-------------- .../src/Formatter/JsonLogFormatterOptions.cs | 27 +- .../src/Formatter/SystemdLogFormatter.cs | 30 +- .../Formatter/SystemdLogFormatterOptions.cs | 25 ++ ...icrosoft.Extensions.Logging.Console.csproj | 5 + 15 files changed, 370 insertions(+), 387 deletions(-) create mode 100644 src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/CompactLogFormatterOptions.cs diff --git a/src/libraries/Microsoft.Extensions.Logging.Console/ref/Microsoft.Extensions.Logging.Console.cs b/src/libraries/Microsoft.Extensions.Logging.Console/ref/Microsoft.Extensions.Logging.Console.cs index 78c244d5692399..1f5ad8949dabfd 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Console/ref/Microsoft.Extensions.Logging.Console.cs +++ b/src/libraries/Microsoft.Extensions.Logging.Console/ref/Microsoft.Extensions.Logging.Console.cs @@ -11,10 +11,21 @@ public static partial class ConsoleLoggerExtensions { public static Microsoft.Extensions.Logging.ILoggingBuilder AddConsole(this Microsoft.Extensions.Logging.ILoggingBuilder builder) { throw null; } public static Microsoft.Extensions.Logging.ILoggingBuilder AddConsole(this Microsoft.Extensions.Logging.ILoggingBuilder builder, System.Action configure) { throw null; } + public static Microsoft.Extensions.Logging.ILoggingBuilder AddLogFormatter(this Microsoft.Extensions.Logging.ILoggingBuilder builder) where TFormatter : class, Microsoft.Extensions.Logging.Console.ILogFormatter where TOptions : class { throw null; } + public static Microsoft.Extensions.Logging.ILoggingBuilder AddLogFormatter(this Microsoft.Extensions.Logging.ILoggingBuilder builder, System.Action configure) where TFormatter : class, Microsoft.Extensions.Logging.Console.ILogFormatter where TOptions : class { throw null; } } } namespace Microsoft.Extensions.Logging.Console { + public partial class CompactLogFormatterOptions + { + public CompactLogFormatterOptions() { } + public bool DisableColors { get { throw null; } set { } } + public bool IncludeScopes { get { throw null; } set { } } + public Microsoft.Extensions.Logging.LogLevel LogToStandardErrorThreshold { get { throw null; } set { } } + public string TimestampFormat { get { throw null; } set { } } + public bool UseUtcTimestamp { get { throw null; } set { } } + } public enum ConsoleLoggerFormat { Default = 0, @@ -23,14 +34,8 @@ public enum ConsoleLoggerFormat public partial class ConsoleLoggerOptions { public ConsoleLoggerOptions() { } - public bool DisableColors { get { throw null; } set { } } public Microsoft.Extensions.Logging.Console.ConsoleLoggerFormat Format { get { throw null; } set { } } public string Formatter { get { throw null; } set { } } - public bool IncludeScopes { get { throw null; } set { } } - public System.Text.Json.JsonWriterOptions JsonWriterOptions { get { throw null; } set { } } - public Microsoft.Extensions.Logging.LogLevel LogToStandardErrorThreshold { get { throw null; } set { } } - public string TimestampFormat { get { throw null; } set { } } - public bool UseUtcTimestamp { get { throw null; } set { } } } [Microsoft.Extensions.Logging.ProviderAliasAttribute("Console")] public partial class ConsoleLoggerProvider : Microsoft.Extensions.Logging.ILoggerProvider, Microsoft.Extensions.Logging.ISupportExternalScope, System.IDisposable @@ -40,16 +45,22 @@ public ConsoleLoggerProvider(Microsoft.Extensions.Options.IOptionsMonitor options) { } public Microsoft.Extensions.Logging.Console.DefaultLogFormatterOptions FormatterOptions { get { throw null; } set { } } public string Name { get { throw null; } } - public Microsoft.Extensions.Logging.Console.LogMessageEntry Format(Microsoft.Extensions.Logging.LogLevel logLevel, string logName, int eventId, string message, System.Exception exception, Microsoft.Extensions.Logging.Console.ConsoleLoggerOptions options, Microsoft.Extensions.Logging.IExternalScopeProvider scopeProvider) { throw null; } + public void Dispose() { } + public Microsoft.Extensions.Logging.Console.LogMessageEntry Format(Microsoft.Extensions.Logging.LogLevel logLevel, string logName, int eventId, string message, System.Exception exception, Microsoft.Extensions.Logging.IExternalScopeProvider scopeProvider) { throw null; } } public partial class DefaultLogFormatterOptions { public DefaultLogFormatterOptions() { } + public bool DisableColors { get { throw null; } set { } } + public bool IncludeScopes { get { throw null; } set { } } + public Microsoft.Extensions.Logging.LogLevel LogToStandardErrorThreshold { get { throw null; } set { } } + public string TimestampFormat { get { throw null; } set { } } + public bool UseUtcTimestamp { get { throw null; } set { } } } public partial interface IConsole { @@ -60,7 +71,7 @@ public partial interface IConsole public partial interface ILogFormatter { string Name { get; } - Microsoft.Extensions.Logging.Console.LogMessageEntry Format(Microsoft.Extensions.Logging.LogLevel logLevel, string logName, int eventId, string message, System.Exception exception, Microsoft.Extensions.Logging.Console.ConsoleLoggerOptions options, Microsoft.Extensions.Logging.IExternalScopeProvider scopeProvider); + Microsoft.Extensions.Logging.Console.LogMessageEntry Format(Microsoft.Extensions.Logging.LogLevel logLevel, string logName, int eventId, string message, System.Exception exception, Microsoft.Extensions.Logging.IExternalScopeProvider scopeProvider); } public partial class JsonConsoleLogFormatter : Microsoft.Extensions.Logging.Console.ILogFormatter, System.IDisposable { @@ -68,12 +79,18 @@ public JsonConsoleLogFormatter(Microsoft.Extensions.Options.IOptionsMonitor WriteCallback; public LogMessageEntry(string message, string timeStamp = null, string levelString = null, System.ConsoleColor? levelBackground = default(System.ConsoleColor?), System.ConsoleColor? levelForeground = default(System.ConsoleColor?), System.ConsoleColor? messageColor = default(System.ConsoleColor?), bool logAsError = false, System.Action writeCallback = null) { throw null; } } - public partial class SystemdLogFormatter : Microsoft.Extensions.Logging.Console.ILogFormatter + public partial class SystemdLogFormatter : Microsoft.Extensions.Logging.Console.ILogFormatter, System.IDisposable { public SystemdLogFormatter(Microsoft.Extensions.Options.IOptionsMonitor options) { } public Microsoft.Extensions.Logging.Console.SystemdLogFormatterOptions FormatterOptions { get { throw null; } set { } } public string Name { get { throw null; } } - public Microsoft.Extensions.Logging.Console.LogMessageEntry Format(Microsoft.Extensions.Logging.LogLevel logLevel, string logName, int eventId, string message, System.Exception exception, Microsoft.Extensions.Logging.Console.ConsoleLoggerOptions options, Microsoft.Extensions.Logging.IExternalScopeProvider scopeProvider) { throw null; } + public void Dispose() { } + public Microsoft.Extensions.Logging.Console.LogMessageEntry Format(Microsoft.Extensions.Logging.LogLevel logLevel, string logName, int eventId, string message, System.Exception exception, Microsoft.Extensions.Logging.IExternalScopeProvider scopeProvider) { throw null; } } public partial class SystemdLogFormatterOptions { public SystemdLogFormatterOptions() { } + public bool DisableColors { get { throw null; } set { } } + public bool IncludeScopes { get { throw null; } set { } } + public Microsoft.Extensions.Logging.LogLevel LogToStandardErrorThreshold { get { throw null; } set { } } + public string TimestampFormat { get { throw null; } set { } } + public bool UseUtcTimestamp { get { throw null; } set { } } } } diff --git a/src/libraries/Microsoft.Extensions.Logging.Console/src/ConsoleLogger.cs b/src/libraries/Microsoft.Extensions.Logging.Console/src/ConsoleLogger.cs index 65f6e63d6326b1..20bce6bbfad83e 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Console/src/ConsoleLogger.cs +++ b/src/libraries/Microsoft.Extensions.Logging.Console/src/ConsoleLogger.cs @@ -31,8 +31,6 @@ internal ConsoleLogger(string name, ConsoleLoggerProcessor loggerProcessor) internal IExternalScopeProvider ScopeProvider { get; set; } - internal ConsoleLoggerOptions Options { get; set; } - internal ILogFormatter Formatter { get; set; } public void Log(LogLevel logLevel, EventId eventId, TState state, Exception exception, Func formatter) @@ -57,7 +55,7 @@ public void Log(LogLevel logLevel, EventId eventId, TState state, Except public virtual void WriteMessage(LogLevel logLevel, string logName, int eventId, string message, Exception exception) { - var entry = Formatter.Format(logLevel, logName, eventId, message, exception, Options, ScopeProvider); + var entry = Formatter.Format(logLevel, logName, eventId, message, exception, ScopeProvider); _queueProcessor.EnqueueMessage(entry); } diff --git a/src/libraries/Microsoft.Extensions.Logging.Console/src/ConsoleLoggerFactoryExtensions.cs b/src/libraries/Microsoft.Extensions.Logging.Console/src/ConsoleLoggerFactoryExtensions.cs index 75441fa6fa97c3..22c92ec3308dc6 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Console/src/ConsoleLoggerFactoryExtensions.cs +++ b/src/libraries/Microsoft.Extensions.Logging.Console/src/ConsoleLoggerFactoryExtensions.cs @@ -8,6 +8,7 @@ using Microsoft.Extensions.Logging.Abstractions; using Microsoft.Extensions.Logging.Configuration; using Microsoft.Extensions.Logging.Console; +using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Options; using System.Collections.Generic; using System.Collections.Concurrent; @@ -28,14 +29,10 @@ public static ILoggingBuilder AddConsole(this ILoggingBuilder builder) { builder.AddConfiguration(); - builder.Services.TryAddEnumerable(ServiceDescriptor.Singleton()); - LoggerProviderOptions.RegisterProviderOptions(builder.Services); - - builder.Services.TryAddEnumerable(ServiceDescriptor.Singleton()); - LoggerProviderOptions.RegisterProviderOptions(builder.Services); - - builder.Services.TryAddEnumerable(ServiceDescriptor.Singleton()); - LoggerProviderOptions.RegisterProviderOptions(builder.Services); + builder.AddLogFormatter(); + builder.AddLogFormatter(); + builder.AddLogFormatter(); + builder.AddLogFormatter(); builder.Services.TryAddEnumerable(ServiceDescriptor.Singleton()); LoggerProviderOptions.RegisterProviderOptions(builder.Services); @@ -60,5 +57,50 @@ public static ILoggingBuilder AddConsole(this ILoggingBuilder builder, Action(this ILoggingBuilder builder) + where TOptions : class + where TFormatter : class, ILogFormatter + { + builder.AddConfiguration(); + + builder.Services.TryAddEnumerable(ServiceDescriptor.Singleton()); + builder.Services.AddSingleton, LogFormatterOptionsSetup>(); + builder.Services.AddSingleton, LoggerProviderOptionsChangeTokenSource>(); + + var configuration = new ConfigurationBuilder() + .AddJsonFile("appsettings.json", optional: false, reloadOnChange: true) + .Build(); + builder.Services.AddOptions().Bind(configuration.GetSection("Logging:Console:FormatterOptions")); + builder.Services.Configure(configuration.GetSection("Logging:Console:FormatterOptions")); + + return builder; + } + + public static ILoggingBuilder AddLogFormatter(this ILoggingBuilder builder, Action configure) + where TOptions : class + where TFormatter : class, ILogFormatter + { + if (configure == null) + { + throw new ArgumentNullException(nameof(configure)); + } + + builder.AddLogFormatter(); + + builder.Services.Configure(configure); + + return builder; + } + } + + internal class LogFormatterOptionsSetup : ConfigureFromConfigurationOptions + where TOptions : class + where TFormatter : class, ILogFormatter + { + public LogFormatterOptionsSetup(ILoggerProviderConfiguration providerConfiguration) + : base(providerConfiguration.Configuration) + { + } } } diff --git a/src/libraries/Microsoft.Extensions.Logging.Console/src/ConsoleLoggerOptions.cs b/src/libraries/Microsoft.Extensions.Logging.Console/src/ConsoleLoggerOptions.cs index 194bd554d08c45..f15a27fed40b04 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Console/src/ConsoleLoggerOptions.cs +++ b/src/libraries/Microsoft.Extensions.Logging.Console/src/ConsoleLoggerOptions.cs @@ -12,16 +12,6 @@ namespace Microsoft.Extensions.Logging.Console /// public class ConsoleLoggerOptions { - /// - /// Includes scopes when . - /// - public bool IncludeScopes { get; set; } - - /// - /// Disables colors when . - /// - public bool DisableColors { get; set; } - /// /// Gets or sets log message format. Defaults to . /// @@ -53,22 +43,5 @@ public ConsoleLoggerFormat Format /// /// public string Formatter { get; set; } - - /// - /// Gets or sets value indicating the minimum level of messaged that would get written to Console.Error. - /// - public LogLevel LogToStandardErrorThreshold { get; set; } = LogLevel.None; - - /// - /// Gets or sets format string used to format timestamp in logging messages. Defaults to null. - /// - public string TimestampFormat { get; set; } - - /// - /// Gets or sets indication whether or not UTC timezone should be used to for timestamps in logging messages. Defaults to false. - /// - public bool UseUtcTimestamp { get; set; } - - public JsonWriterOptions JsonWriterOptions { get; set; } } } diff --git a/src/libraries/Microsoft.Extensions.Logging.Console/src/ConsoleLoggerProvider.cs b/src/libraries/Microsoft.Extensions.Logging.Console/src/ConsoleLoggerProvider.cs index ba495275139625..65ce2d92f895f6 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Console/src/ConsoleLoggerProvider.cs +++ b/src/libraries/Microsoft.Extensions.Logging.Console/src/ConsoleLoggerProvider.cs @@ -64,7 +64,6 @@ private void ReloadLoggerOptions(ConsoleLoggerOptions options) foreach (var logger in _loggers) { - logger.Value.Options = options; logger.Value.Formatter = logFormatter; } } @@ -81,7 +80,6 @@ public ILogger CreateLogger(string name) return _loggers.GetOrAdd(name, loggerName => new ConsoleLogger(name, _messageQueue) { - Options = _options.CurrentValue, ScopeProvider = _scopeProvider, Formatter = logFormatter }); diff --git a/src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/CompactLogFormatter.cs b/src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/CompactLogFormatter.cs index ff9ec830349177..11f2b21db4254b 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/CompactLogFormatter.cs +++ b/src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/CompactLogFormatter.cs @@ -4,11 +4,13 @@ using System; using System.Text; +using Microsoft.Extensions.Options; namespace Microsoft.Extensions.Logging.Console { - internal class CompactLogFormatter : ILogFormatter + internal class CompactLogFormatter : ILogFormatter, IDisposable { + private IDisposable _optionsReloadToken; private static readonly string _loglevelPadding = ": "; private static readonly string _messagePadding; private static readonly string _newLineWithMessagePadding; @@ -26,11 +28,28 @@ static CompactLogFormatter() _newLineWithMessagePadding = Environment.NewLine + _messagePadding; } - public CompactLogFormatter() { } + public CompactLogFormatter(IOptionsMonitor options) + { + FormatterOptions = options.CurrentValue; + ReloadLoggerOptions(options.CurrentValue); + _optionsReloadToken = options.OnChange(ReloadLoggerOptions); + } + + private void ReloadLoggerOptions(CompactLogFormatterOptions options) + { + FormatterOptions = options; + } + + public void Dispose() + { + _optionsReloadToken?.Dispose(); + } + + public CompactLogFormatterOptions FormatterOptions { get; set; } public string Name => "Compact"; - public LogMessageEntry Format(LogLevel logLevel, string logName, int eventId, string message, Exception exception, ConsoleLoggerOptions options, IExternalScopeProvider scopeProvider) + public LogMessageEntry Format(LogLevel logLevel, string logName, int eventId, string message, Exception exception, IExternalScopeProvider scopeProvider) { // todo fix later: var logBuilder = _logBuilder; @@ -45,7 +64,7 @@ public LogMessageEntry Format(LogLevel logLevel, string logName, int eventId, st // INFO: ConsoleApp.Program[10] // Request received - var logLevelColors = GetLogLevelConsoleColors(logLevel, options); + var logLevelColors = GetLogLevelConsoleColors(logLevel); var logLevelString = GetLogLevelString(logLevel); // category and event id logBuilder.Append(_loglevelPadding); @@ -56,7 +75,7 @@ public LogMessageEntry Format(LogLevel logLevel, string logName, int eventId, st // logBuilder.AppendLine("]"); // scope information - GetScopeInformation(logBuilder, options, scopeProvider); + GetScopeInformation(logBuilder, scopeProvider); if (!string.IsNullOrEmpty(message)) { @@ -78,10 +97,10 @@ public LogMessageEntry Format(LogLevel logLevel, string logName, int eventId, st } string timestamp = null; - var timestampFormat = options.TimestampFormat; + var timestampFormat = FormatterOptions.TimestampFormat; if (timestampFormat != null) { - var dateTime = GetCurrentDateTime(options); + var dateTime = GetCurrentDateTime(); timestamp = dateTime.ToString(timestampFormat); } @@ -100,7 +119,7 @@ public LogMessageEntry Format(LogLevel logLevel, string logName, int eventId, st levelBackground: logLevelColors.Background, levelForeground: logLevelColors.Foreground, messageColor: DefaultConsoleColor, - logAsError: logLevel >= options.LogToStandardErrorThreshold, + logAsError: logLevel >= FormatterOptions.LogToStandardErrorThreshold, writeCallback : console => { if (timestamp != null) @@ -119,9 +138,9 @@ public LogMessageEntry Format(LogLevel logLevel, string logName, int eventId, st ); } - private DateTime GetCurrentDateTime(ConsoleLoggerOptions options) + private DateTime GetCurrentDateTime() { - return options.UseUtcTimestamp ? DateTime.UtcNow : DateTime.Now; + return FormatterOptions.UseUtcTimestamp ? DateTime.UtcNow : DateTime.Now; } private static string GetLogLevelString(LogLevel logLevel) @@ -145,9 +164,9 @@ private static string GetLogLevelString(LogLevel logLevel) } } - private ConsoleColors GetLogLevelConsoleColors(LogLevel logLevel, ConsoleLoggerOptions options) + private ConsoleColors GetLogLevelConsoleColors(LogLevel logLevel) { - if (options.DisableColors) + if (FormatterOptions.DisableColors) { return new ConsoleColors(null, null); } @@ -173,9 +192,9 @@ private ConsoleColors GetLogLevelConsoleColors(LogLevel logLevel, ConsoleLoggerO } } - private void GetScopeInformation(StringBuilder stringBuilder, ConsoleLoggerOptions options, IExternalScopeProvider scopeProvider) + private void GetScopeInformation(StringBuilder stringBuilder, IExternalScopeProvider scopeProvider) { - if (options.IncludeScopes && scopeProvider != null) + if (FormatterOptions.IncludeScopes && scopeProvider != null) { var initialLength = stringBuilder.Length; diff --git a/src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/CompactLogFormatterOptions.cs b/src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/CompactLogFormatterOptions.cs new file mode 100644 index 00000000000000..aee8d125e7b739 --- /dev/null +++ b/src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/CompactLogFormatterOptions.cs @@ -0,0 +1,40 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using System.Collections.Generic; +using System.Text; + +namespace Microsoft.Extensions.Logging.Console +{ + public class CompactLogFormatterOptions + { + public CompactLogFormatterOptions() { } + + /// + /// Includes scopes when . + /// + public bool IncludeScopes { get; set; } + + /// + /// Disables colors when . + /// + public bool DisableColors { get; set; } + + /// + /// Gets or sets value indicating the minimum level of messaged that would get written to Console.Error. + /// + public LogLevel LogToStandardErrorThreshold { get; set; } = LogLevel.None; + + /// + /// Gets or sets format string used to format timestamp in logging messages. Defaults to null. + /// + public string TimestampFormat { get; set; } + + /// + /// Gets or sets indication whether or not UTC timezone should be used to for timestamps in logging messages. Defaults to false. + /// + public bool UseUtcTimestamp { get; set; } + } +} diff --git a/src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/DefaultLogFormatter.cs b/src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/DefaultLogFormatter.cs index b8526d69ebb8cb..9805c26227b630 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/DefaultLogFormatter.cs +++ b/src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/DefaultLogFormatter.cs @@ -4,14 +4,16 @@ using System; using System.Text; +using Microsoft.Extensions.Options; namespace Microsoft.Extensions.Logging.Console { - public class DefaultLogFormatter : ILogFormatter + public class DefaultLogFormatter : ILogFormatter, IDisposable { private static readonly string _loglevelPadding = ": "; private static readonly string _messagePadding; private static readonly string _newLineWithMessagePadding; + private IDisposable _optionsReloadToken; // ConsoleColor does not have a value to specify the 'Default' color private readonly ConsoleColor? DefaultConsoleColor = null; @@ -26,13 +28,28 @@ static DefaultLogFormatter() _newLineWithMessagePadding = Environment.NewLine + _messagePadding; } - public DefaultLogFormatter() { } + public DefaultLogFormatter(IOptionsMonitor options) + { + FormatterOptions = options.CurrentValue; + ReloadLoggerOptions(options.CurrentValue); + _optionsReloadToken = options.OnChange(ReloadLoggerOptions); + } + + private void ReloadLoggerOptions(DefaultLogFormatterOptions options) + { + FormatterOptions = options; + } + + public void Dispose() + { + _optionsReloadToken?.Dispose(); + } public string Name => "Default"; public DefaultLogFormatterOptions FormatterOptions { get; set; } - public LogMessageEntry Format(LogLevel logLevel, string logName, int eventId, string message, Exception exception, ConsoleLoggerOptions options, IExternalScopeProvider scopeProvider) + public LogMessageEntry Format(LogLevel logLevel, string logName, int eventId, string message, Exception exception, IExternalScopeProvider scopeProvider) { var logBuilder = _logBuilder; _logBuilder = null; @@ -46,7 +63,7 @@ public LogMessageEntry Format(LogLevel logLevel, string logName, int eventId, st // INFO: ConsoleApp.Program[10] // Request received - var logLevelColors = GetLogLevelConsoleColors(logLevel, options); + var logLevelColors = GetLogLevelConsoleColors(logLevel); var logLevelString = GetLogLevelString(logLevel); // category and event id logBuilder.Append(_loglevelPadding); @@ -56,7 +73,7 @@ public LogMessageEntry Format(LogLevel logLevel, string logName, int eventId, st logBuilder.AppendLine("]"); // scope information - GetScopeInformation(logBuilder, options, scopeProvider); + GetScopeInformation(logBuilder, scopeProvider); if (!string.IsNullOrEmpty(message)) { @@ -78,10 +95,10 @@ public LogMessageEntry Format(LogLevel logLevel, string logName, int eventId, st } string timestamp = null; - var timestampFormat = options.TimestampFormat; + var timestampFormat = FormatterOptions.TimestampFormat; if (timestampFormat != null) { - var dateTime = GetCurrentDateTime(options); + var dateTime = GetCurrentDateTime(); timestamp = dateTime.ToString(timestampFormat); } @@ -100,7 +117,7 @@ public LogMessageEntry Format(LogLevel logLevel, string logName, int eventId, st levelBackground: logLevelColors.Background, levelForeground: logLevelColors.Foreground, messageColor: DefaultConsoleColor, - logAsError: logLevel >= options.LogToStandardErrorThreshold, + logAsError: logLevel >= FormatterOptions.LogToStandardErrorThreshold, writeCallback : console => { if (timestamp != null) @@ -119,9 +136,9 @@ public LogMessageEntry Format(LogLevel logLevel, string logName, int eventId, st ); } - private DateTime GetCurrentDateTime(ConsoleLoggerOptions options) + private DateTime GetCurrentDateTime() { - return options.UseUtcTimestamp ? DateTime.UtcNow : DateTime.Now; + return FormatterOptions.UseUtcTimestamp ? DateTime.UtcNow : DateTime.Now; } private static string GetLogLevelString(LogLevel logLevel) @@ -145,9 +162,9 @@ private static string GetLogLevelString(LogLevel logLevel) } } - private ConsoleColors GetLogLevelConsoleColors(LogLevel logLevel, ConsoleLoggerOptions options) + private ConsoleColors GetLogLevelConsoleColors(LogLevel logLevel) { - if (options.DisableColors) + if (FormatterOptions.DisableColors) { return new ConsoleColors(null, null); } @@ -173,9 +190,9 @@ private ConsoleColors GetLogLevelConsoleColors(LogLevel logLevel, ConsoleLoggerO } } - private void GetScopeInformation(StringBuilder stringBuilder, ConsoleLoggerOptions options, IExternalScopeProvider scopeProvider) + private void GetScopeInformation(StringBuilder stringBuilder, IExternalScopeProvider scopeProvider) { - if (options.IncludeScopes && scopeProvider != null) + if (FormatterOptions.IncludeScopes && scopeProvider != null) { var initialLength = stringBuilder.Length; diff --git a/src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/DefaultLogFormatterOptions.cs b/src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/DefaultLogFormatterOptions.cs index 60699c0e8b2398..0da31ccdf8830b 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/DefaultLogFormatterOptions.cs +++ b/src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/DefaultLogFormatterOptions.cs @@ -11,5 +11,30 @@ namespace Microsoft.Extensions.Logging.Console public class DefaultLogFormatterOptions { public DefaultLogFormatterOptions() { } + + /// + /// Includes scopes when . + /// + public bool IncludeScopes { get; set; } + + /// + /// Disables colors when . + /// + public bool DisableColors { get; set; } + + /// + /// Gets or sets value indicating the minimum level of messaged that would get written to Console.Error. + /// + public LogLevel LogToStandardErrorThreshold { get; set; } = LogLevel.None; + + /// + /// Gets or sets format string used to format timestamp in logging messages. Defaults to null. + /// + public string TimestampFormat { get; set; } + + /// + /// Gets or sets indication whether or not UTC timezone should be used to for timestamps in logging messages. Defaults to false. + /// + public bool UseUtcTimestamp { get; set; } } } diff --git a/src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/ILogFormatter.cs b/src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/ILogFormatter.cs index c8cc438c4db1fe..5a8ad45bb97836 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/ILogFormatter.cs +++ b/src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/ILogFormatter.cs @@ -9,6 +9,6 @@ namespace Microsoft.Extensions.Logging.Console public interface ILogFormatter { string Name { get; } - LogMessageEntry Format(LogLevel logLevel, string logName, int eventId, string message, Exception exception, ConsoleLoggerOptions options, IExternalScopeProvider scopeProvider); + LogMessageEntry Format(LogLevel logLevel, string logName, int eventId, string message, Exception exception, IExternalScopeProvider scopeProvider); } } diff --git a/src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/JsonLogFormatter.cs b/src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/JsonLogFormatter.cs index 8a072974a1baf5..12ca8d22981877 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/JsonLogFormatter.cs +++ b/src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/JsonLogFormatter.cs @@ -21,288 +21,79 @@ namespace Microsoft.Extensions.Logging.Console { - internal sealed class PooledByteBufferWriter : IBufferWriter, IDisposable + public class JsonConsoleLogFormatter : ILogFormatter, IDisposable { - private byte[] _rentedBuffer; - private int _index; - - private const int MinimumBufferSize = 256; - - public PooledByteBufferWriter(int initialCapacity) - { - Debug.Assert(initialCapacity > 0); - - _rentedBuffer = ArrayPool.Shared.Rent(initialCapacity); - _index = 0; - } - - public ReadOnlyMemory WrittenMemory - { - get - { - Debug.Assert(_rentedBuffer != null); - Debug.Assert(_index <= _rentedBuffer.Length); - return _rentedBuffer.AsMemory(0, _index); - } - } - - public int WrittenCount - { - get - { - Debug.Assert(_rentedBuffer != null); - return _index; - } - } - - public int Capacity - { - get - { - Debug.Assert(_rentedBuffer != null); - return _rentedBuffer.Length; - } - } - - public int FreeCapacity - { - get - { - Debug.Assert(_rentedBuffer != null); - return _rentedBuffer.Length - _index; - } - } - - public void Clear() - { - ClearHelper(); - } - - private void ClearHelper() - { - Debug.Assert(_rentedBuffer != null); - Debug.Assert(_index <= _rentedBuffer.Length); - - _rentedBuffer.AsSpan(0, _index).Clear(); - _index = 0; - } - - // Returns the rented buffer back to the pool - public void Dispose() - { - if (_rentedBuffer == null) - { - return; - } - - ClearHelper(); - ArrayPool.Shared.Return(_rentedBuffer); - _rentedBuffer = null!; - } - - public void Advance(int count) - { - Debug.Assert(_rentedBuffer != null); - Debug.Assert(count >= 0); - Debug.Assert(_index <= _rentedBuffer.Length - count); - - _index += count; - } - - public Memory GetMemory(int sizeHint = 0) - { - CheckAndResizeBuffer(sizeHint); - return _rentedBuffer.AsMemory(_index); - } + private IDisposable _optionsReloadToken; + + [ThreadStatic] + private static StringBuilder _logBuilder; - public Span GetSpan(int sizeHint = 0) + public JsonConsoleLogFormatter(IOptionsMonitor options) { - CheckAndResizeBuffer(sizeHint); - return _rentedBuffer.AsSpan(_index); + FormatterOptions = options.CurrentValue; + ReloadLoggerOptions(options.CurrentValue); + _optionsReloadToken = options.OnChange(ReloadLoggerOptions); } -#if BUILDING_INBOX_LIBRARY - internal ValueTask WriteToStreamAsync(Stream destination, CancellationToken cancellationToken) - { - return destination.WriteAsync(WrittenMemory, cancellationToken); - } -#else - internal Task WriteToStreamAsync(Stream destination, CancellationToken cancellationToken) - { - return destination.WriteAsync(_rentedBuffer, 0, _index, cancellationToken); - } -#endif + public string Name => "Json"; - private void CheckAndResizeBuffer(int sizeHint) + private string WriteJson(LogLevel logLevel, string logName, int eventId, string message, Exception exception, IExternalScopeProvider scopeProvider)//long[] extraData) { - Debug.Assert(_rentedBuffer != null); - Debug.Assert(sizeHint >= 0); - - if (sizeHint == 0) + const int DefaultBufferSize = 1024; + var output = new ArrayBufferWriter(DefaultBufferSize); + using (var writer = new Utf8JsonWriter(output, FormatterOptions.JsonWriterOptions)) { - sizeHint = MinimumBufferSize; - } - - int availableSpace = _rentedBuffer.Length - _index; + writer.WriteStartObject(); - if (sizeHint > availableSpace) - { - int currentLength = _rentedBuffer.Length; - int growBy = Math.Max(sizeHint, currentLength); - int newSize = currentLength + growBy; + string timestamp = null; + var timestampFormat = FormatterOptions.TimestampFormat; + if (timestampFormat != null) + { + var dateTime = FormatterOptions.UseUtcTimestamp ? DateTime.UtcNow : DateTime.Now; + timestamp = dateTime.ToString(timestampFormat); + } + writer.WriteString("timestamp", timestamp); + writer.WriteNumber("eventId", eventId); + writer.WriteString("logLevel", GetLogLevelString(logLevel)); + writer.WriteString("category", logName); + writer.WriteString("message", message); - if ((uint)newSize > int.MaxValue) + if (exception != null) { - newSize = currentLength + sizeHint; - if ((uint)newSize > int.MaxValue) + writer.WriteStartObject("exception"); + writer.WriteString("message", exception.Message.ToString() + "' anc'"); + writer.WriteString("type", exception.GetType().ToString()); + writer.WriteStartArray("stackTrace"); + foreach (var xx in exception?.StackTrace?.Split(Environment.NewLine)) { - throw new OutOfMemoryException("(uint)newSize _BufferMaximumSizeExceeded"); + JsonSerializer.Serialize(writer, xx, FormatterOptions.JsonSerializerOptions); } + writer.WriteEndArray(); + writer.WriteNumber("hResult", exception.HResult); + writer.WriteEndObject(); } - byte[] oldBuffer = _rentedBuffer; + GetScopeInformation(writer, scopeProvider); - _rentedBuffer = ArrayPool.Shared.Rent(newSize); + writer.WriteEndObject(); - Debug.Assert(oldBuffer.Length >= _index); - Debug.Assert(_rentedBuffer.Length >= _index); - - Span previousBuffer = oldBuffer.AsSpan(0, _index); - previousBuffer.CopyTo(_rentedBuffer); - previousBuffer.Clear(); - ArrayPool.Shared.Return(oldBuffer); + writer.Flush(); } - - Debug.Assert(_rentedBuffer.Length - _index > 0); - Debug.Assert(_rentedBuffer.Length - _index >= sizeHint); + return Encoding.UTF8.GetString(output.WrittenMemory.Span); } - } - public class JsonConsoleLogFormatter : ILogFormatter, IDisposable - { - private readonly IOptionsMonitor _options; - private IDisposable _optionsReloadToken; - - private static readonly string _loglevelPadding = ": "; - private static readonly string _messagePadding; - private static readonly string _newLineWithMessagePadding; - - [ThreadStatic] - private static StringBuilder _logBuilder; - [ThreadStatic] - private static IDictionary _xBuilder; - - static JsonConsoleLogFormatter() - { - var logLevelString = GetLogLevelString(LogLevel.Information); - _messagePadding = new string(' ', logLevelString.Length + _loglevelPadding.Length); - _newLineWithMessagePadding = Environment.NewLine + _messagePadding; - } - - public JsonLogFormatterOptions FormatterOptions { get; set; } - - public JsonConsoleLogFormatter(IOptionsMonitor options) - { - _options = options; - ReloadLoggerOptions(options.CurrentValue); - _optionsReloadToken = _options.OnChange(ReloadLoggerOptions); - } - - private void ReloadLoggerOptions(JsonLogFormatterOptions options) - { - FormatterOptions = options; - } - - public string Name => "Json"; - - internal IDictionary Scope { get; } = new Dictionary(StringComparer.Ordinal); - - /// - public void Dispose() - { - _optionsReloadToken?.Dispose(); - } - - public LogMessageEntry Format(LogLevel logLevel, string logName, int eventId, string message, Exception exception, ConsoleLoggerOptions options, IExternalScopeProvider scopeProvider) + public LogMessageEntry Format(LogLevel logLevel, string logName, int eventId, string message, Exception exception, IExternalScopeProvider scopeProvider) { var logBuilder = _logBuilder; - var xBuilder = _xBuilder; _logBuilder = null; - _xBuilder = null; if (logBuilder == null) { logBuilder = new StringBuilder(); - xBuilder = new Dictionary(); } - // Example: - // INFO: ConsoleApp.Program[10] - // Request received - - var logLevelString = GetLogLevelString(logLevel); - - if (!string.IsNullOrEmpty(message)) - { - const int DefaultBufferSize = 16384; - - using (var output = new PooledByteBufferWriter(DefaultBufferSize)) - { - using (var writer = new Utf8JsonWriter(output, options.JsonWriterOptions)) - { - writer.WriteStartObject(); - // TimeStamp - writer.WriteNumber("EventId", eventId); - writer.WriteString("LogLevel", logLevelString); - writer.WriteString("Category", logName); - writer.WriteString("Message", message); - - GetScopeInformation(writer, options, scopeProvider); - - writer.WriteEndObject(); - } - logBuilder.AppendLine(Encoding.UTF8.GetString(output.WrittenMemory.Span)); - } - } - - // Example: - // System.InvalidOperationException - // at Namespace.Class.Function() in File:line X - if (exception != null) - { - // exception message - // logBuilder.AppendLine(exception.ToString()); - const int DefaultBufferSize = 16384; - - using (var output = new PooledByteBufferWriter(DefaultBufferSize)) - { - using (var writer = new Utf8JsonWriter(output, FormatterOptions.JsonWriterOptions)) - { - writer.WriteStartObject(); - writer.WriteString("Message", exception.Message.ToString()); - writer.WriteString("Type", exception.GetType().ToString()); - writer.WriteStartArray("StackTrace"); - foreach (var xx in exception?.StackTrace?.Split(Environment.NewLine)) - { - JsonSerializer.Serialize(writer, xx); - } - writer.WriteEndArray(); - writer.WriteNumber("HResult", exception.HResult); - writer.WriteEndObject(); - } - - logBuilder.AppendLine(Encoding.UTF8.GetString(output.WrittenMemory.Span)); - } - } - - string timestamp = null; - var timestampFormat = options.TimestampFormat; - if (timestampFormat != null) - { - var dateTime = GetCurrentDateTime(options); - timestamp = dateTime.ToString(timestampFormat); - } + logBuilder.Append(WriteJson(logLevel, logName, eventId, message, exception, scopeProvider)); var formattedMessage = logBuilder.ToString(); logBuilder.Clear(); @@ -311,42 +102,31 @@ public LogMessageEntry Format(LogLevel logLevel, string logName, int eventId, st logBuilder.Capacity = 1024; } _logBuilder = logBuilder; - _xBuilder = xBuilder; return new LogMessageEntry( message: formattedMessage, - timeStamp: timestamp, - levelString: string.Empty, +// timeStamp: timestamp, +// levelString: logLevelString, levelBackground: null, levelForeground: null, messageColor: null, - logAsError: logLevel >= options.LogToStandardErrorThreshold, - writeCallback : console => + logAsError: logLevel >= FormatterOptions.LogToStandardErrorThreshold, + writeCallback: console => { - if (timestamp != null) - { - console.Write(timestamp, null, null); - } - - console.Write(formattedMessage, null, null); + console.WriteLine(formattedMessage, null, null); console.Flush(); } ); } - private DateTime GetCurrentDateTime(ConsoleLoggerOptions options) - { - return options.UseUtcTimestamp ? DateTime.UtcNow : DateTime.Now; - } - private static string GetLogLevelString(LogLevel logLevel) { switch (logLevel) { case LogLevel.Trace: - return "json_trce"; + return "json_trace"; case LogLevel.Debug: - return "json_dbug"; + return "json_debug"; case LogLevel.Information: return "json_info"; case LogLevel.Warning: @@ -354,33 +134,43 @@ private static string GetLogLevelString(LogLevel logLevel) case LogLevel.Error: return "json_fail"; case LogLevel.Critical: - return "json_crit"; + return "json_critical"; default: throw new ArgumentOutOfRangeException(nameof(logLevel)); } } - private void GetScopeInformation(Utf8JsonWriter writer, ConsoleLoggerOptions options, IExternalScopeProvider scopeProvider) + private void GetScopeInformation(Utf8JsonWriter writer, IExternalScopeProvider scopeProvider) { try { - if (options.IncludeScopes && scopeProvider != null) + if (FormatterOptions.IncludeScopes && scopeProvider != null) { - writer.WriteStartArray("Scopes"); + writer.WriteStartObject("scopes"); scopeProvider.ForEachScope((scope, state) => { - if (scope is IReadOnlyList>)// kvps) + if (scope is IReadOnlyList> kvps) { - //foreach (var kvp in kvps) - //{ - // //state.WritePropertyName(kvp.Key); - // JsonSerializer.Serialize(kvp.Value); - //} + foreach (var kvp in kvps) + { + + if (kvp.Value is String ss) + state.WriteString(kvp.Key, ss); + else + if (kvp.Value is int ii) + state.WriteNumber(kvp.Key, ii); + else + { + // check how this work + state.WritePropertyName(kvp.Key); + JsonSerializer.Serialize(state, kvp.Value); + } + } //state is the writer - JsonSerializer.Serialize(state, scope); + //JsonSerializer.Serialize(state, scope); } }, (writer)); - writer.WriteEndArray(); + writer.WriteEndObject(); } } catch (Exception ex) @@ -389,17 +179,16 @@ private void GetScopeInformation(Utf8JsonWriter writer, ConsoleLoggerOptions opt } } - private readonly struct ConsoleColors - { - public ConsoleColors(ConsoleColor? foreground, ConsoleColor? background) - { - Foreground = foreground; - Background = background; - } + public JsonLogFormatterOptions FormatterOptions { get; set; } - public ConsoleColor? Foreground { get; } + private void ReloadLoggerOptions(JsonLogFormatterOptions options) + { + FormatterOptions = options; + } - public ConsoleColor? Background { get; } + public void Dispose() + { + _optionsReloadToken?.Dispose(); } } } diff --git a/src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/JsonLogFormatterOptions.cs b/src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/JsonLogFormatterOptions.cs index d1845d9e0ca747..63d0259fa97331 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/JsonLogFormatterOptions.cs +++ b/src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/JsonLogFormatterOptions.cs @@ -12,6 +12,31 @@ public class JsonLogFormatterOptions { public JsonLogFormatterOptions() { } public JsonWriterOptions JsonWriterOptions { get; set; } - // or public JsonSerializerOptions JsonSerializerOptions { get; set; } + public JsonSerializerOptions JsonSerializerOptions { get; set; } + + /// + /// Includes scopes when . + /// + public bool IncludeScopes { get; set; } + + /// + /// Disables colors when . + /// + public bool DisableColors { get; set; } + + /// + /// Gets or sets value indicating the minimum level of messaged that would get written to Console.Error. + /// + public LogLevel LogToStandardErrorThreshold { get; set; } = LogLevel.None; + + /// + /// Gets or sets format string used to format timestamp in logging messages. Defaults to null. + /// + public string TimestampFormat { get; set; } + + /// + /// Gets or sets indication whether or not UTC timezone should be used to for timestamps in logging messages. Defaults to false. + /// + public bool UseUtcTimestamp { get; set; } } } diff --git a/src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/SystemdLogFormatter.cs b/src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/SystemdLogFormatter.cs index 10e690e89e0a4a..1fa7559ee5cc24 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/SystemdLogFormatter.cs +++ b/src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/SystemdLogFormatter.cs @@ -8,9 +8,8 @@ namespace Microsoft.Extensions.Logging.Console { - public class SystemdLogFormatter : ILogFormatter + public class SystemdLogFormatter : ILogFormatter, IDisposable { - private readonly IOptionsMonitor _options; private IDisposable _optionsReloadToken; private static readonly string _loglevelPadding = ": "; @@ -27,9 +26,9 @@ static SystemdLogFormatter() public SystemdLogFormatter(IOptionsMonitor options) { - _options = options; + FormatterOptions = options.CurrentValue; ReloadLoggerOptions(options.CurrentValue); - _optionsReloadToken = _options.OnChange(ReloadLoggerOptions); + _optionsReloadToken = options.OnChange(ReloadLoggerOptions); } private void ReloadLoggerOptions(SystemdLogFormatterOptions options) @@ -37,11 +36,16 @@ private void ReloadLoggerOptions(SystemdLogFormatterOptions options) FormatterOptions = options; } + public void Dispose() + { + _optionsReloadToken?.Dispose(); + } + public string Name => "Systemd"; public SystemdLogFormatterOptions FormatterOptions { get; set; } - public LogMessageEntry Format(LogLevel logLevel, string logName, int eventId, string message, Exception exception, ConsoleLoggerOptions options, IExternalScopeProvider scopeProvider) + public LogMessageEntry Format(LogLevel logLevel, string logName, int eventId, string message, Exception exception, IExternalScopeProvider scopeProvider) { var logBuilder = _logBuilder; _logBuilder = null; @@ -62,10 +66,10 @@ public LogMessageEntry Format(LogLevel logLevel, string logName, int eventId, st logBuilder.Append(logLevelString); // timestamp - var timestampFormat = options.TimestampFormat; + var timestampFormat = FormatterOptions.TimestampFormat; if (timestampFormat != null) { - var dateTime = GetCurrentDateTime(options); + var dateTime = GetCurrentDateTime(); logBuilder.Append(dateTime.ToString(timestampFormat)); } @@ -76,7 +80,7 @@ public LogMessageEntry Format(LogLevel logLevel, string logName, int eventId, st logBuilder.Append("]"); // scope information - GetScopeInformation(logBuilder, options, scopeProvider); + GetScopeInformation(logBuilder, scopeProvider); // message if (!string.IsNullOrEmpty(message)) @@ -108,7 +112,7 @@ public LogMessageEntry Format(LogLevel logLevel, string logName, int eventId, st return new LogMessageEntry( message: formattedMessage, - logAsError: logLevel >= options.LogToStandardErrorThreshold, + logAsError: logLevel >= FormatterOptions.LogToStandardErrorThreshold, writeCallback : console => { console.Write(formattedMessage, null, null); @@ -124,9 +128,9 @@ static void AppendAndReplaceNewLine(StringBuilder sb, string message) } } - private DateTime GetCurrentDateTime(ConsoleLoggerOptions options) + private DateTime GetCurrentDateTime() { - return options.UseUtcTimestamp ? DateTime.UtcNow : DateTime.Now; + return FormatterOptions.UseUtcTimestamp ? DateTime.UtcNow : DateTime.Now; } private static string GetSyslogSeverityString(LogLevel logLevel) @@ -150,9 +154,9 @@ private static string GetSyslogSeverityString(LogLevel logLevel) } } - private void GetScopeInformation(StringBuilder stringBuilder, ConsoleLoggerOptions options, IExternalScopeProvider scopeProvider) + private void GetScopeInformation(StringBuilder stringBuilder, IExternalScopeProvider scopeProvider) { - if (options.IncludeScopes && scopeProvider != null) + if (FormatterOptions.IncludeScopes && scopeProvider != null) { var initialLength = stringBuilder.Length; diff --git a/src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/SystemdLogFormatterOptions.cs b/src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/SystemdLogFormatterOptions.cs index 89b282a627f8f6..922d62e7ddf738 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/SystemdLogFormatterOptions.cs +++ b/src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/SystemdLogFormatterOptions.cs @@ -10,5 +10,30 @@ namespace Microsoft.Extensions.Logging.Console public class SystemdLogFormatterOptions { public SystemdLogFormatterOptions() { } + + /// + /// Includes scopes when . + /// + public bool IncludeScopes { get; set; } + + /// + /// Disables colors when . + /// + public bool DisableColors { get; set; } + + /// + /// Gets or sets value indicating the minimum level of messaged that would get written to Console.Error. + /// + public LogLevel LogToStandardErrorThreshold { get; set; } = LogLevel.None; + + /// + /// Gets or sets format string used to format timestamp in logging messages. Defaults to null. + /// + public string TimestampFormat { get; set; } + + /// + /// Gets or sets indication whether or not UTC timezone should be used to for timestamps in logging messages. Defaults to false. + /// + public bool UseUtcTimestamp { get; set; } } } diff --git a/src/libraries/Microsoft.Extensions.Logging.Console/src/Microsoft.Extensions.Logging.Console.csproj b/src/libraries/Microsoft.Extensions.Logging.Console/src/Microsoft.Extensions.Logging.Console.csproj index d235bf2d2f1fe5..c44f56fa9fdf0e 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Console/src/Microsoft.Extensions.Logging.Console.csproj +++ b/src/libraries/Microsoft.Extensions.Logging.Console/src/Microsoft.Extensions.Logging.Console.csproj @@ -33,6 +33,11 @@ + + + + + From 62aecebe8cdb2400e9a5b0265a8938fcfe27ef9e Mon Sep 17 00:00:00 2001 From: Maryam Ariyan Date: Thu, 14 May 2020 15:37:55 -0700 Subject: [PATCH 03/15] nit cleanup - Remove unused properties on *FormatterOptions - ScopeProvider to be set outside of logger ctor --- .../ref/Microsoft.Extensions.Logging.Console.cs | 2 -- .../src/ConsoleLogger.cs | 2 -- .../src/Formatter/JsonLogFormatterOptions.cs | 5 ----- .../src/Formatter/SystemdLogFormatterOptions.cs | 5 ----- 4 files changed, 14 deletions(-) diff --git a/src/libraries/Microsoft.Extensions.Logging.Console/ref/Microsoft.Extensions.Logging.Console.cs b/src/libraries/Microsoft.Extensions.Logging.Console/ref/Microsoft.Extensions.Logging.Console.cs index 1f5ad8949dabfd..291ecfbab33702 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Console/ref/Microsoft.Extensions.Logging.Console.cs +++ b/src/libraries/Microsoft.Extensions.Logging.Console/ref/Microsoft.Extensions.Logging.Console.cs @@ -84,7 +84,6 @@ public void Dispose() { } public partial class JsonLogFormatterOptions { public JsonLogFormatterOptions() { } - public bool DisableColors { get { throw null; } set { } } public bool IncludeScopes { get { throw null; } set { } } public System.Text.Json.JsonSerializerOptions JsonSerializerOptions { get { throw null; } set { } } public System.Text.Json.JsonWriterOptions JsonWriterOptions { get { throw null; } set { } } @@ -115,7 +114,6 @@ public void Dispose() { } public partial class SystemdLogFormatterOptions { public SystemdLogFormatterOptions() { } - public bool DisableColors { get { throw null; } set { } } public bool IncludeScopes { get { throw null; } set { } } public Microsoft.Extensions.Logging.LogLevel LogToStandardErrorThreshold { get { throw null; } set { } } public string TimestampFormat { get { throw null; } set { } } diff --git a/src/libraries/Microsoft.Extensions.Logging.Console/src/ConsoleLogger.cs b/src/libraries/Microsoft.Extensions.Logging.Console/src/ConsoleLogger.cs index 20bce6bbfad83e..b84ccde9aa9491 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Console/src/ConsoleLogger.cs +++ b/src/libraries/Microsoft.Extensions.Logging.Console/src/ConsoleLogger.cs @@ -25,8 +25,6 @@ internal ConsoleLogger(string name, ConsoleLoggerProcessor loggerProcessor) _name = name; _queueProcessor = loggerProcessor; - ScopeProvider = new LoggerExternalScopeProvider(); - } internal IExternalScopeProvider ScopeProvider { get; set; } diff --git a/src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/JsonLogFormatterOptions.cs b/src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/JsonLogFormatterOptions.cs index 63d0259fa97331..7a79a068584554 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/JsonLogFormatterOptions.cs +++ b/src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/JsonLogFormatterOptions.cs @@ -19,11 +19,6 @@ public JsonLogFormatterOptions() { } /// public bool IncludeScopes { get; set; } - /// - /// Disables colors when . - /// - public bool DisableColors { get; set; } - /// /// Gets or sets value indicating the minimum level of messaged that would get written to Console.Error. /// diff --git a/src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/SystemdLogFormatterOptions.cs b/src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/SystemdLogFormatterOptions.cs index 922d62e7ddf738..f207d2f8be4d6a 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/SystemdLogFormatterOptions.cs +++ b/src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/SystemdLogFormatterOptions.cs @@ -16,11 +16,6 @@ public SystemdLogFormatterOptions() { } /// public bool IncludeScopes { get; set; } - /// - /// Disables colors when . - /// - public bool DisableColors { get; set; } - /// /// Gets or sets value indicating the minimum level of messaged that would get written to Console.Error. /// From 391d561256cee7aab52e137fb93acb23b7e71098 Mon Sep 17 00:00:00 2001 From: Maryam Ariyan Date: Fri, 15 May 2020 02:18:27 -0700 Subject: [PATCH 04/15] - messages can color vars in messages (Compact) TODO: - Fix performance. - Improve LogMessageEnrty struct --- .../Microsoft.Extensions.Logging.Console.cs | 4 + .../src/ConsoleLogger.cs | 4 +- .../src/ConsoleLoggerProcessor.cs | 1 + .../src/Formatter/CompactLogFormatter.cs | 193 +++++++++++++++++- .../src/Formatter/DefaultLogFormatter.cs | 10 + .../src/Formatter/ILogFormatter.cs | 1 + .../src/Formatter/JsonLogFormatter.cs | 26 ++- .../src/Formatter/SystemdLogFormatter.cs | 10 + ...icrosoft.Extensions.Logging.Console.csproj | 1 + 9 files changed, 233 insertions(+), 17 deletions(-) diff --git a/src/libraries/Microsoft.Extensions.Logging.Console/ref/Microsoft.Extensions.Logging.Console.cs b/src/libraries/Microsoft.Extensions.Logging.Console/ref/Microsoft.Extensions.Logging.Console.cs index 291ecfbab33702..7f18c6484d0a76 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Console/ref/Microsoft.Extensions.Logging.Console.cs +++ b/src/libraries/Microsoft.Extensions.Logging.Console/ref/Microsoft.Extensions.Logging.Console.cs @@ -52,6 +52,7 @@ public DefaultLogFormatter(Microsoft.Extensions.Options.IOptionsMonitor(Microsoft.Extensions.Logging.LogLevel logLevel, string logName, int eventId, TState state, System.Exception exception, System.Func formatter, Microsoft.Extensions.Logging.IExternalScopeProvider scopeProvider) { throw null; } } public partial class DefaultLogFormatterOptions { @@ -72,6 +73,7 @@ public partial interface ILogFormatter { string Name { get; } Microsoft.Extensions.Logging.Console.LogMessageEntry Format(Microsoft.Extensions.Logging.LogLevel logLevel, string logName, int eventId, string message, System.Exception exception, Microsoft.Extensions.Logging.IExternalScopeProvider scopeProvider); + Microsoft.Extensions.Logging.Console.LogMessageEntry Format(Microsoft.Extensions.Logging.LogLevel logLevel, string logName, int eventId, TState state, System.Exception exception, System.Func formatter, Microsoft.Extensions.Logging.IExternalScopeProvider scopeProvider); } public partial class JsonConsoleLogFormatter : Microsoft.Extensions.Logging.Console.ILogFormatter, System.IDisposable { @@ -80,6 +82,7 @@ public JsonConsoleLogFormatter(Microsoft.Extensions.Options.IOptionsMonitor(Microsoft.Extensions.Logging.LogLevel logLevel, string logName, int eventId, TState state, System.Exception exception, System.Func formatter, Microsoft.Extensions.Logging.IExternalScopeProvider scopeProvider) { throw null; } } public partial class JsonLogFormatterOptions { @@ -110,6 +113,7 @@ public SystemdLogFormatter(Microsoft.Extensions.Options.IOptionsMonitor(Microsoft.Extensions.Logging.LogLevel logLevel, string logName, int eventId, TState state, System.Exception exception, System.Func formatter, Microsoft.Extensions.Logging.IExternalScopeProvider scopeProvider) { throw null; } } public partial class SystemdLogFormatterOptions { diff --git a/src/libraries/Microsoft.Extensions.Logging.Console/src/ConsoleLogger.cs b/src/libraries/Microsoft.Extensions.Logging.Console/src/ConsoleLogger.cs index b84ccde9aa9491..7215e3439dd905 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Console/src/ConsoleLogger.cs +++ b/src/libraries/Microsoft.Extensions.Logging.Console/src/ConsoleLogger.cs @@ -44,10 +44,10 @@ public void Log(LogLevel logLevel, EventId eventId, TState state, Except } var message = formatter(state, exception); - if (!string.IsNullOrEmpty(message) || exception != null) { - WriteMessage(logLevel, _name, eventId.Id, message, exception); + var entry = Formatter.Format(logLevel, _name, eventId.Id, state, exception, formatter, ScopeProvider); + _queueProcessor.EnqueueMessage(entry); } } diff --git a/src/libraries/Microsoft.Extensions.Logging.Console/src/ConsoleLoggerProcessor.cs b/src/libraries/Microsoft.Extensions.Logging.Console/src/ConsoleLoggerProcessor.cs index 988aa5c2fe23de..9234b7dcced882 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Console/src/ConsoleLoggerProcessor.cs +++ b/src/libraries/Microsoft.Extensions.Logging.Console/src/ConsoleLoggerProcessor.cs @@ -53,6 +53,7 @@ public virtual void EnqueueMessage(LogMessageEntry message) internal virtual void WriteMessage(LogMessageEntry message) { var console = message.LogAsError ? ErrorConsole : Console; + // is giving user control on this thread over how long the output thread takes to write to console - something to consider message.WriteCallback(console); } diff --git a/src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/CompactLogFormatter.cs b/src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/CompactLogFormatter.cs index 11f2b21db4254b..3edb59af209329 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/CompactLogFormatter.cs +++ b/src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/CompactLogFormatter.cs @@ -5,6 +5,9 @@ using System; using System.Text; using Microsoft.Extensions.Options; +using System.Collections.Generic; +using System.Reflection; +using System.Linq; namespace Microsoft.Extensions.Logging.Console { @@ -49,8 +52,24 @@ public void Dispose() public string Name => "Compact"; + public LogMessageEntry Format(LogLevel logLevel, string logName, int eventId, TState state, Exception exception, Func formatter, IExternalScopeProvider scopeProvider) + { + var message = formatter(state, exception); + if (!string.IsNullOrEmpty(message) || exception != null) + { + return FormatHelper(logLevel, logName, eventId, message, exception, scopeProvider, state); + } + return default; + } + public LogMessageEntry Format(LogLevel logLevel, string logName, int eventId, string message, Exception exception, IExternalScopeProvider scopeProvider) { + return FormatHelper(logLevel, logName, eventId, message, exception, scopeProvider, null); + } + + private LogMessageEntry FormatHelper(LogLevel logLevel, string logName, int eventId, string message, Exception exception, IExternalScopeProvider scopeProvider, TState scope) + { + List msgs = new List(); // todo fix later: var logBuilder = _logBuilder; _logBuilder = null; @@ -74,8 +93,100 @@ public LogMessageEntry Format(LogLevel logLevel, string logName, int eventId, st logBuilder.Append("]"); // logBuilder.AppendLine("]"); - // scope information - GetScopeInformation(logBuilder, scopeProvider); + msgs.Add(new Message($"{logName}[{eventId}] ", null, null)); + string originalFormat = null; + int count = 0; + + if (scope != null) + { + logBuilder.Append(_messagePadding); + if (scope is IReadOnlyList> kvpsx) + { + var strings = new List>(); + logBuilder.Append(" -> "); + foreach (var kvp in kvpsx) + { + if (kvp.Key.Contains("{OriginalFormat}")) + { + originalFormat = kvp.Value.ToString(); + } + else + { + //count++; + strings.Add(kvp); + logBuilder.Append(kvp.Value.ToString()); + logBuilder.Append(", "); + } + } + int prevIndex = 0; + if (originalFormat != null) + { + foreach (var kvp in kvpsx) + { + if (!kvp.Key.Contains("{OriginalFormat}")) + { + var curIndex = originalFormat.IndexOf("{" + strings.ElementAt(count).Key + "}"); + if (curIndex != -1) + { + var curString = originalFormat.Substring(prevIndex, curIndex - prevIndex); + msgs.Add(new Message(curString, null, null)); + msgs.Add(new Message(strings.ElementAt(count).Value.ToString(), null, ConsoleColor.Cyan)); + prevIndex += curIndex + strings.ElementAt(count).Key.Length + 2; + count++; + //strings.Add(kvp.Value.ToString()); + logBuilder.Append(kvp.Value.ToString()); + logBuilder.Append(", "); + } + } + } + } + } + else if (scope is IReadOnlyList> kvps) + { + var strings = new List>(); + logBuilder.Append(" -> "); + foreach (var kvp in kvps) + { + if (kvp.Key.Contains("{OriginalFormat}")) + { + originalFormat = kvp.Value; + } + else + { + //count++; + strings.Add(kvp); + logBuilder.Append(kvp.Value); + logBuilder.Append(", "); + } + } + int prevIndex = 0; + if (originalFormat != null) + { + foreach (var kvp in kvps) + { + if (!kvp.Key.Contains("{OriginalFormat}")) + { + var curIndex = originalFormat.IndexOf("{" + strings.ElementAt(count).Key + "}"); + if (curIndex != -1) + { + var curString = originalFormat.Substring(prevIndex, curIndex - prevIndex); + msgs.Add(new Message(curString, null, null)); + msgs.Add(new Message(strings.ElementAt(count).Value, null, ConsoleColor.Cyan)); + prevIndex += curIndex + strings.ElementAt(count).Key.Length + 2; + count++; + logBuilder.Append(kvp.Value); + logBuilder.Append(", "); + } + } + } + } + } + else + { + logBuilder.Append("-> "); + logBuilder.Append(scope.ToString()); + } + } if (!string.IsNullOrEmpty(message)) { @@ -84,8 +195,20 @@ public LogMessageEntry Format(LogLevel logLevel, string logName, int eventId, st var len = logBuilder.Length; logBuilder.AppendLine(message); + if (originalFormat == null) + { + msgs.Add(new Message(message, null, null)); + } + else if (count == 0) + { + msgs.Add(new Message(originalFormat, null, null)); + } } + // scope information + msgs.Add(new Message(" ", null, null)); + GetScopeInformation(logBuilder, scopeProvider, msgs); + // Example: // System.InvalidOperationException // at Namespace.Class.Function() in File:line X @@ -93,6 +216,8 @@ public LogMessageEntry Format(LogLevel logLevel, string logName, int eventId, st { // exception message logBuilder.Append(exception.ToString()); + msgs.Add(new Message(" ", null, null)); + msgs.Add(new Message(exception.ToString(), null, null)); // logBuilder.AppendLine(exception.ToString()); } @@ -122,22 +247,65 @@ public LogMessageEntry Format(LogLevel logLevel, string logName, int eventId, st logAsError: logLevel >= FormatterOptions.LogToStandardErrorThreshold, writeCallback : console => { - if (timestamp != null) + if (timestamp != null || logLevelString != null) { - console.Write(timestamp, DefaultConsoleColor, DefaultConsoleColor); + console.Write("[", null, null); + + if (timestamp != null) + { + console.Write(timestamp, null, null); + console.Write(" ", null, null); + } + if (logLevelString != null) + { + console.Write(logLevelString, logLevelColors.Background, logLevelColors.Foreground); + console.Write("", null, null); + } + console.Write("] ", null, null); } - if (logLevelString != null) + if (msgs.Count > 0) { - console.Write(logLevelString, logLevelColors.Background, logLevelColors.Foreground); + foreach (var item in msgs) + { + console.Write(item.Content, item.Background, item.Foreground); + } } - console.Write(formattedMessage, DefaultConsoleColor, DefaultConsoleColor); + //console.Write(formattedMessage, DefaultConsoleColor, DefaultConsoleColor); + console.WriteLine(string.Empty, DefaultConsoleColor, DefaultConsoleColor); console.Flush(); } ); } + internal struct LogEntry + { + internal LogEntry(Action action, Message[] messages, bool logAsError) + { + Messages = messages; + WriteCallback = action; + LogAsError = logAsError; + } + + internal Message[] Messages; + internal Action WriteCallback; + internal bool LogAsError; + } + + internal struct Message + { + internal Message(string message, ConsoleColor? background, ConsoleColor? foreground) + { + Content = message; + Background = background; + Foreground = foreground; + } + internal string Content; + internal ConsoleColor? Background; + internal ConsoleColor? Foreground; + } + private DateTime GetCurrentDateTime() { return FormatterOptions.UseUtcTimestamp ? DateTime.UtcNow : DateTime.Now; @@ -192,7 +360,7 @@ private ConsoleColors GetLogLevelConsoleColors(LogLevel logLevel) } } - private void GetScopeInformation(StringBuilder stringBuilder, IExternalScopeProvider scopeProvider) + private void GetScopeInformation(StringBuilder stringBuilder, IExternalScopeProvider scopeProvider, List msgs) { if (FormatterOptions.IncludeScopes && scopeProvider != null) { @@ -200,16 +368,21 @@ private void GetScopeInformation(StringBuilder stringBuilder, IExternalScopeProv scopeProvider.ForEachScope((scope, state) => { - var (builder, paddAt) = state; + var (builder, paddAt, messages) = state; var padd = paddAt == builder.Length; if (padd) { + //messages.Add(new Message(_messagePadding, null, null)); builder.Append(_messagePadding); } + messages.Add(new Message("=> ", null, null)); + messages.Add(new Message(scope.ToString(), null, ConsoleColor.DarkGray)); + messages.Add(new Message(" ", null, null)); builder.Append("=> "); builder.Append(scope); builder.Append(" "); - }, (stringBuilder, initialLength)); + + }, (stringBuilder, initialLength, msgs)); if (stringBuilder.Length > initialLength) { diff --git a/src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/DefaultLogFormatter.cs b/src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/DefaultLogFormatter.cs index 9805c26227b630..bf311fe2143f87 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/DefaultLogFormatter.cs +++ b/src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/DefaultLogFormatter.cs @@ -49,6 +49,16 @@ public void Dispose() public DefaultLogFormatterOptions FormatterOptions { get; set; } + public LogMessageEntry Format(LogLevel logLevel, string logName, int eventId, TState state, Exception exception, Func formatter, IExternalScopeProvider scopeProvider) + { + var message = formatter(state, exception); + if (!string.IsNullOrEmpty(message) || exception != null) + { + return Format(logLevel, logName, eventId, message, exception, scopeProvider); + } + return default; + } + public LogMessageEntry Format(LogLevel logLevel, string logName, int eventId, string message, Exception exception, IExternalScopeProvider scopeProvider) { var logBuilder = _logBuilder; diff --git a/src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/ILogFormatter.cs b/src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/ILogFormatter.cs index 5a8ad45bb97836..3ef81d3c350faa 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/ILogFormatter.cs +++ b/src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/ILogFormatter.cs @@ -10,5 +10,6 @@ public interface ILogFormatter { string Name { get; } LogMessageEntry Format(LogLevel logLevel, string logName, int eventId, string message, Exception exception, IExternalScopeProvider scopeProvider); + LogMessageEntry Format(LogLevel logLevel, string logName, int eventId, TState state, Exception exception, Func formatter, IExternalScopeProvider scopeProvider); } } diff --git a/src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/JsonLogFormatter.cs b/src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/JsonLogFormatter.cs index 12ca8d22981877..4cb5f916bc2e8d 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/JsonLogFormatter.cs +++ b/src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/JsonLogFormatter.cs @@ -62,12 +62,15 @@ private string WriteJson(LogLevel logLevel, string logName, int eventId, string if (exception != null) { writer.WriteStartObject("exception"); - writer.WriteString("message", exception.Message.ToString() + "' anc'"); + writer.WriteString("message", exception.Message.ToString()); writer.WriteString("type", exception.GetType().ToString()); writer.WriteStartArray("stackTrace"); - foreach (var xx in exception?.StackTrace?.Split(Environment.NewLine)) + if (exception?.StackTrace != null) { - JsonSerializer.Serialize(writer, xx, FormatterOptions.JsonSerializerOptions); + foreach (var xx in exception?.StackTrace?.Split(Environment.NewLine)) + { + JsonSerializer.Serialize(writer, xx, FormatterOptions.JsonSerializerOptions); + } } writer.WriteEndArray(); writer.WriteNumber("hResult", exception.HResult); @@ -83,6 +86,16 @@ private string WriteJson(LogLevel logLevel, string logName, int eventId, string return Encoding.UTF8.GetString(output.WrittenMemory.Span); } + public LogMessageEntry Format(LogLevel logLevel, string logName, int eventId, TState state, Exception exception, Func formatter, IExternalScopeProvider scopeProvider) + { + var message = formatter(state, exception); + if (!string.IsNullOrEmpty(message) || exception != null) + { + return Format(logLevel, logName, eventId, message, exception, scopeProvider); + } + return default; + } + public LogMessageEntry Format(LogLevel logLevel, string logName, int eventId, string message, Exception exception, IExternalScopeProvider scopeProvider) { var logBuilder = _logBuilder; @@ -153,8 +166,7 @@ private void GetScopeInformation(Utf8JsonWriter writer, IExternalScopeProvider s { foreach (var kvp in kvps) { - - if (kvp.Value is String ss) + if (kvp.Value is string ss) state.WriteString(kvp.Key, ss); else if (kvp.Value is int ii) @@ -169,6 +181,10 @@ private void GetScopeInformation(Utf8JsonWriter writer, IExternalScopeProvider s //state is the writer //JsonSerializer.Serialize(state, scope); } + else + { + state.WriteString("noName", scope.ToString()); + } }, (writer)); writer.WriteEndObject(); } diff --git a/src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/SystemdLogFormatter.cs b/src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/SystemdLogFormatter.cs index 1fa7559ee5cc24..6b141f86992cac 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/SystemdLogFormatter.cs +++ b/src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/SystemdLogFormatter.cs @@ -45,6 +45,16 @@ public void Dispose() public SystemdLogFormatterOptions FormatterOptions { get; set; } + public LogMessageEntry Format(LogLevel logLevel, string logName, int eventId, TState state, Exception exception, Func formatter, IExternalScopeProvider scopeProvider) + { + var message = formatter(state, exception); + if (!string.IsNullOrEmpty(message) || exception != null) + { + return Format(logLevel, logName, eventId, message, exception, scopeProvider); + } + return default; + } + public LogMessageEntry Format(LogLevel logLevel, string logName, int eventId, string message, Exception exception, IExternalScopeProvider scopeProvider) { var logBuilder = _logBuilder; diff --git a/src/libraries/Microsoft.Extensions.Logging.Console/src/Microsoft.Extensions.Logging.Console.csproj b/src/libraries/Microsoft.Extensions.Logging.Console/src/Microsoft.Extensions.Logging.Console.csproj index c44f56fa9fdf0e..2f718757bae34c 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Console/src/Microsoft.Extensions.Logging.Console.csproj +++ b/src/libraries/Microsoft.Extensions.Logging.Console/src/Microsoft.Extensions.Logging.Console.csproj @@ -26,6 +26,7 @@ + From 881c00227fc71f90f15608f79219eaac4d13b9cb Mon Sep 17 00:00:00 2001 From: Maryam Ariyan Date: Fri, 15 May 2020 08:05:17 -0700 Subject: [PATCH 05/15] TODO - make custom autoselect when just AddLogFormatter - make API renames: ConsoleLogFormatterX - const string on XFormatter.Name rather than getter - overall perf check - perf on compact and json (just for demo now) --- .../Microsoft.Extensions.Logging.Console.cs | 17 +- .../src/ConsoleLoggerProcessor.cs | 11 +- .../src/Formatter/CompactLogFormatter.cs | 203 ++++-------------- .../src/Formatter/DefaultLogFormatter.cs | 36 ++-- .../src/Formatter/JsonLogFormatter.cs | 16 +- .../src/Formatter/SystemdLogFormatter.cs | 11 +- .../src/LogMessageEntry.cs | 31 +-- 7 files changed, 90 insertions(+), 235 deletions(-) diff --git a/src/libraries/Microsoft.Extensions.Logging.Console/ref/Microsoft.Extensions.Logging.Console.cs b/src/libraries/Microsoft.Extensions.Logging.Console/ref/Microsoft.Extensions.Logging.Console.cs index 7f18c6484d0a76..fcabc69c8463ab 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Console/ref/Microsoft.Extensions.Logging.Console.cs +++ b/src/libraries/Microsoft.Extensions.Logging.Console/ref/Microsoft.Extensions.Logging.Console.cs @@ -45,6 +45,13 @@ public ConsoleLoggerProvider(Microsoft.Extensions.Options.IOptionsMonitor options) { } @@ -96,15 +103,9 @@ public JsonLogFormatterOptions() { } } public readonly partial struct LogMessageEntry { - public readonly System.ConsoleColor? LevelBackground; - public readonly System.ConsoleColor? LevelForeground; - public readonly string LevelString; public readonly bool LogAsError; - public readonly string Message; - public readonly System.ConsoleColor? MessageColor; - public readonly string TimeStamp; - public readonly System.Action WriteCallback; - public LogMessageEntry(string message, string timeStamp = null, string levelString = null, System.ConsoleColor? levelBackground = default(System.ConsoleColor?), System.ConsoleColor? levelForeground = default(System.ConsoleColor?), System.ConsoleColor? messageColor = default(System.ConsoleColor?), bool logAsError = false, System.Action writeCallback = null) { throw null; } + public readonly Microsoft.Extensions.Logging.Console.ConsoleMessage[] Messages; + public LogMessageEntry(Microsoft.Extensions.Logging.Console.ConsoleMessage[] messages, bool logAsError = false) { throw null; } } public partial class SystemdLogFormatter : Microsoft.Extensions.Logging.Console.ILogFormatter, System.IDisposable { diff --git a/src/libraries/Microsoft.Extensions.Logging.Console/src/ConsoleLoggerProcessor.cs b/src/libraries/Microsoft.Extensions.Logging.Console/src/ConsoleLoggerProcessor.cs index 9234b7dcced882..ae7434a2fcb695 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Console/src/ConsoleLoggerProcessor.cs +++ b/src/libraries/Microsoft.Extensions.Logging.Console/src/ConsoleLoggerProcessor.cs @@ -50,11 +50,14 @@ public virtual void EnqueueMessage(LogMessageEntry message) } // for testing - internal virtual void WriteMessage(LogMessageEntry message) + internal virtual void WriteMessage(LogMessageEntry entry) { - var console = message.LogAsError ? ErrorConsole : Console; - // is giving user control on this thread over how long the output thread takes to write to console - something to consider - message.WriteCallback(console); + var console = entry.LogAsError ? ErrorConsole : Console; + foreach (var message in entry.Messages) + { + console.Write(message.Content, message.Background, message.Foreground); + } + console.Flush(); } private void ProcessLogQueue() diff --git a/src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/CompactLogFormatter.cs b/src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/CompactLogFormatter.cs index 3edb59af209329..e5c38ec9201f4d 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/CompactLogFormatter.cs +++ b/src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/CompactLogFormatter.cs @@ -21,9 +21,6 @@ internal class CompactLogFormatter : ILogFormatter, IDisposable // ConsoleColor does not have a value to specify the 'Default' color private readonly ConsoleColor? DefaultConsoleColor = null; - [ThreadStatic] - private static StringBuilder _logBuilder; - static CompactLogFormatter() { var logLevelString = GetLogLevelString(LogLevel.Information); @@ -69,41 +66,36 @@ public LogMessageEntry Format(LogLevel logLevel, string logName, int eventId, st private LogMessageEntry FormatHelper(LogLevel logLevel, string logName, int eventId, string message, Exception exception, IExternalScopeProvider scopeProvider, TState scope) { - List msgs = new List(); - // todo fix later: - var logBuilder = _logBuilder; - _logBuilder = null; - - if (logBuilder == null) - { - logBuilder = new StringBuilder(); - } - - // Example: - // INFO: ConsoleApp.Program[10] - // Request received + var messages = new List(); var logLevelColors = GetLogLevelConsoleColors(logLevel); var logLevelString = GetLogLevelString(logLevel); - // category and event id - logBuilder.Append(_loglevelPadding); - logBuilder.Append(logName); - logBuilder.Append("["); - logBuilder.Append(eventId); - logBuilder.Append("]"); - // logBuilder.AppendLine("]"); - msgs.Add(new Message($"{logName}[{eventId}] ", null, null)); + string timestamp = null; + var timestampFormat = FormatterOptions.TimestampFormat; + if (timestampFormat != null) + { + var dateTime = GetCurrentDateTime(); + timestamp = dateTime.ToString(timestampFormat); + } + if (timestamp != null) + { + messages.Add(new ConsoleMessage(timestamp + " ", null, null)); + } + if (logLevelString != null) + { + messages.Add(new ConsoleMessage(logLevelString,logLevelColors.Background, logLevelColors.Foreground)); + } + + messages.Add(new ConsoleMessage($"{logName}[{eventId}] ", null, null)); string originalFormat = null; int count = 0; if (scope != null) { - logBuilder.Append(_messagePadding); if (scope is IReadOnlyList> kvpsx) { var strings = new List>(); - logBuilder.Append(" -> "); foreach (var kvp in kvpsx) { if (kvp.Key.Contains("{OriginalFormat}")) @@ -112,10 +104,7 @@ private LogMessageEntry FormatHelper(LogLevel logLevel, string logName, } else { - //count++; strings.Add(kvp); - logBuilder.Append(kvp.Value.ToString()); - logBuilder.Append(", "); } } int prevIndex = 0; @@ -129,13 +118,10 @@ private LogMessageEntry FormatHelper(LogLevel logLevel, string logName, if (curIndex != -1) { var curString = originalFormat.Substring(prevIndex, curIndex - prevIndex); - msgs.Add(new Message(curString, null, null)); - msgs.Add(new Message(strings.ElementAt(count).Value.ToString(), null, ConsoleColor.Cyan)); + messages.Add(new ConsoleMessage(curString, null, null)); + messages.Add(new ConsoleMessage(strings.ElementAt(count).Value.ToString(), null, ConsoleColor.Cyan)); prevIndex += curIndex + strings.ElementAt(count).Key.Length + 2; count++; - //strings.Add(kvp.Value.ToString()); - logBuilder.Append(kvp.Value.ToString()); - logBuilder.Append(", "); } } } @@ -144,7 +130,6 @@ private LogMessageEntry FormatHelper(LogLevel logLevel, string logName, else if (scope is IReadOnlyList> kvps) { var strings = new List>(); - logBuilder.Append(" -> "); foreach (var kvp in kvps) { if (kvp.Key.Contains("{OriginalFormat}")) @@ -153,10 +138,7 @@ private LogMessageEntry FormatHelper(LogLevel logLevel, string logName, } else { - //count++; strings.Add(kvp); - logBuilder.Append(kvp.Value); - logBuilder.Append(", "); } } int prevIndex = 0; @@ -170,142 +152,46 @@ private LogMessageEntry FormatHelper(LogLevel logLevel, string logName, if (curIndex != -1) { var curString = originalFormat.Substring(prevIndex, curIndex - prevIndex); - msgs.Add(new Message(curString, null, null)); - msgs.Add(new Message(strings.ElementAt(count).Value, null, ConsoleColor.Cyan)); + messages.Add(new ConsoleMessage(curString, null, null)); + messages.Add(new ConsoleMessage(strings.ElementAt(count).Value, null, ConsoleColor.Cyan)); prevIndex += curIndex + strings.ElementAt(count).Key.Length + 2; count++; - logBuilder.Append(kvp.Value); - logBuilder.Append(", "); } } } } } - else - { - logBuilder.Append("-> "); - logBuilder.Append(scope.ToString()); - } } if (!string.IsNullOrEmpty(message)) { - // message - logBuilder.Append(_messagePadding); - - var len = logBuilder.Length; - logBuilder.AppendLine(message); if (originalFormat == null) { - msgs.Add(new Message(message, null, null)); + messages.Add(new ConsoleMessage(message, null, null)); } else if (count == 0) { - msgs.Add(new Message(originalFormat, null, null)); + messages.Add(new ConsoleMessage(originalFormat, null, null)); } } - // scope information - msgs.Add(new Message(" ", null, null)); - GetScopeInformation(logBuilder, scopeProvider, msgs); + messages.Add(new ConsoleMessage(" ", null, null)); + GetScopeInformation(scopeProvider, messages); - // Example: - // System.InvalidOperationException - // at Namespace.Class.Function() in File:line X if (exception != null) { // exception message - logBuilder.Append(exception.ToString()); - msgs.Add(new Message(" ", null, null)); - msgs.Add(new Message(exception.ToString(), null, null)); - // logBuilder.AppendLine(exception.ToString()); - } - - string timestamp = null; - var timestampFormat = FormatterOptions.TimestampFormat; - if (timestampFormat != null) - { - var dateTime = GetCurrentDateTime(); - timestamp = dateTime.ToString(timestampFormat); + messages.Add(new ConsoleMessage(" ", null, null)); + messages.Add(new ConsoleMessage(exception.ToString(), null, null)); + // TODO: confirm exception message all in one line? } - var formattedMessage = logBuilder.ToString(); - logBuilder.Clear(); - if (logBuilder.Capacity > 1024) - { - logBuilder.Capacity = 1024; - } - _logBuilder = logBuilder; - return new LogMessageEntry( - message: formattedMessage, - timeStamp: timestamp, - levelString: logLevelString, - levelBackground: logLevelColors.Background, - levelForeground: logLevelColors.Foreground, - messageColor: DefaultConsoleColor, - logAsError: logLevel >= FormatterOptions.LogToStandardErrorThreshold, - writeCallback : console => - { - if (timestamp != null || logLevelString != null) - { - console.Write("[", null, null); - - if (timestamp != null) - { - console.Write(timestamp, null, null); - console.Write(" ", null, null); - } - if (logLevelString != null) - { - console.Write(logLevelString, logLevelColors.Background, logLevelColors.Foreground); - console.Write("", null, null); - } - console.Write("] ", null, null); - } - - if (msgs.Count > 0) - { - foreach (var item in msgs) - { - console.Write(item.Content, item.Background, item.Foreground); - } - } - - //console.Write(formattedMessage, DefaultConsoleColor, DefaultConsoleColor); - console.WriteLine(string.Empty, DefaultConsoleColor, DefaultConsoleColor); - console.Flush(); - } + messages: messages.ToArray(), + logAsError: logLevel >= FormatterOptions.LogToStandardErrorThreshold ); } - internal struct LogEntry - { - internal LogEntry(Action action, Message[] messages, bool logAsError) - { - Messages = messages; - WriteCallback = action; - LogAsError = logAsError; - } - - internal Message[] Messages; - internal Action WriteCallback; - internal bool LogAsError; - } - - internal struct Message - { - internal Message(string message, ConsoleColor? background, ConsoleColor? foreground) - { - Content = message; - Background = background; - Foreground = foreground; - } - internal string Content; - internal ConsoleColor? Background; - internal ConsoleColor? Foreground; - } - private DateTime GetCurrentDateTime() { return FormatterOptions.UseUtcTimestamp ? DateTime.UtcNow : DateTime.Now; @@ -360,34 +246,17 @@ private ConsoleColors GetLogLevelConsoleColors(LogLevel logLevel) } } - private void GetScopeInformation(StringBuilder stringBuilder, IExternalScopeProvider scopeProvider, List msgs) + private void GetScopeInformation(IExternalScopeProvider scopeProvider, List messages) { if (FormatterOptions.IncludeScopes && scopeProvider != null) { - var initialLength = stringBuilder.Length; - scopeProvider.ForEachScope((scope, state) => { - var (builder, paddAt, messages) = state; - var padd = paddAt == builder.Length; - if (padd) - { - //messages.Add(new Message(_messagePadding, null, null)); - builder.Append(_messagePadding); - } - messages.Add(new Message("=> ", null, null)); - messages.Add(new Message(scope.ToString(), null, ConsoleColor.DarkGray)); - messages.Add(new Message(" ", null, null)); - builder.Append("=> "); - builder.Append(scope); - builder.Append(" "); - - }, (stringBuilder, initialLength, msgs)); + state.Add(new ConsoleMessage("=> ", null, null)); + state.Add(new ConsoleMessage(scope.ToString(), null, ConsoleColor.DarkGray)); + state.Add(new ConsoleMessage(" ", null, null)); - if (stringBuilder.Length > initialLength) - { - // stringBuilder.AppendLine(); - } + }, messages); } } diff --git a/src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/DefaultLogFormatter.cs b/src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/DefaultLogFormatter.cs index bf311fe2143f87..c6f73fc7c880b4 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/DefaultLogFormatter.cs +++ b/src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/DefaultLogFormatter.cs @@ -4,6 +4,7 @@ using System; using System.Text; +using System.Collections.Generic; using Microsoft.Extensions.Options; namespace Microsoft.Extensions.Logging.Console @@ -119,30 +120,21 @@ public LogMessageEntry Format(LogLevel logLevel, string logName, int eventId, st logBuilder.Capacity = 1024; } _logBuilder = logBuilder; + + var messages = new List(); + if (timestamp != null) + { + messages.Add(new ConsoleMessage(timestamp, DefaultConsoleColor, DefaultConsoleColor)); + } + if (logLevelString != null) + { + messages.Add(new ConsoleMessage(logLevelString, logLevelColors.Background, logLevelColors.Foreground)); + } + messages.Add(new ConsoleMessage(formattedMessage, DefaultConsoleColor, DefaultConsoleColor)); return new LogMessageEntry( - message: formattedMessage, - timeStamp: timestamp, - levelString: logLevelString, - levelBackground: logLevelColors.Background, - levelForeground: logLevelColors.Foreground, - messageColor: DefaultConsoleColor, - logAsError: logLevel >= FormatterOptions.LogToStandardErrorThreshold, - writeCallback : console => - { - if (timestamp != null) - { - console.Write(timestamp, DefaultConsoleColor, DefaultConsoleColor); - } - - if (logLevelString != null) - { - console.Write(logLevelString, logLevelColors.Background, logLevelColors.Foreground); - } - - console.Write(formattedMessage, DefaultConsoleColor, DefaultConsoleColor); - console.Flush(); - } + messages: messages.ToArray(), + logAsError: logLevel >= FormatterOptions.LogToStandardErrorThreshold ); } diff --git a/src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/JsonLogFormatter.cs b/src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/JsonLogFormatter.cs index 4cb5f916bc2e8d..fe0e48c6fa5d53 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/JsonLogFormatter.cs +++ b/src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/JsonLogFormatter.cs @@ -115,20 +115,12 @@ public LogMessageEntry Format(LogLevel logLevel, string logName, int eventId, st logBuilder.Capacity = 1024; } _logBuilder = logBuilder; + + var messages = new ConsoleMessage[1] { new ConsoleMessage(formattedMessage, null, null) }; return new LogMessageEntry( - message: formattedMessage, -// timeStamp: timestamp, -// levelString: logLevelString, - levelBackground: null, - levelForeground: null, - messageColor: null, - logAsError: logLevel >= FormatterOptions.LogToStandardErrorThreshold, - writeCallback: console => - { - console.WriteLine(formattedMessage, null, null); - console.Flush(); - } + messages: messages, + logAsError: logLevel >= FormatterOptions.LogToStandardErrorThreshold ); } diff --git a/src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/SystemdLogFormatter.cs b/src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/SystemdLogFormatter.cs index 6b141f86992cac..6b7f5cfb792cf6 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/SystemdLogFormatter.cs +++ b/src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/SystemdLogFormatter.cs @@ -119,15 +119,12 @@ public LogMessageEntry Format(LogLevel logLevel, string logName, int eventId, st logBuilder.Capacity = 1024; } _logBuilder = logBuilder; + + var messages = new ConsoleMessage[1] { new ConsoleMessage(formattedMessage, null, null) }; return new LogMessageEntry( - message: formattedMessage, - logAsError: logLevel >= FormatterOptions.LogToStandardErrorThreshold, - writeCallback : console => - { - console.Write(formattedMessage, null, null); - console.Flush(); - } + messages: messages, + logAsError: logLevel >= FormatterOptions.LogToStandardErrorThreshold ); static void AppendAndReplaceNewLine(StringBuilder sb, string message) diff --git a/src/libraries/Microsoft.Extensions.Logging.Console/src/LogMessageEntry.cs b/src/libraries/Microsoft.Extensions.Logging.Console/src/LogMessageEntry.cs index ad57f9480e8866..d58f3fb5417992 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Console/src/LogMessageEntry.cs +++ b/src/libraries/Microsoft.Extensions.Logging.Console/src/LogMessageEntry.cs @@ -8,25 +8,26 @@ namespace Microsoft.Extensions.Logging.Console { public readonly struct LogMessageEntry { - public LogMessageEntry(string message, string timeStamp = null, string levelString = null, ConsoleColor? levelBackground = null, ConsoleColor? levelForeground = null, ConsoleColor? messageColor = null, bool logAsError = false, Action writeCallback = null) + public LogMessageEntry(ConsoleMessage[] messages, bool logAsError = false) { - TimeStamp = timeStamp; - LevelString = levelString; - LevelBackground = levelBackground; - LevelForeground = levelForeground; - MessageColor = messageColor; - Message = message; + Messages = messages; LogAsError = logAsError; - WriteCallback = writeCallback; } - public readonly string TimeStamp; - public readonly string LevelString; - public readonly ConsoleColor? LevelBackground; - public readonly ConsoleColor? LevelForeground; - public readonly ConsoleColor? MessageColor; - public readonly string Message; + public readonly ConsoleMessage[] Messages; public readonly bool LogAsError; - public readonly Action WriteCallback; + } + + public readonly struct ConsoleMessage + { + public ConsoleMessage(string message, ConsoleColor? background = null, ConsoleColor? foreground = null) + { + Content = message; + Background = background; + Foreground = foreground; + } + public readonly string Content; + public readonly ConsoleColor? Background; + public readonly ConsoleColor? Foreground; } } From fb74d57d9d15355495bf3af5cea1e4b26c9509e8 Mon Sep 17 00:00:00 2001 From: Maryam Ariyan Date: Fri, 15 May 2020 08:23:35 -0700 Subject: [PATCH 06/15] Rename to XConsoleLog... --- .../Microsoft.Extensions.Logging.Console.cs | 44 ++++++++----------- .../src/ConsoleLogger.cs | 2 +- .../src/ConsoleLoggerFactoryExtensions.cs | 22 +++++----- .../src/ConsoleLoggerProvider.cs | 10 ++--- .../src/Formatter/CompactLogFormatter.cs | 2 +- ...atter.cs => DefaultConsoleLogFormatter.cs} | 10 ++--- ...s => DefaultConsoleLogFormatterOptions.cs} | 4 +- ...ogFormatter.cs => IConsoleLogFormatter.cs} | 2 +- ...ormatter.cs => JsonConsoleLogFormatter.cs} | 8 ++-- ...s.cs => JsonConsoleLogFormatterOptions.cs} | 4 +- ...atter.cs => SystemdConsoleLogFormatter.cs} | 10 ++--- ...s => SystemdConsoleLogFormatterOptions.cs} | 4 +- .../src/IConsole.cs | 2 +- 13 files changed, 59 insertions(+), 65 deletions(-) rename src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/{DefaultLogFormatter.cs => DefaultConsoleLogFormatter.cs} (95%) rename src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/{DefaultLogFormatterOptions.cs => DefaultConsoleLogFormatterOptions.cs} (92%) rename src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/{ILogFormatter.cs => IConsoleLogFormatter.cs} (94%) rename src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/{JsonLogFormatter.cs => JsonConsoleLogFormatter.cs} (95%) rename src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/{JsonLogFormatterOptions.cs => JsonConsoleLogFormatterOptions.cs} (92%) rename src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/{SystemdLogFormatter.cs => SystemdConsoleLogFormatter.cs} (94%) rename src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/{SystemdLogFormatterOptions.cs => SystemdConsoleLogFormatterOptions.cs} (91%) diff --git a/src/libraries/Microsoft.Extensions.Logging.Console/ref/Microsoft.Extensions.Logging.Console.cs b/src/libraries/Microsoft.Extensions.Logging.Console/ref/Microsoft.Extensions.Logging.Console.cs index fcabc69c8463ab..50b7d5854a7f6c 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Console/ref/Microsoft.Extensions.Logging.Console.cs +++ b/src/libraries/Microsoft.Extensions.Logging.Console/ref/Microsoft.Extensions.Logging.Console.cs @@ -11,8 +11,8 @@ public static partial class ConsoleLoggerExtensions { public static Microsoft.Extensions.Logging.ILoggingBuilder AddConsole(this Microsoft.Extensions.Logging.ILoggingBuilder builder) { throw null; } public static Microsoft.Extensions.Logging.ILoggingBuilder AddConsole(this Microsoft.Extensions.Logging.ILoggingBuilder builder, System.Action configure) { throw null; } - public static Microsoft.Extensions.Logging.ILoggingBuilder AddLogFormatter(this Microsoft.Extensions.Logging.ILoggingBuilder builder) where TFormatter : class, Microsoft.Extensions.Logging.Console.ILogFormatter where TOptions : class { throw null; } - public static Microsoft.Extensions.Logging.ILoggingBuilder AddLogFormatter(this Microsoft.Extensions.Logging.ILoggingBuilder builder, System.Action configure) where TFormatter : class, Microsoft.Extensions.Logging.Console.ILogFormatter where TOptions : class { throw null; } + public static Microsoft.Extensions.Logging.ILoggingBuilder AddConsoleLogFormatter(this Microsoft.Extensions.Logging.ILoggingBuilder builder) where TFormatter : class, Microsoft.Extensions.Logging.Console.IConsoleLogFormatter where TOptions : class { throw null; } + public static Microsoft.Extensions.Logging.ILoggingBuilder AddConsoleLogFormatter(this Microsoft.Extensions.Logging.ILoggingBuilder builder, System.Action configure) where TFormatter : class, Microsoft.Extensions.Logging.Console.IConsoleLogFormatter where TOptions : class { throw null; } } } namespace Microsoft.Extensions.Logging.Console @@ -40,7 +40,7 @@ public ConsoleLoggerOptions() { } [Microsoft.Extensions.Logging.ProviderAliasAttribute("Console")] public partial class ConsoleLoggerProvider : Microsoft.Extensions.Logging.ILoggerProvider, Microsoft.Extensions.Logging.ISupportExternalScope, System.IDisposable { - public ConsoleLoggerProvider(Microsoft.Extensions.Options.IOptionsMonitor options, System.Collections.Generic.IEnumerable formatters) { } + public ConsoleLoggerProvider(Microsoft.Extensions.Options.IOptionsMonitor options, System.Collections.Generic.IEnumerable formatters) { } public Microsoft.Extensions.Logging.ILogger CreateLogger(string name) { throw null; } public void Dispose() { } public void SetScopeProvider(Microsoft.Extensions.Logging.IExternalScopeProvider scopeProvider) { } @@ -52,48 +52,42 @@ public readonly partial struct ConsoleMessage public readonly System.ConsoleColor? Foreground; public ConsoleMessage(string message, System.ConsoleColor? background = default(System.ConsoleColor?), System.ConsoleColor? foreground = default(System.ConsoleColor?)) { throw null; } } - public partial class DefaultLogFormatter : Microsoft.Extensions.Logging.Console.ILogFormatter, System.IDisposable + public partial class DefaultConsoleLogFormatter : Microsoft.Extensions.Logging.Console.IConsoleLogFormatter, System.IDisposable { - public DefaultLogFormatter(Microsoft.Extensions.Options.IOptionsMonitor options) { } - public Microsoft.Extensions.Logging.Console.DefaultLogFormatterOptions FormatterOptions { get { throw null; } set { } } + public DefaultConsoleLogFormatter(Microsoft.Extensions.Options.IOptionsMonitor options) { } + public Microsoft.Extensions.Logging.Console.DefaultConsoleLogFormatterOptions FormatterOptions { get { throw null; } set { } } public string Name { get { throw null; } } public void Dispose() { } public Microsoft.Extensions.Logging.Console.LogMessageEntry Format(Microsoft.Extensions.Logging.LogLevel logLevel, string logName, int eventId, string message, System.Exception exception, Microsoft.Extensions.Logging.IExternalScopeProvider scopeProvider) { throw null; } public Microsoft.Extensions.Logging.Console.LogMessageEntry Format(Microsoft.Extensions.Logging.LogLevel logLevel, string logName, int eventId, TState state, System.Exception exception, System.Func formatter, Microsoft.Extensions.Logging.IExternalScopeProvider scopeProvider) { throw null; } } - public partial class DefaultLogFormatterOptions + public partial class DefaultConsoleLogFormatterOptions { - public DefaultLogFormatterOptions() { } + public DefaultConsoleLogFormatterOptions() { } public bool DisableColors { get { throw null; } set { } } public bool IncludeScopes { get { throw null; } set { } } public Microsoft.Extensions.Logging.LogLevel LogToStandardErrorThreshold { get { throw null; } set { } } public string TimestampFormat { get { throw null; } set { } } public bool UseUtcTimestamp { get { throw null; } set { } } } - public partial interface IConsole - { - void Flush(); - void Write(string message, System.ConsoleColor? background, System.ConsoleColor? foreground); - void WriteLine(string message, System.ConsoleColor? background, System.ConsoleColor? foreground); - } - public partial interface ILogFormatter + public partial interface IConsoleLogFormatter { string Name { get; } Microsoft.Extensions.Logging.Console.LogMessageEntry Format(Microsoft.Extensions.Logging.LogLevel logLevel, string logName, int eventId, string message, System.Exception exception, Microsoft.Extensions.Logging.IExternalScopeProvider scopeProvider); Microsoft.Extensions.Logging.Console.LogMessageEntry Format(Microsoft.Extensions.Logging.LogLevel logLevel, string logName, int eventId, TState state, System.Exception exception, System.Func formatter, Microsoft.Extensions.Logging.IExternalScopeProvider scopeProvider); } - public partial class JsonConsoleLogFormatter : Microsoft.Extensions.Logging.Console.ILogFormatter, System.IDisposable + public partial class JsonConsoleLogFormatter : Microsoft.Extensions.Logging.Console.IConsoleLogFormatter, System.IDisposable { - public JsonConsoleLogFormatter(Microsoft.Extensions.Options.IOptionsMonitor options) { } - public Microsoft.Extensions.Logging.Console.JsonLogFormatterOptions FormatterOptions { get { throw null; } set { } } + public JsonConsoleLogFormatter(Microsoft.Extensions.Options.IOptionsMonitor options) { } + public Microsoft.Extensions.Logging.Console.JsonConsoleLogFormatterOptions FormatterOptions { get { throw null; } set { } } public string Name { get { throw null; } } public void Dispose() { } public Microsoft.Extensions.Logging.Console.LogMessageEntry Format(Microsoft.Extensions.Logging.LogLevel logLevel, string logName, int eventId, string message, System.Exception exception, Microsoft.Extensions.Logging.IExternalScopeProvider scopeProvider) { throw null; } public Microsoft.Extensions.Logging.Console.LogMessageEntry Format(Microsoft.Extensions.Logging.LogLevel logLevel, string logName, int eventId, TState state, System.Exception exception, System.Func formatter, Microsoft.Extensions.Logging.IExternalScopeProvider scopeProvider) { throw null; } } - public partial class JsonLogFormatterOptions + public partial class JsonConsoleLogFormatterOptions { - public JsonLogFormatterOptions() { } + public JsonConsoleLogFormatterOptions() { } public bool IncludeScopes { get { throw null; } set { } } public System.Text.Json.JsonSerializerOptions JsonSerializerOptions { get { throw null; } set { } } public System.Text.Json.JsonWriterOptions JsonWriterOptions { get { throw null; } set { } } @@ -107,18 +101,18 @@ public readonly partial struct LogMessageEntry public readonly Microsoft.Extensions.Logging.Console.ConsoleMessage[] Messages; public LogMessageEntry(Microsoft.Extensions.Logging.Console.ConsoleMessage[] messages, bool logAsError = false) { throw null; } } - public partial class SystemdLogFormatter : Microsoft.Extensions.Logging.Console.ILogFormatter, System.IDisposable + public partial class SystemdConsoleLogFormatter : Microsoft.Extensions.Logging.Console.IConsoleLogFormatter, System.IDisposable { - public SystemdLogFormatter(Microsoft.Extensions.Options.IOptionsMonitor options) { } - public Microsoft.Extensions.Logging.Console.SystemdLogFormatterOptions FormatterOptions { get { throw null; } set { } } + public SystemdConsoleLogFormatter(Microsoft.Extensions.Options.IOptionsMonitor options) { } + public Microsoft.Extensions.Logging.Console.SystemdConsoleLogFormatterOptions FormatterOptions { get { throw null; } set { } } public string Name { get { throw null; } } public void Dispose() { } public Microsoft.Extensions.Logging.Console.LogMessageEntry Format(Microsoft.Extensions.Logging.LogLevel logLevel, string logName, int eventId, string message, System.Exception exception, Microsoft.Extensions.Logging.IExternalScopeProvider scopeProvider) { throw null; } public Microsoft.Extensions.Logging.Console.LogMessageEntry Format(Microsoft.Extensions.Logging.LogLevel logLevel, string logName, int eventId, TState state, System.Exception exception, System.Func formatter, Microsoft.Extensions.Logging.IExternalScopeProvider scopeProvider) { throw null; } } - public partial class SystemdLogFormatterOptions + public partial class SystemdConsoleLogFormatterOptions { - public SystemdLogFormatterOptions() { } + public SystemdConsoleLogFormatterOptions() { } public bool IncludeScopes { get { throw null; } set { } } public Microsoft.Extensions.Logging.LogLevel LogToStandardErrorThreshold { get { throw null; } set { } } public string TimestampFormat { get { throw null; } set { } } diff --git a/src/libraries/Microsoft.Extensions.Logging.Console/src/ConsoleLogger.cs b/src/libraries/Microsoft.Extensions.Logging.Console/src/ConsoleLogger.cs index 7215e3439dd905..1311f0325a054f 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Console/src/ConsoleLogger.cs +++ b/src/libraries/Microsoft.Extensions.Logging.Console/src/ConsoleLogger.cs @@ -29,7 +29,7 @@ internal ConsoleLogger(string name, ConsoleLoggerProcessor loggerProcessor) internal IExternalScopeProvider ScopeProvider { get; set; } - internal ILogFormatter Formatter { get; set; } + internal IConsoleLogFormatter Formatter { get; set; } public void Log(LogLevel logLevel, EventId eventId, TState state, Exception exception, Func formatter) { diff --git a/src/libraries/Microsoft.Extensions.Logging.Console/src/ConsoleLoggerFactoryExtensions.cs b/src/libraries/Microsoft.Extensions.Logging.Console/src/ConsoleLoggerFactoryExtensions.cs index 22c92ec3308dc6..83c7a527712736 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Console/src/ConsoleLoggerFactoryExtensions.cs +++ b/src/libraries/Microsoft.Extensions.Logging.Console/src/ConsoleLoggerFactoryExtensions.cs @@ -29,10 +29,10 @@ public static ILoggingBuilder AddConsole(this ILoggingBuilder builder) { builder.AddConfiguration(); - builder.AddLogFormatter(); - builder.AddLogFormatter(); - builder.AddLogFormatter(); - builder.AddLogFormatter(); + builder.AddConsoleLogFormatter(); + builder.AddConsoleLogFormatter(); + builder.AddConsoleLogFormatter(); + builder.AddConsoleLogFormatter(); builder.Services.TryAddEnumerable(ServiceDescriptor.Singleton()); LoggerProviderOptions.RegisterProviderOptions(builder.Services); @@ -58,13 +58,13 @@ public static ILoggingBuilder AddConsole(this ILoggingBuilder builder, Action(this ILoggingBuilder builder) + public static ILoggingBuilder AddConsoleLogFormatter(this ILoggingBuilder builder) where TOptions : class - where TFormatter : class, ILogFormatter + where TFormatter : class, IConsoleLogFormatter { builder.AddConfiguration(); - builder.Services.TryAddEnumerable(ServiceDescriptor.Singleton()); + builder.Services.TryAddEnumerable(ServiceDescriptor.Singleton()); builder.Services.AddSingleton, LogFormatterOptionsSetup>(); builder.Services.AddSingleton, LoggerProviderOptionsChangeTokenSource>(); @@ -77,16 +77,16 @@ public static ILoggingBuilder AddLogFormatter(this ILoggin return builder; } - public static ILoggingBuilder AddLogFormatter(this ILoggingBuilder builder, Action configure) + public static ILoggingBuilder AddConsoleLogFormatter(this ILoggingBuilder builder, Action configure) where TOptions : class - where TFormatter : class, ILogFormatter + where TFormatter : class, IConsoleLogFormatter { if (configure == null) { throw new ArgumentNullException(nameof(configure)); } - builder.AddLogFormatter(); + builder.AddConsoleLogFormatter(); builder.Services.Configure(configure); @@ -96,7 +96,7 @@ public static ILoggingBuilder AddLogFormatter(this ILoggin internal class LogFormatterOptionsSetup : ConfigureFromConfigurationOptions where TOptions : class - where TFormatter : class, ILogFormatter + where TFormatter : class, IConsoleLogFormatter { public LogFormatterOptionsSetup(ILoggerProviderConfiguration providerConfiguration) : base(providerConfiguration.Configuration) diff --git a/src/libraries/Microsoft.Extensions.Logging.Console/src/ConsoleLoggerProvider.cs b/src/libraries/Microsoft.Extensions.Logging.Console/src/ConsoleLoggerProvider.cs index 65ce2d92f895f6..406f5bd29fe8fa 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Console/src/ConsoleLoggerProvider.cs +++ b/src/libraries/Microsoft.Extensions.Logging.Console/src/ConsoleLoggerProvider.cs @@ -19,7 +19,7 @@ public class ConsoleLoggerProvider : ILoggerProvider, ISupportExternalScope { private readonly IOptionsMonitor _options; private readonly ConcurrentDictionary _loggers; - private readonly ConcurrentDictionary _formatters; + private readonly ConcurrentDictionary _formatters; private readonly ConsoleLoggerProcessor _messageQueue; private IDisposable _optionsReloadToken; @@ -30,11 +30,11 @@ public class ConsoleLoggerProvider : ILoggerProvider, ISupportExternalScope /// /// The options to create instances with. /// - public ConsoleLoggerProvider(IOptionsMonitor options, IEnumerable formatters) + public ConsoleLoggerProvider(IOptionsMonitor options, IEnumerable formatters) { _options = options; _loggers = new ConcurrentDictionary(); - _formatters = new ConcurrentDictionary(formatters.ToDictionary(f => f.Name)); + _formatters = new ConcurrentDictionary(formatters.ToDictionary(f => f.Name)); ReloadLoggerOptions(options.CurrentValue); _optionsReloadToken = _options.OnChange(ReloadLoggerOptions); @@ -56,7 +56,7 @@ public ConsoleLoggerProvider(IOptionsMonitor options, IEnu private void ReloadLoggerOptions(ConsoleLoggerOptions options) { string nameFromFormat = Enum.GetName(typeof(ConsoleLoggerFormat), options?.Format); - _formatters.TryGetValue(options?.Formatter ?? nameFromFormat, out ILogFormatter logFormatter); + _formatters.TryGetValue(options?.Formatter ?? nameFromFormat, out IConsoleLogFormatter logFormatter); if (logFormatter == null) { logFormatter = _formatters[nameFromFormat]; @@ -72,7 +72,7 @@ private void ReloadLoggerOptions(ConsoleLoggerOptions options) public ILogger CreateLogger(string name) { string nameFromFormat = Enum.GetName(typeof(ConsoleLoggerFormat), _options.CurrentValue.Format); - _formatters.TryGetValue(_options.CurrentValue.Formatter ?? nameFromFormat, out ILogFormatter logFormatter); + _formatters.TryGetValue(_options.CurrentValue.Formatter ?? nameFromFormat, out IConsoleLogFormatter logFormatter); if (logFormatter == null) { logFormatter = _formatters[nameFromFormat]; diff --git a/src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/CompactLogFormatter.cs b/src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/CompactLogFormatter.cs index e5c38ec9201f4d..ec717a0c2a107d 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/CompactLogFormatter.cs +++ b/src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/CompactLogFormatter.cs @@ -11,7 +11,7 @@ namespace Microsoft.Extensions.Logging.Console { - internal class CompactLogFormatter : ILogFormatter, IDisposable + internal class CompactLogFormatter : IConsoleLogFormatter, IDisposable { private IDisposable _optionsReloadToken; private static readonly string _loglevelPadding = ": "; diff --git a/src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/DefaultLogFormatter.cs b/src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/DefaultConsoleLogFormatter.cs similarity index 95% rename from src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/DefaultLogFormatter.cs rename to src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/DefaultConsoleLogFormatter.cs index c6f73fc7c880b4..aa7647183693f4 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/DefaultLogFormatter.cs +++ b/src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/DefaultConsoleLogFormatter.cs @@ -9,7 +9,7 @@ namespace Microsoft.Extensions.Logging.Console { - public class DefaultLogFormatter : ILogFormatter, IDisposable + public class DefaultConsoleLogFormatter : IConsoleLogFormatter, IDisposable { private static readonly string _loglevelPadding = ": "; private static readonly string _messagePadding; @@ -22,21 +22,21 @@ public class DefaultLogFormatter : ILogFormatter, IDisposable [ThreadStatic] private static StringBuilder _logBuilder; - static DefaultLogFormatter() + static DefaultConsoleLogFormatter() { var logLevelString = GetLogLevelString(LogLevel.Information); _messagePadding = new string(' ', logLevelString.Length + _loglevelPadding.Length); _newLineWithMessagePadding = Environment.NewLine + _messagePadding; } - public DefaultLogFormatter(IOptionsMonitor options) + public DefaultConsoleLogFormatter(IOptionsMonitor options) { FormatterOptions = options.CurrentValue; ReloadLoggerOptions(options.CurrentValue); _optionsReloadToken = options.OnChange(ReloadLoggerOptions); } - private void ReloadLoggerOptions(DefaultLogFormatterOptions options) + private void ReloadLoggerOptions(DefaultConsoleLogFormatterOptions options) { FormatterOptions = options; } @@ -48,7 +48,7 @@ public void Dispose() public string Name => "Default"; - public DefaultLogFormatterOptions FormatterOptions { get; set; } + public DefaultConsoleLogFormatterOptions FormatterOptions { get; set; } public LogMessageEntry Format(LogLevel logLevel, string logName, int eventId, TState state, Exception exception, Func formatter, IExternalScopeProvider scopeProvider) { diff --git a/src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/DefaultLogFormatterOptions.cs b/src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/DefaultConsoleLogFormatterOptions.cs similarity index 92% rename from src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/DefaultLogFormatterOptions.cs rename to src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/DefaultConsoleLogFormatterOptions.cs index 0da31ccdf8830b..5524a869545560 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/DefaultLogFormatterOptions.cs +++ b/src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/DefaultConsoleLogFormatterOptions.cs @@ -8,9 +8,9 @@ namespace Microsoft.Extensions.Logging.Console { - public class DefaultLogFormatterOptions + public class DefaultConsoleLogFormatterOptions { - public DefaultLogFormatterOptions() { } + public DefaultConsoleLogFormatterOptions() { } /// /// Includes scopes when . diff --git a/src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/ILogFormatter.cs b/src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/IConsoleLogFormatter.cs similarity index 94% rename from src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/ILogFormatter.cs rename to src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/IConsoleLogFormatter.cs index 3ef81d3c350faa..ea768ec77c8d9c 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/ILogFormatter.cs +++ b/src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/IConsoleLogFormatter.cs @@ -6,7 +6,7 @@ namespace Microsoft.Extensions.Logging.Console { - public interface ILogFormatter + public interface IConsoleLogFormatter { string Name { get; } LogMessageEntry Format(LogLevel logLevel, string logName, int eventId, string message, Exception exception, IExternalScopeProvider scopeProvider); diff --git a/src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/JsonLogFormatter.cs b/src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/JsonConsoleLogFormatter.cs similarity index 95% rename from src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/JsonLogFormatter.cs rename to src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/JsonConsoleLogFormatter.cs index fe0e48c6fa5d53..b86bcf1b4c5ccd 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/JsonLogFormatter.cs +++ b/src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/JsonConsoleLogFormatter.cs @@ -21,14 +21,14 @@ namespace Microsoft.Extensions.Logging.Console { - public class JsonConsoleLogFormatter : ILogFormatter, IDisposable + public class JsonConsoleLogFormatter : IConsoleLogFormatter, IDisposable { private IDisposable _optionsReloadToken; [ThreadStatic] private static StringBuilder _logBuilder; - public JsonConsoleLogFormatter(IOptionsMonitor options) + public JsonConsoleLogFormatter(IOptionsMonitor options) { FormatterOptions = options.CurrentValue; ReloadLoggerOptions(options.CurrentValue); @@ -187,9 +187,9 @@ private void GetScopeInformation(Utf8JsonWriter writer, IExternalScopeProvider s } } - public JsonLogFormatterOptions FormatterOptions { get; set; } + public JsonConsoleLogFormatterOptions FormatterOptions { get; set; } - private void ReloadLoggerOptions(JsonLogFormatterOptions options) + private void ReloadLoggerOptions(JsonConsoleLogFormatterOptions options) { FormatterOptions = options; } diff --git a/src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/JsonLogFormatterOptions.cs b/src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/JsonConsoleLogFormatterOptions.cs similarity index 92% rename from src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/JsonLogFormatterOptions.cs rename to src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/JsonConsoleLogFormatterOptions.cs index 7a79a068584554..b8f6c72144495c 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/JsonLogFormatterOptions.cs +++ b/src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/JsonConsoleLogFormatterOptions.cs @@ -8,9 +8,9 @@ namespace Microsoft.Extensions.Logging.Console { - public class JsonLogFormatterOptions + public class JsonConsoleLogFormatterOptions { - public JsonLogFormatterOptions() { } + public JsonConsoleLogFormatterOptions() { } public JsonWriterOptions JsonWriterOptions { get; set; } public JsonSerializerOptions JsonSerializerOptions { get; set; } diff --git a/src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/SystemdLogFormatter.cs b/src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/SystemdConsoleLogFormatter.cs similarity index 94% rename from src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/SystemdLogFormatter.cs rename to src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/SystemdConsoleLogFormatter.cs index 6b7f5cfb792cf6..1ec6651b77c0d2 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/SystemdLogFormatter.cs +++ b/src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/SystemdConsoleLogFormatter.cs @@ -8,7 +8,7 @@ namespace Microsoft.Extensions.Logging.Console { - public class SystemdLogFormatter : ILogFormatter, IDisposable + public class SystemdConsoleLogFormatter : IConsoleLogFormatter, IDisposable { private IDisposable _optionsReloadToken; @@ -18,20 +18,20 @@ public class SystemdLogFormatter : ILogFormatter, IDisposable [ThreadStatic] private static StringBuilder _logBuilder; - static SystemdLogFormatter() + static SystemdConsoleLogFormatter() { var logLevelString = GetSyslogSeverityString(LogLevel.Information); _messagePadding = new string(' ', logLevelString.Length + _loglevelPadding.Length); } - public SystemdLogFormatter(IOptionsMonitor options) + public SystemdConsoleLogFormatter(IOptionsMonitor options) { FormatterOptions = options.CurrentValue; ReloadLoggerOptions(options.CurrentValue); _optionsReloadToken = options.OnChange(ReloadLoggerOptions); } - private void ReloadLoggerOptions(SystemdLogFormatterOptions options) + private void ReloadLoggerOptions(SystemdConsoleLogFormatterOptions options) { FormatterOptions = options; } @@ -43,7 +43,7 @@ public void Dispose() public string Name => "Systemd"; - public SystemdLogFormatterOptions FormatterOptions { get; set; } + public SystemdConsoleLogFormatterOptions FormatterOptions { get; set; } public LogMessageEntry Format(LogLevel logLevel, string logName, int eventId, TState state, Exception exception, Func formatter, IExternalScopeProvider scopeProvider) { diff --git a/src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/SystemdLogFormatterOptions.cs b/src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/SystemdConsoleLogFormatterOptions.cs similarity index 91% rename from src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/SystemdLogFormatterOptions.cs rename to src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/SystemdConsoleLogFormatterOptions.cs index f207d2f8be4d6a..5bc28892dc085e 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/SystemdLogFormatterOptions.cs +++ b/src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/SystemdConsoleLogFormatterOptions.cs @@ -7,9 +7,9 @@ namespace Microsoft.Extensions.Logging.Console { - public class SystemdLogFormatterOptions + public class SystemdConsoleLogFormatterOptions { - public SystemdLogFormatterOptions() { } + public SystemdConsoleLogFormatterOptions() { } /// /// Includes scopes when . diff --git a/src/libraries/Microsoft.Extensions.Logging.Console/src/IConsole.cs b/src/libraries/Microsoft.Extensions.Logging.Console/src/IConsole.cs index 88500ecf16f374..a9975b0105b17f 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Console/src/IConsole.cs +++ b/src/libraries/Microsoft.Extensions.Logging.Console/src/IConsole.cs @@ -6,7 +6,7 @@ namespace Microsoft.Extensions.Logging.Console { - public interface IConsole + internal interface IConsole { void Write(string message, ConsoleColor? background, ConsoleColor? foreground); void WriteLine(string message, ConsoleColor? background, ConsoleColor? foreground); From 0499b0a065338d2f3a36827dcd9abe55c5c6e2bf Mon Sep 17 00:00:00 2001 From: Maryam Ariyan Date: Fri, 15 May 2020 09:51:02 -0700 Subject: [PATCH 07/15] FormatterNames const not instance properties --- .../ref/Microsoft.Extensions.Logging.Console.cs | 7 +++++++ .../src/ConsoleLoggerFactoryExtensions.cs | 2 +- .../src/Formatter/CompactLogFormatter.cs | 5 +++-- .../src/Formatter/ConsoleFormatterConstants.cs | 14 ++++++++++++++ .../src/Formatter/DefaultConsoleLogFormatter.cs | 2 +- .../src/Formatter/JsonConsoleLogFormatter.cs | 7 +++++-- .../src/Formatter/SystemdConsoleLogFormatter.cs | 2 +- 7 files changed, 32 insertions(+), 7 deletions(-) create mode 100644 src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/ConsoleFormatterConstants.cs diff --git a/src/libraries/Microsoft.Extensions.Logging.Console/ref/Microsoft.Extensions.Logging.Console.cs b/src/libraries/Microsoft.Extensions.Logging.Console/ref/Microsoft.Extensions.Logging.Console.cs index 50b7d5854a7f6c..a70972d9fbedcf 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Console/ref/Microsoft.Extensions.Logging.Console.cs +++ b/src/libraries/Microsoft.Extensions.Logging.Console/ref/Microsoft.Extensions.Logging.Console.cs @@ -26,6 +26,13 @@ public CompactLogFormatterOptions() { } public string TimestampFormat { get { throw null; } set { } } public bool UseUtcTimestamp { get { throw null; } set { } } } + public static partial class ConsoleLogFormatterNames + { + public const string Compact = "Compact"; + public const string Default = "Default"; + public const string Json = "Json"; + public const string Systemd = "Systemd"; + } public enum ConsoleLoggerFormat { Default = 0, diff --git a/src/libraries/Microsoft.Extensions.Logging.Console/src/ConsoleLoggerFactoryExtensions.cs b/src/libraries/Microsoft.Extensions.Logging.Console/src/ConsoleLoggerFactoryExtensions.cs index 83c7a527712736..93db3435a31ade 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Console/src/ConsoleLoggerFactoryExtensions.cs +++ b/src/libraries/Microsoft.Extensions.Logging.Console/src/ConsoleLoggerFactoryExtensions.cs @@ -30,9 +30,9 @@ public static ILoggingBuilder AddConsole(this ILoggingBuilder builder) builder.AddConfiguration(); builder.AddConsoleLogFormatter(); - builder.AddConsoleLogFormatter(); builder.AddConsoleLogFormatter(); builder.AddConsoleLogFormatter(); + builder.AddConsoleLogFormatter(); builder.Services.TryAddEnumerable(ServiceDescriptor.Singleton()); LoggerProviderOptions.RegisterProviderOptions(builder.Services); diff --git a/src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/CompactLogFormatter.cs b/src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/CompactLogFormatter.cs index ec717a0c2a107d..5cda9720a4dced 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/CompactLogFormatter.cs +++ b/src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/CompactLogFormatter.cs @@ -47,7 +47,7 @@ public void Dispose() public CompactLogFormatterOptions FormatterOptions { get; set; } - public string Name => "Compact"; + public string Name => ConsoleLogFormatterNames.Compact; public LogMessageEntry Format(LogLevel logLevel, string logName, int eventId, TState state, Exception exception, Func formatter, IExternalScopeProvider scopeProvider) { @@ -84,7 +84,7 @@ private LogMessageEntry FormatHelper(LogLevel logLevel, string logName, } if (logLevelString != null) { - messages.Add(new ConsoleMessage(logLevelString,logLevelColors.Background, logLevelColors.Foreground)); + messages.Add(new ConsoleMessage(logLevelString + " ", logLevelColors.Background, logLevelColors.Foreground)); } messages.Add(new ConsoleMessage($"{logName}[{eventId}] ", null, null)); @@ -185,6 +185,7 @@ private LogMessageEntry FormatHelper(LogLevel logLevel, string logName, messages.Add(new ConsoleMessage(exception.ToString(), null, null)); // TODO: confirm exception message all in one line? } + messages.Add(new ConsoleMessage(Environment.NewLine, null, null)); return new LogMessageEntry( messages: messages.ToArray(), diff --git a/src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/ConsoleFormatterConstants.cs b/src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/ConsoleFormatterConstants.cs new file mode 100644 index 00000000000000..c094a5e3ec0228 --- /dev/null +++ b/src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/ConsoleFormatterConstants.cs @@ -0,0 +1,14 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +namespace Microsoft.Extensions.Logging.Console +{ + public static class ConsoleLogFormatterNames + { + public const string Compact = nameof(Compact); + public const string Default = nameof(Default); + public const string Json = nameof(Json); + public const string Systemd = nameof(Systemd); + } +} diff --git a/src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/DefaultConsoleLogFormatter.cs b/src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/DefaultConsoleLogFormatter.cs index aa7647183693f4..a7eb46d422d871 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/DefaultConsoleLogFormatter.cs +++ b/src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/DefaultConsoleLogFormatter.cs @@ -46,7 +46,7 @@ public void Dispose() _optionsReloadToken?.Dispose(); } - public string Name => "Default"; + public string Name => ConsoleLogFormatterNames.Default; public DefaultConsoleLogFormatterOptions FormatterOptions { get; set; } diff --git a/src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/JsonConsoleLogFormatter.cs b/src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/JsonConsoleLogFormatter.cs index b86bcf1b4c5ccd..87b040eb3875ed 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/JsonConsoleLogFormatter.cs +++ b/src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/JsonConsoleLogFormatter.cs @@ -35,7 +35,7 @@ public JsonConsoleLogFormatter(IOptionsMonitor o _optionsReloadToken = options.OnChange(ReloadLoggerOptions); } - public string Name => "Json"; + public string Name => ConsoleLogFormatterNames.Json; private string WriteJson(LogLevel logLevel, string logName, int eventId, string message, Exception exception, IExternalScopeProvider scopeProvider)//long[] extraData) { @@ -116,7 +116,10 @@ public LogMessageEntry Format(LogLevel logLevel, string logName, int eventId, st } _logBuilder = logBuilder; - var messages = new ConsoleMessage[1] { new ConsoleMessage(formattedMessage, null, null) }; + var messages = new ConsoleMessage[2] { + new ConsoleMessage(formattedMessage, null, null), + new ConsoleMessage(Environment.NewLine, null, null) + }; return new LogMessageEntry( messages: messages, diff --git a/src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/SystemdConsoleLogFormatter.cs b/src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/SystemdConsoleLogFormatter.cs index 1ec6651b77c0d2..d46ef253003e47 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/SystemdConsoleLogFormatter.cs +++ b/src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/SystemdConsoleLogFormatter.cs @@ -41,7 +41,7 @@ public void Dispose() _optionsReloadToken?.Dispose(); } - public string Name => "Systemd"; + public string Name => ConsoleLogFormatterNames.Systemd; public SystemdConsoleLogFormatterOptions FormatterOptions { get; set; } From 805d6e2a078886afa1942a9273a43e3b3a995d4f Mon Sep 17 00:00:00 2001 From: Maryam Ariyan Date: Fri, 15 May 2020 10:02:06 -0700 Subject: [PATCH 08/15] add AddCompact and other helpers --- .../Microsoft.Extensions.Logging.Console.cs | 31 ++--------- .../src/ConsoleLoggerFactoryExtensions.cs | 52 +++++++++++++++++++ .../Formatter/DefaultConsoleLogFormatter.cs | 2 +- .../src/Formatter/JsonConsoleLogFormatter.cs | 2 +- .../Formatter/SystemdConsoleLogFormatter.cs | 2 +- 5 files changed, 59 insertions(+), 30 deletions(-) diff --git a/src/libraries/Microsoft.Extensions.Logging.Console/ref/Microsoft.Extensions.Logging.Console.cs b/src/libraries/Microsoft.Extensions.Logging.Console/ref/Microsoft.Extensions.Logging.Console.cs index a70972d9fbedcf..c03f6c52c60252 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Console/ref/Microsoft.Extensions.Logging.Console.cs +++ b/src/libraries/Microsoft.Extensions.Logging.Console/ref/Microsoft.Extensions.Logging.Console.cs @@ -9,10 +9,14 @@ namespace Microsoft.Extensions.Logging { public static partial class ConsoleLoggerExtensions { + public static Microsoft.Extensions.Logging.ILoggingBuilder AddCompactConsoleLogFormatter(this Microsoft.Extensions.Logging.ILoggingBuilder builder, System.Action configure) { throw null; } public static Microsoft.Extensions.Logging.ILoggingBuilder AddConsole(this Microsoft.Extensions.Logging.ILoggingBuilder builder) { throw null; } public static Microsoft.Extensions.Logging.ILoggingBuilder AddConsole(this Microsoft.Extensions.Logging.ILoggingBuilder builder, System.Action configure) { throw null; } public static Microsoft.Extensions.Logging.ILoggingBuilder AddConsoleLogFormatter(this Microsoft.Extensions.Logging.ILoggingBuilder builder) where TFormatter : class, Microsoft.Extensions.Logging.Console.IConsoleLogFormatter where TOptions : class { throw null; } public static Microsoft.Extensions.Logging.ILoggingBuilder AddConsoleLogFormatter(this Microsoft.Extensions.Logging.ILoggingBuilder builder, System.Action configure) where TFormatter : class, Microsoft.Extensions.Logging.Console.IConsoleLogFormatter where TOptions : class { throw null; } + public static Microsoft.Extensions.Logging.ILoggingBuilder AddDefaultConsoleLogFormatter(this Microsoft.Extensions.Logging.ILoggingBuilder builder, System.Action configure) { throw null; } + public static Microsoft.Extensions.Logging.ILoggingBuilder AddJsonConsoleLogFormatter(this Microsoft.Extensions.Logging.ILoggingBuilder builder, System.Action configure) { throw null; } + public static Microsoft.Extensions.Logging.ILoggingBuilder AddSystemdConsoleLogFormatter(this Microsoft.Extensions.Logging.ILoggingBuilder builder, System.Action configure) { throw null; } } } namespace Microsoft.Extensions.Logging.Console @@ -59,15 +63,6 @@ public readonly partial struct ConsoleMessage public readonly System.ConsoleColor? Foreground; public ConsoleMessage(string message, System.ConsoleColor? background = default(System.ConsoleColor?), System.ConsoleColor? foreground = default(System.ConsoleColor?)) { throw null; } } - public partial class DefaultConsoleLogFormatter : Microsoft.Extensions.Logging.Console.IConsoleLogFormatter, System.IDisposable - { - public DefaultConsoleLogFormatter(Microsoft.Extensions.Options.IOptionsMonitor options) { } - public Microsoft.Extensions.Logging.Console.DefaultConsoleLogFormatterOptions FormatterOptions { get { throw null; } set { } } - public string Name { get { throw null; } } - public void Dispose() { } - public Microsoft.Extensions.Logging.Console.LogMessageEntry Format(Microsoft.Extensions.Logging.LogLevel logLevel, string logName, int eventId, string message, System.Exception exception, Microsoft.Extensions.Logging.IExternalScopeProvider scopeProvider) { throw null; } - public Microsoft.Extensions.Logging.Console.LogMessageEntry Format(Microsoft.Extensions.Logging.LogLevel logLevel, string logName, int eventId, TState state, System.Exception exception, System.Func formatter, Microsoft.Extensions.Logging.IExternalScopeProvider scopeProvider) { throw null; } - } public partial class DefaultConsoleLogFormatterOptions { public DefaultConsoleLogFormatterOptions() { } @@ -83,15 +78,6 @@ public partial interface IConsoleLogFormatter Microsoft.Extensions.Logging.Console.LogMessageEntry Format(Microsoft.Extensions.Logging.LogLevel logLevel, string logName, int eventId, string message, System.Exception exception, Microsoft.Extensions.Logging.IExternalScopeProvider scopeProvider); Microsoft.Extensions.Logging.Console.LogMessageEntry Format(Microsoft.Extensions.Logging.LogLevel logLevel, string logName, int eventId, TState state, System.Exception exception, System.Func formatter, Microsoft.Extensions.Logging.IExternalScopeProvider scopeProvider); } - public partial class JsonConsoleLogFormatter : Microsoft.Extensions.Logging.Console.IConsoleLogFormatter, System.IDisposable - { - public JsonConsoleLogFormatter(Microsoft.Extensions.Options.IOptionsMonitor options) { } - public Microsoft.Extensions.Logging.Console.JsonConsoleLogFormatterOptions FormatterOptions { get { throw null; } set { } } - public string Name { get { throw null; } } - public void Dispose() { } - public Microsoft.Extensions.Logging.Console.LogMessageEntry Format(Microsoft.Extensions.Logging.LogLevel logLevel, string logName, int eventId, string message, System.Exception exception, Microsoft.Extensions.Logging.IExternalScopeProvider scopeProvider) { throw null; } - public Microsoft.Extensions.Logging.Console.LogMessageEntry Format(Microsoft.Extensions.Logging.LogLevel logLevel, string logName, int eventId, TState state, System.Exception exception, System.Func formatter, Microsoft.Extensions.Logging.IExternalScopeProvider scopeProvider) { throw null; } - } public partial class JsonConsoleLogFormatterOptions { public JsonConsoleLogFormatterOptions() { } @@ -108,15 +94,6 @@ public readonly partial struct LogMessageEntry public readonly Microsoft.Extensions.Logging.Console.ConsoleMessage[] Messages; public LogMessageEntry(Microsoft.Extensions.Logging.Console.ConsoleMessage[] messages, bool logAsError = false) { throw null; } } - public partial class SystemdConsoleLogFormatter : Microsoft.Extensions.Logging.Console.IConsoleLogFormatter, System.IDisposable - { - public SystemdConsoleLogFormatter(Microsoft.Extensions.Options.IOptionsMonitor options) { } - public Microsoft.Extensions.Logging.Console.SystemdConsoleLogFormatterOptions FormatterOptions { get { throw null; } set { } } - public string Name { get { throw null; } } - public void Dispose() { } - public Microsoft.Extensions.Logging.Console.LogMessageEntry Format(Microsoft.Extensions.Logging.LogLevel logLevel, string logName, int eventId, string message, System.Exception exception, Microsoft.Extensions.Logging.IExternalScopeProvider scopeProvider) { throw null; } - public Microsoft.Extensions.Logging.Console.LogMessageEntry Format(Microsoft.Extensions.Logging.LogLevel logLevel, string logName, int eventId, TState state, System.Exception exception, System.Func formatter, Microsoft.Extensions.Logging.IExternalScopeProvider scopeProvider) { throw null; } - } public partial class SystemdConsoleLogFormatterOptions { public SystemdConsoleLogFormatterOptions() { } diff --git a/src/libraries/Microsoft.Extensions.Logging.Console/src/ConsoleLoggerFactoryExtensions.cs b/src/libraries/Microsoft.Extensions.Logging.Console/src/ConsoleLoggerFactoryExtensions.cs index 93db3435a31ade..99b97b540014df 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Console/src/ConsoleLoggerFactoryExtensions.cs +++ b/src/libraries/Microsoft.Extensions.Logging.Console/src/ConsoleLoggerFactoryExtensions.cs @@ -57,6 +57,58 @@ public static ILoggingBuilder AddConsole(this ILoggingBuilder builder, Action configure) + { + if (configure == null) + { + throw new ArgumentNullException(nameof(configure)); + } + + builder.AddConsole(); + builder.Services.Configure(configure); + + return builder; + } + + public static ILoggingBuilder AddDefaultConsoleLogFormatter(this ILoggingBuilder builder, Action configure) + { + if (configure == null) + { + throw new ArgumentNullException(nameof(configure)); + } + + builder.AddConsole(); + builder.Services.Configure(configure); + + return builder; + } + + public static ILoggingBuilder AddJsonConsoleLogFormatter(this ILoggingBuilder builder, Action configure) + { + if (configure == null) + { + throw new ArgumentNullException(nameof(configure)); + } + + builder.AddConsole(); + builder.Services.Configure(configure); + + return builder; + } + + public static ILoggingBuilder AddSystemdConsoleLogFormatter(this ILoggingBuilder builder, Action configure) + { + if (configure == null) + { + throw new ArgumentNullException(nameof(configure)); + } + + builder.AddConsole(); + builder.Services.Configure(configure); + + return builder; + } public static ILoggingBuilder AddConsoleLogFormatter(this ILoggingBuilder builder) where TOptions : class diff --git a/src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/DefaultConsoleLogFormatter.cs b/src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/DefaultConsoleLogFormatter.cs index a7eb46d422d871..5d6383d5001596 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/DefaultConsoleLogFormatter.cs +++ b/src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/DefaultConsoleLogFormatter.cs @@ -9,7 +9,7 @@ namespace Microsoft.Extensions.Logging.Console { - public class DefaultConsoleLogFormatter : IConsoleLogFormatter, IDisposable + internal class DefaultConsoleLogFormatter : IConsoleLogFormatter, IDisposable { private static readonly string _loglevelPadding = ": "; private static readonly string _messagePadding; diff --git a/src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/JsonConsoleLogFormatter.cs b/src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/JsonConsoleLogFormatter.cs index 87b040eb3875ed..e91775ce3d837d 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/JsonConsoleLogFormatter.cs +++ b/src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/JsonConsoleLogFormatter.cs @@ -21,7 +21,7 @@ namespace Microsoft.Extensions.Logging.Console { - public class JsonConsoleLogFormatter : IConsoleLogFormatter, IDisposable + internal class JsonConsoleLogFormatter : IConsoleLogFormatter, IDisposable { private IDisposable _optionsReloadToken; diff --git a/src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/SystemdConsoleLogFormatter.cs b/src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/SystemdConsoleLogFormatter.cs index d46ef253003e47..6bddc6baa8cce1 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/SystemdConsoleLogFormatter.cs +++ b/src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/SystemdConsoleLogFormatter.cs @@ -8,7 +8,7 @@ namespace Microsoft.Extensions.Logging.Console { - public class SystemdConsoleLogFormatter : IConsoleLogFormatter, IDisposable + internal class SystemdConsoleLogFormatter : IConsoleLogFormatter, IDisposable { private IDisposable _optionsReloadToken; From 36b7a24d0ec1e7beda9d7ca0f3d7bb3fed45b79a Mon Sep 17 00:00:00 2001 From: Maryam Ariyan Date: Fri, 15 May 2020 10:21:23 -0700 Subject: [PATCH 09/15] Rename AddCompactFormatter for short? --- .../ref/Microsoft.Extensions.Logging.Console.cs | 8 ++++---- .../src/ConsoleLoggerFactoryExtensions.cs | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/libraries/Microsoft.Extensions.Logging.Console/ref/Microsoft.Extensions.Logging.Console.cs b/src/libraries/Microsoft.Extensions.Logging.Console/ref/Microsoft.Extensions.Logging.Console.cs index c03f6c52c60252..3ecdc48b1ee2e5 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Console/ref/Microsoft.Extensions.Logging.Console.cs +++ b/src/libraries/Microsoft.Extensions.Logging.Console/ref/Microsoft.Extensions.Logging.Console.cs @@ -9,14 +9,14 @@ namespace Microsoft.Extensions.Logging { public static partial class ConsoleLoggerExtensions { - public static Microsoft.Extensions.Logging.ILoggingBuilder AddCompactConsoleLogFormatter(this Microsoft.Extensions.Logging.ILoggingBuilder builder, System.Action configure) { throw null; } + public static Microsoft.Extensions.Logging.ILoggingBuilder AddCompactFormatter(this Microsoft.Extensions.Logging.ILoggingBuilder builder, System.Action configure) { throw null; } public static Microsoft.Extensions.Logging.ILoggingBuilder AddConsole(this Microsoft.Extensions.Logging.ILoggingBuilder builder) { throw null; } public static Microsoft.Extensions.Logging.ILoggingBuilder AddConsole(this Microsoft.Extensions.Logging.ILoggingBuilder builder, System.Action configure) { throw null; } public static Microsoft.Extensions.Logging.ILoggingBuilder AddConsoleLogFormatter(this Microsoft.Extensions.Logging.ILoggingBuilder builder) where TFormatter : class, Microsoft.Extensions.Logging.Console.IConsoleLogFormatter where TOptions : class { throw null; } public static Microsoft.Extensions.Logging.ILoggingBuilder AddConsoleLogFormatter(this Microsoft.Extensions.Logging.ILoggingBuilder builder, System.Action configure) where TFormatter : class, Microsoft.Extensions.Logging.Console.IConsoleLogFormatter where TOptions : class { throw null; } - public static Microsoft.Extensions.Logging.ILoggingBuilder AddDefaultConsoleLogFormatter(this Microsoft.Extensions.Logging.ILoggingBuilder builder, System.Action configure) { throw null; } - public static Microsoft.Extensions.Logging.ILoggingBuilder AddJsonConsoleLogFormatter(this Microsoft.Extensions.Logging.ILoggingBuilder builder, System.Action configure) { throw null; } - public static Microsoft.Extensions.Logging.ILoggingBuilder AddSystemdConsoleLogFormatter(this Microsoft.Extensions.Logging.ILoggingBuilder builder, System.Action configure) { throw null; } + public static Microsoft.Extensions.Logging.ILoggingBuilder AddDefaultFormatter(this Microsoft.Extensions.Logging.ILoggingBuilder builder, System.Action configure) { throw null; } + public static Microsoft.Extensions.Logging.ILoggingBuilder AddJsonFormatter(this Microsoft.Extensions.Logging.ILoggingBuilder builder, System.Action configure) { throw null; } + public static Microsoft.Extensions.Logging.ILoggingBuilder AddSystemdFormatter(this Microsoft.Extensions.Logging.ILoggingBuilder builder, System.Action configure) { throw null; } } } namespace Microsoft.Extensions.Logging.Console diff --git a/src/libraries/Microsoft.Extensions.Logging.Console/src/ConsoleLoggerFactoryExtensions.cs b/src/libraries/Microsoft.Extensions.Logging.Console/src/ConsoleLoggerFactoryExtensions.cs index 99b97b540014df..f95a6d5f4dea91 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Console/src/ConsoleLoggerFactoryExtensions.cs +++ b/src/libraries/Microsoft.Extensions.Logging.Console/src/ConsoleLoggerFactoryExtensions.cs @@ -58,7 +58,7 @@ public static ILoggingBuilder AddConsole(this ILoggingBuilder builder, Action configure) + public static ILoggingBuilder AddCompactFormatter(this ILoggingBuilder builder, Action configure) { if (configure == null) { @@ -71,7 +71,7 @@ public static ILoggingBuilder AddCompactConsoleLogFormatter(this ILoggingBuilder return builder; } - public static ILoggingBuilder AddDefaultConsoleLogFormatter(this ILoggingBuilder builder, Action configure) + public static ILoggingBuilder AddDefaultFormatter(this ILoggingBuilder builder, Action configure) { if (configure == null) { @@ -84,7 +84,7 @@ public static ILoggingBuilder AddDefaultConsoleLogFormatter(this ILoggingBuilder return builder; } - public static ILoggingBuilder AddJsonConsoleLogFormatter(this ILoggingBuilder builder, Action configure) + public static ILoggingBuilder AddJsonFormatter(this ILoggingBuilder builder, Action configure) { if (configure == null) { @@ -97,7 +97,7 @@ public static ILoggingBuilder AddJsonConsoleLogFormatter(this ILoggingBuilder bu return builder; } - public static ILoggingBuilder AddSystemdConsoleLogFormatter(this ILoggingBuilder builder, Action configure) + public static ILoggingBuilder AddSystemdFormatter(this ILoggingBuilder builder, Action configure) { if (configure == null) { From d9b0c009533770ddf0aef719ca2ed476c0e191ee Mon Sep 17 00:00:00 2001 From: Maryam Ariyan Date: Thu, 21 May 2020 10:57:47 -0700 Subject: [PATCH 10/15] Revert "Rename AddCompactFormatter for short?" This reverts commit 36b7a24d0ec1e7beda9d7ca0f3d7bb3fed45b79a. --- .../ref/Microsoft.Extensions.Logging.Console.cs | 8 ++++---- .../src/ConsoleLoggerFactoryExtensions.cs | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/libraries/Microsoft.Extensions.Logging.Console/ref/Microsoft.Extensions.Logging.Console.cs b/src/libraries/Microsoft.Extensions.Logging.Console/ref/Microsoft.Extensions.Logging.Console.cs index 3ecdc48b1ee2e5..c03f6c52c60252 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Console/ref/Microsoft.Extensions.Logging.Console.cs +++ b/src/libraries/Microsoft.Extensions.Logging.Console/ref/Microsoft.Extensions.Logging.Console.cs @@ -9,14 +9,14 @@ namespace Microsoft.Extensions.Logging { public static partial class ConsoleLoggerExtensions { - public static Microsoft.Extensions.Logging.ILoggingBuilder AddCompactFormatter(this Microsoft.Extensions.Logging.ILoggingBuilder builder, System.Action configure) { throw null; } + public static Microsoft.Extensions.Logging.ILoggingBuilder AddCompactConsoleLogFormatter(this Microsoft.Extensions.Logging.ILoggingBuilder builder, System.Action configure) { throw null; } public static Microsoft.Extensions.Logging.ILoggingBuilder AddConsole(this Microsoft.Extensions.Logging.ILoggingBuilder builder) { throw null; } public static Microsoft.Extensions.Logging.ILoggingBuilder AddConsole(this Microsoft.Extensions.Logging.ILoggingBuilder builder, System.Action configure) { throw null; } public static Microsoft.Extensions.Logging.ILoggingBuilder AddConsoleLogFormatter(this Microsoft.Extensions.Logging.ILoggingBuilder builder) where TFormatter : class, Microsoft.Extensions.Logging.Console.IConsoleLogFormatter where TOptions : class { throw null; } public static Microsoft.Extensions.Logging.ILoggingBuilder AddConsoleLogFormatter(this Microsoft.Extensions.Logging.ILoggingBuilder builder, System.Action configure) where TFormatter : class, Microsoft.Extensions.Logging.Console.IConsoleLogFormatter where TOptions : class { throw null; } - public static Microsoft.Extensions.Logging.ILoggingBuilder AddDefaultFormatter(this Microsoft.Extensions.Logging.ILoggingBuilder builder, System.Action configure) { throw null; } - public static Microsoft.Extensions.Logging.ILoggingBuilder AddJsonFormatter(this Microsoft.Extensions.Logging.ILoggingBuilder builder, System.Action configure) { throw null; } - public static Microsoft.Extensions.Logging.ILoggingBuilder AddSystemdFormatter(this Microsoft.Extensions.Logging.ILoggingBuilder builder, System.Action configure) { throw null; } + public static Microsoft.Extensions.Logging.ILoggingBuilder AddDefaultConsoleLogFormatter(this Microsoft.Extensions.Logging.ILoggingBuilder builder, System.Action configure) { throw null; } + public static Microsoft.Extensions.Logging.ILoggingBuilder AddJsonConsoleLogFormatter(this Microsoft.Extensions.Logging.ILoggingBuilder builder, System.Action configure) { throw null; } + public static Microsoft.Extensions.Logging.ILoggingBuilder AddSystemdConsoleLogFormatter(this Microsoft.Extensions.Logging.ILoggingBuilder builder, System.Action configure) { throw null; } } } namespace Microsoft.Extensions.Logging.Console diff --git a/src/libraries/Microsoft.Extensions.Logging.Console/src/ConsoleLoggerFactoryExtensions.cs b/src/libraries/Microsoft.Extensions.Logging.Console/src/ConsoleLoggerFactoryExtensions.cs index f95a6d5f4dea91..99b97b540014df 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Console/src/ConsoleLoggerFactoryExtensions.cs +++ b/src/libraries/Microsoft.Extensions.Logging.Console/src/ConsoleLoggerFactoryExtensions.cs @@ -58,7 +58,7 @@ public static ILoggingBuilder AddConsole(this ILoggingBuilder builder, Action configure) + public static ILoggingBuilder AddCompactConsoleLogFormatter(this ILoggingBuilder builder, Action configure) { if (configure == null) { @@ -71,7 +71,7 @@ public static ILoggingBuilder AddCompactFormatter(this ILoggingBuilder builder, return builder; } - public static ILoggingBuilder AddDefaultFormatter(this ILoggingBuilder builder, Action configure) + public static ILoggingBuilder AddDefaultConsoleLogFormatter(this ILoggingBuilder builder, Action configure) { if (configure == null) { @@ -84,7 +84,7 @@ public static ILoggingBuilder AddDefaultFormatter(this ILoggingBuilder builder, return builder; } - public static ILoggingBuilder AddJsonFormatter(this ILoggingBuilder builder, Action configure) + public static ILoggingBuilder AddJsonConsoleLogFormatter(this ILoggingBuilder builder, Action configure) { if (configure == null) { @@ -97,7 +97,7 @@ public static ILoggingBuilder AddJsonFormatter(this ILoggingBuilder builder, Act return builder; } - public static ILoggingBuilder AddSystemdFormatter(this ILoggingBuilder builder, Action configure) + public static ILoggingBuilder AddSystemdConsoleLogFormatter(this ILoggingBuilder builder, Action configure) { if (configure == null) { From 615f88aea06cff9da5c90b12c0c4ac43136e610f Mon Sep 17 00:00:00 2001 From: Maryam Ariyan Date: Thu, 21 May 2020 10:55:06 -0700 Subject: [PATCH 11/15] Add back deprecated APIs Move Options properties to common base class Only Keep IConsoleLogFormatter.Format --- .../Microsoft.Extensions.Logging.Console.cs | 39 +++++++++---------- .../src/ConsoleLogger.cs | 7 ---- .../src/ConsoleLoggerOptions.cs | 32 ++++++++++----- .../src/ConsoleLoggerProvider.cs | 24 +++++++++++- .../src/Formatter/CompactLogFormatter.cs | 14 ++++--- .../Formatter/CompactLogFormatterOptions.cs | 22 +---------- .../Formatter/DefaultConsoleLogFormatter.cs | 10 ++++- .../DefaultConsoleLogFormatterOptions.cs | 22 +---------- .../src/Formatter/IConsoleLogFormatter.cs | 2 +- .../src/Formatter/JsonConsoleLogFormatter.cs | 10 ++++- .../JsonConsoleLogFormatterOptions.cs | 22 +---------- .../Formatter/SystemdConsoleLogFormatter.cs | 10 ++++- .../SystemdConsoleLogFormatterOptions.cs | 22 +---------- 13 files changed, 103 insertions(+), 133 deletions(-) diff --git a/src/libraries/Microsoft.Extensions.Logging.Console/ref/Microsoft.Extensions.Logging.Console.cs b/src/libraries/Microsoft.Extensions.Logging.Console/ref/Microsoft.Extensions.Logging.Console.cs index c03f6c52c60252..40c7efb61f426b 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Console/ref/Microsoft.Extensions.Logging.Console.cs +++ b/src/libraries/Microsoft.Extensions.Logging.Console/ref/Microsoft.Extensions.Logging.Console.cs @@ -21,15 +21,19 @@ public static partial class ConsoleLoggerExtensions } namespace Microsoft.Extensions.Logging.Console { - public partial class CompactLogFormatterOptions + public abstract partial class BaseOptions { - public CompactLogFormatterOptions() { } - public bool DisableColors { get { throw null; } set { } } + protected BaseOptions() { } public bool IncludeScopes { get { throw null; } set { } } public Microsoft.Extensions.Logging.LogLevel LogToStandardErrorThreshold { get { throw null; } set { } } public string TimestampFormat { get { throw null; } set { } } public bool UseUtcTimestamp { get { throw null; } set { } } } + public partial class CompactLogFormatterOptions : Microsoft.Extensions.Logging.Console.BaseOptions + { + public CompactLogFormatterOptions() { } + public bool DisableColors { get { throw null; } set { } } + } public static partial class ConsoleLogFormatterNames { public const string Compact = "Compact"; @@ -42,15 +46,20 @@ public enum ConsoleLoggerFormat Default = 0, Systemd = 1, } - public partial class ConsoleLoggerOptions + public partial class ConsoleLoggerOptions : Microsoft.Extensions.Logging.Console.BaseOptions { public ConsoleLoggerOptions() { } + [System.ObsoleteAttribute("ConsoleLoggerOptions.DisableColors has been deprecated. Please use DefaultConsoleLogFormatterOptions.DisableColors instead.", false)] + public bool DisableColors { get { throw null; } set { } } + [System.ObsoleteAttribute("ConsoleLoggerOptions.Format has been deprecated. Please use ConsoleLoggerOptions.FormatterName instead.", false)] public Microsoft.Extensions.Logging.Console.ConsoleLoggerFormat Format { get { throw null; } set { } } - public string Formatter { get { throw null; } set { } } + public string FormatterName { get { throw null; } set { } } } [Microsoft.Extensions.Logging.ProviderAliasAttribute("Console")] public partial class ConsoleLoggerProvider : Microsoft.Extensions.Logging.ILoggerProvider, Microsoft.Extensions.Logging.ISupportExternalScope, System.IDisposable { + [System.ObsoleteAttribute("ConsoleLoggerProvider.ctor has been deprecated.", false)] + public ConsoleLoggerProvider(Microsoft.Extensions.Options.IOptionsMonitor options) { } public ConsoleLoggerProvider(Microsoft.Extensions.Options.IOptionsMonitor options, System.Collections.Generic.IEnumerable formatters) { } public Microsoft.Extensions.Logging.ILogger CreateLogger(string name) { throw null; } public void Dispose() { } @@ -63,30 +72,22 @@ public readonly partial struct ConsoleMessage public readonly System.ConsoleColor? Foreground; public ConsoleMessage(string message, System.ConsoleColor? background = default(System.ConsoleColor?), System.ConsoleColor? foreground = default(System.ConsoleColor?)) { throw null; } } - public partial class DefaultConsoleLogFormatterOptions + public partial class DefaultConsoleLogFormatterOptions : Microsoft.Extensions.Logging.Console.BaseOptions { public DefaultConsoleLogFormatterOptions() { } public bool DisableColors { get { throw null; } set { } } - public bool IncludeScopes { get { throw null; } set { } } - public Microsoft.Extensions.Logging.LogLevel LogToStandardErrorThreshold { get { throw null; } set { } } - public string TimestampFormat { get { throw null; } set { } } - public bool UseUtcTimestamp { get { throw null; } set { } } } public partial interface IConsoleLogFormatter { string Name { get; } - Microsoft.Extensions.Logging.Console.LogMessageEntry Format(Microsoft.Extensions.Logging.LogLevel logLevel, string logName, int eventId, string message, System.Exception exception, Microsoft.Extensions.Logging.IExternalScopeProvider scopeProvider); + BaseOptions Options { get; } Microsoft.Extensions.Logging.Console.LogMessageEntry Format(Microsoft.Extensions.Logging.LogLevel logLevel, string logName, int eventId, TState state, System.Exception exception, System.Func formatter, Microsoft.Extensions.Logging.IExternalScopeProvider scopeProvider); } - public partial class JsonConsoleLogFormatterOptions + public partial class JsonConsoleLogFormatterOptions : Microsoft.Extensions.Logging.Console.BaseOptions { public JsonConsoleLogFormatterOptions() { } - public bool IncludeScopes { get { throw null; } set { } } public System.Text.Json.JsonSerializerOptions JsonSerializerOptions { get { throw null; } set { } } public System.Text.Json.JsonWriterOptions JsonWriterOptions { get { throw null; } set { } } - public Microsoft.Extensions.Logging.LogLevel LogToStandardErrorThreshold { get { throw null; } set { } } - public string TimestampFormat { get { throw null; } set { } } - public bool UseUtcTimestamp { get { throw null; } set { } } } public readonly partial struct LogMessageEntry { @@ -94,12 +95,8 @@ public readonly partial struct LogMessageEntry public readonly Microsoft.Extensions.Logging.Console.ConsoleMessage[] Messages; public LogMessageEntry(Microsoft.Extensions.Logging.Console.ConsoleMessage[] messages, bool logAsError = false) { throw null; } } - public partial class SystemdConsoleLogFormatterOptions + public partial class SystemdConsoleLogFormatterOptions : Microsoft.Extensions.Logging.Console.BaseOptions { public SystemdConsoleLogFormatterOptions() { } - public bool IncludeScopes { get { throw null; } set { } } - public Microsoft.Extensions.Logging.LogLevel LogToStandardErrorThreshold { get { throw null; } set { } } - public string TimestampFormat { get { throw null; } set { } } - public bool UseUtcTimestamp { get { throw null; } set { } } } } diff --git a/src/libraries/Microsoft.Extensions.Logging.Console/src/ConsoleLogger.cs b/src/libraries/Microsoft.Extensions.Logging.Console/src/ConsoleLogger.cs index 1311f0325a054f..14620aadf64867 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Console/src/ConsoleLogger.cs +++ b/src/libraries/Microsoft.Extensions.Logging.Console/src/ConsoleLogger.cs @@ -51,13 +51,6 @@ public void Log(LogLevel logLevel, EventId eventId, TState state, Except } } - public virtual void WriteMessage(LogLevel logLevel, string logName, int eventId, string message, Exception exception) - { - var entry = Formatter.Format(logLevel, logName, eventId, message, exception, ScopeProvider); - _queueProcessor.EnqueueMessage(entry); - } - - public bool IsEnabled(LogLevel logLevel) { return logLevel != LogLevel.None; diff --git a/src/libraries/Microsoft.Extensions.Logging.Console/src/ConsoleLoggerOptions.cs b/src/libraries/Microsoft.Extensions.Logging.Console/src/ConsoleLoggerOptions.cs index f15a27fed40b04..10a2afda8c6855 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Console/src/ConsoleLoggerOptions.cs +++ b/src/libraries/Microsoft.Extensions.Logging.Console/src/ConsoleLoggerOptions.cs @@ -10,31 +10,32 @@ namespace Microsoft.Extensions.Logging.Console /// /// Options for a . /// - public class ConsoleLoggerOptions + public class ConsoleLoggerOptions : BaseOptions { + [System.ObsoleteAttribute("ConsoleLoggerOptions.DisableColors has been deprecated. Please use DefaultConsoleLogFormatterOptions.DisableColors instead.", false)] + public bool DisableColors { get; set; } + /// /// Gets or sets log message format. Defaults to . /// + [System.ObsoleteAttribute("ConsoleLoggerOptions.Format has been deprecated. Please use ConsoleLoggerOptions.FormatterName instead.", false)] public ConsoleLoggerFormat Format { get { - try { - return (ConsoleLoggerFormat) Enum.Parse(typeof(ConsoleLoggerFormat), Formatter); - } - catch (ArgumentException) { - return ConsoleLoggerFormat.Default; - } + if (FormatterName != null && FormatterName.Equals(ConsoleLogFormatterNames.Systemd, StringComparison.OrdinalIgnoreCase)) + return ConsoleLoggerFormat.Systemd; + return ConsoleLoggerFormat.Default; } set { if (value == ConsoleLoggerFormat.Systemd) { - Formatter = Enum.GetName(typeof(ConsoleLoggerFormat), ConsoleLoggerFormat.Systemd); + FormatterName = ConsoleLogFormatterNames.Systemd; } else { - Formatter = Enum.GetName(typeof(ConsoleLoggerFormat), ConsoleLoggerFormat.Default); + FormatterName = ConsoleLogFormatterNames.Default; } } } @@ -42,6 +43,17 @@ public ConsoleLoggerFormat Format /// /// /// - public string Formatter { get; set; } + public string FormatterName { get; set; } + } + + public abstract class BaseOptions + { + public bool IncludeScopes { get; set; } + + public Microsoft.Extensions.Logging.LogLevel LogToStandardErrorThreshold { get; set; } + + public string TimestampFormat { get; set; } + + public bool UseUtcTimestamp { get; set; } } } diff --git a/src/libraries/Microsoft.Extensions.Logging.Console/src/ConsoleLoggerProvider.cs b/src/libraries/Microsoft.Extensions.Logging.Console/src/ConsoleLoggerProvider.cs index 406f5bd29fe8fa..5895b835bad2a0 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Console/src/ConsoleLoggerProvider.cs +++ b/src/libraries/Microsoft.Extensions.Logging.Console/src/ConsoleLoggerProvider.cs @@ -25,6 +25,13 @@ public class ConsoleLoggerProvider : ILoggerProvider, ISupportExternalScope private IDisposable _optionsReloadToken; private IExternalScopeProvider _scopeProvider = NullExternalScopeProvider.Instance; + [System.ObsoleteAttribute("ConsoleLoggerProvider.ctor has been deprecated.", false)] + public ConsoleLoggerProvider(Microsoft.Extensions.Options.IOptionsMonitor options) + : this(options, Enumerable.Empty()) + { + ; // todo: check workflow. maybe we should always have 4 formatters prepped instead? + } + /// /// Creates an instance of . /// @@ -56,11 +63,12 @@ public ConsoleLoggerProvider(IOptionsMonitor options, IEnu private void ReloadLoggerOptions(ConsoleLoggerOptions options) { string nameFromFormat = Enum.GetName(typeof(ConsoleLoggerFormat), options?.Format); - _formatters.TryGetValue(options?.Formatter ?? nameFromFormat, out IConsoleLogFormatter logFormatter); + _formatters.TryGetValue(options?.FormatterName ?? nameFromFormat, out IConsoleLogFormatter logFormatter); if (logFormatter == null) { logFormatter = _formatters[nameFromFormat]; } + UpdateFormatterOptions(logFormatter, options); foreach (var logger in _loggers) { @@ -68,15 +76,27 @@ private void ReloadLoggerOptions(ConsoleLoggerOptions options) } } + private void UpdateFormatterOptions(IConsoleLogFormatter formatter, ConsoleLoggerOptions fromOptions) + { + formatter.Options.IncludeScopes = fromOptions.IncludeScopes; + formatter.Options.LogToStandardErrorThreshold = fromOptions.LogToStandardErrorThreshold; + formatter.Options.TimestampFormat = fromOptions.TimestampFormat; + formatter.Options.UseUtcTimestamp = fromOptions.UseUtcTimestamp; + // kept for deprecated api: + if (formatter is DefaultConsoleLogFormatter dFormatter) + dFormatter.FormatterOptions.DisableColors = fromOptions.DisableColors; + } + /// public ILogger CreateLogger(string name) { string nameFromFormat = Enum.GetName(typeof(ConsoleLoggerFormat), _options.CurrentValue.Format); - _formatters.TryGetValue(_options.CurrentValue.Formatter ?? nameFromFormat, out IConsoleLogFormatter logFormatter); + _formatters.TryGetValue(_options.CurrentValue.FormatterName ?? nameFromFormat, out IConsoleLogFormatter logFormatter); if (logFormatter == null) { logFormatter = _formatters[nameFromFormat]; } + UpdateFormatterOptions(logFormatter, _options.CurrentValue); return _loggers.GetOrAdd(name, loggerName => new ConsoleLogger(name, _messageQueue) { diff --git a/src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/CompactLogFormatter.cs b/src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/CompactLogFormatter.cs index 5cda9720a4dced..8a10e3e659f14e 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/CompactLogFormatter.cs +++ b/src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/CompactLogFormatter.cs @@ -45,6 +45,14 @@ public void Dispose() _optionsReloadToken?.Dispose(); } + public BaseOptions Options + { + get + { + return FormatterOptions as BaseOptions; + } + } + public CompactLogFormatterOptions FormatterOptions { get; set; } public string Name => ConsoleLogFormatterNames.Compact; @@ -56,14 +64,10 @@ public LogMessageEntry Format(LogLevel logLevel, string logName, int eve { return FormatHelper(logLevel, logName, eventId, message, exception, scopeProvider, state); } + // TODO: test use case: return default; } - public LogMessageEntry Format(LogLevel logLevel, string logName, int eventId, string message, Exception exception, IExternalScopeProvider scopeProvider) - { - return FormatHelper(logLevel, logName, eventId, message, exception, scopeProvider, null); - } - private LogMessageEntry FormatHelper(LogLevel logLevel, string logName, int eventId, string message, Exception exception, IExternalScopeProvider scopeProvider, TState scope) { var messages = new List(); diff --git a/src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/CompactLogFormatterOptions.cs b/src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/CompactLogFormatterOptions.cs index aee8d125e7b739..c5e03e0ba7d3b8 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/CompactLogFormatterOptions.cs +++ b/src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/CompactLogFormatterOptions.cs @@ -8,33 +8,13 @@ namespace Microsoft.Extensions.Logging.Console { - public class CompactLogFormatterOptions + public class CompactLogFormatterOptions : BaseOptions { public CompactLogFormatterOptions() { } - /// - /// Includes scopes when . - /// - public bool IncludeScopes { get; set; } - /// /// Disables colors when . /// public bool DisableColors { get; set; } - - /// - /// Gets or sets value indicating the minimum level of messaged that would get written to Console.Error. - /// - public LogLevel LogToStandardErrorThreshold { get; set; } = LogLevel.None; - - /// - /// Gets or sets format string used to format timestamp in logging messages. Defaults to null. - /// - public string TimestampFormat { get; set; } - - /// - /// Gets or sets indication whether or not UTC timezone should be used to for timestamps in logging messages. Defaults to false. - /// - public bool UseUtcTimestamp { get; set; } } } diff --git a/src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/DefaultConsoleLogFormatter.cs b/src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/DefaultConsoleLogFormatter.cs index 5d6383d5001596..2643ae11811fa9 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/DefaultConsoleLogFormatter.cs +++ b/src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/DefaultConsoleLogFormatter.cs @@ -48,6 +48,14 @@ public void Dispose() public string Name => ConsoleLogFormatterNames.Default; + public BaseOptions Options + { + get + { + return FormatterOptions as BaseOptions; + } + } + public DefaultConsoleLogFormatterOptions FormatterOptions { get; set; } public LogMessageEntry Format(LogLevel logLevel, string logName, int eventId, TState state, Exception exception, Func formatter, IExternalScopeProvider scopeProvider) @@ -60,7 +68,7 @@ public LogMessageEntry Format(LogLevel logLevel, string logName, int eve return default; } - public LogMessageEntry Format(LogLevel logLevel, string logName, int eventId, string message, Exception exception, IExternalScopeProvider scopeProvider) + private LogMessageEntry Format(LogLevel logLevel, string logName, int eventId, string message, Exception exception, IExternalScopeProvider scopeProvider) { var logBuilder = _logBuilder; _logBuilder = null; diff --git a/src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/DefaultConsoleLogFormatterOptions.cs b/src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/DefaultConsoleLogFormatterOptions.cs index 5524a869545560..62c0ac1ea57af4 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/DefaultConsoleLogFormatterOptions.cs +++ b/src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/DefaultConsoleLogFormatterOptions.cs @@ -8,33 +8,13 @@ namespace Microsoft.Extensions.Logging.Console { - public class DefaultConsoleLogFormatterOptions + public class DefaultConsoleLogFormatterOptions : BaseOptions { public DefaultConsoleLogFormatterOptions() { } - /// - /// Includes scopes when . - /// - public bool IncludeScopes { get; set; } - /// /// Disables colors when . /// public bool DisableColors { get; set; } - - /// - /// Gets or sets value indicating the minimum level of messaged that would get written to Console.Error. - /// - public LogLevel LogToStandardErrorThreshold { get; set; } = LogLevel.None; - - /// - /// Gets or sets format string used to format timestamp in logging messages. Defaults to null. - /// - public string TimestampFormat { get; set; } - - /// - /// Gets or sets indication whether or not UTC timezone should be used to for timestamps in logging messages. Defaults to false. - /// - public bool UseUtcTimestamp { get; set; } } } diff --git a/src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/IConsoleLogFormatter.cs b/src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/IConsoleLogFormatter.cs index ea768ec77c8d9c..06db89f51f3517 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/IConsoleLogFormatter.cs +++ b/src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/IConsoleLogFormatter.cs @@ -9,7 +9,7 @@ namespace Microsoft.Extensions.Logging.Console public interface IConsoleLogFormatter { string Name { get; } - LogMessageEntry Format(LogLevel logLevel, string logName, int eventId, string message, Exception exception, IExternalScopeProvider scopeProvider); + BaseOptions Options { get; } LogMessageEntry Format(LogLevel logLevel, string logName, int eventId, TState state, Exception exception, Func formatter, IExternalScopeProvider scopeProvider); } } diff --git a/src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/JsonConsoleLogFormatter.cs b/src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/JsonConsoleLogFormatter.cs index e91775ce3d837d..3efaf37640e00d 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/JsonConsoleLogFormatter.cs +++ b/src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/JsonConsoleLogFormatter.cs @@ -96,7 +96,7 @@ public LogMessageEntry Format(LogLevel logLevel, string logName, int eve return default; } - public LogMessageEntry Format(LogLevel logLevel, string logName, int eventId, string message, Exception exception, IExternalScopeProvider scopeProvider) + private LogMessageEntry Format(LogLevel logLevel, string logName, int eventId, string message, Exception exception, IExternalScopeProvider scopeProvider) { var logBuilder = _logBuilder; _logBuilder = null; @@ -190,6 +190,14 @@ private void GetScopeInformation(Utf8JsonWriter writer, IExternalScopeProvider s } } + public BaseOptions Options + { + get + { + return FormatterOptions as BaseOptions; + } + } + public JsonConsoleLogFormatterOptions FormatterOptions { get; set; } private void ReloadLoggerOptions(JsonConsoleLogFormatterOptions options) diff --git a/src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/JsonConsoleLogFormatterOptions.cs b/src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/JsonConsoleLogFormatterOptions.cs index b8f6c72144495c..195664a2642a7c 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/JsonConsoleLogFormatterOptions.cs +++ b/src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/JsonConsoleLogFormatterOptions.cs @@ -8,30 +8,10 @@ namespace Microsoft.Extensions.Logging.Console { - public class JsonConsoleLogFormatterOptions + public class JsonConsoleLogFormatterOptions : BaseOptions { public JsonConsoleLogFormatterOptions() { } public JsonWriterOptions JsonWriterOptions { get; set; } public JsonSerializerOptions JsonSerializerOptions { get; set; } - - /// - /// Includes scopes when . - /// - public bool IncludeScopes { get; set; } - - /// - /// Gets or sets value indicating the minimum level of messaged that would get written to Console.Error. - /// - public LogLevel LogToStandardErrorThreshold { get; set; } = LogLevel.None; - - /// - /// Gets or sets format string used to format timestamp in logging messages. Defaults to null. - /// - public string TimestampFormat { get; set; } - - /// - /// Gets or sets indication whether or not UTC timezone should be used to for timestamps in logging messages. Defaults to false. - /// - public bool UseUtcTimestamp { get; set; } } } diff --git a/src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/SystemdConsoleLogFormatter.cs b/src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/SystemdConsoleLogFormatter.cs index 6bddc6baa8cce1..3ed9b40add98c9 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/SystemdConsoleLogFormatter.cs +++ b/src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/SystemdConsoleLogFormatter.cs @@ -43,6 +43,14 @@ public void Dispose() public string Name => ConsoleLogFormatterNames.Systemd; + public BaseOptions Options + { + get + { + return FormatterOptions as BaseOptions; + } + } + public SystemdConsoleLogFormatterOptions FormatterOptions { get; set; } public LogMessageEntry Format(LogLevel logLevel, string logName, int eventId, TState state, Exception exception, Func formatter, IExternalScopeProvider scopeProvider) @@ -55,7 +63,7 @@ public LogMessageEntry Format(LogLevel logLevel, string logName, int eve return default; } - public LogMessageEntry Format(LogLevel logLevel, string logName, int eventId, string message, Exception exception, IExternalScopeProvider scopeProvider) + private LogMessageEntry Format(LogLevel logLevel, string logName, int eventId, string message, Exception exception, IExternalScopeProvider scopeProvider) { var logBuilder = _logBuilder; _logBuilder = null; diff --git a/src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/SystemdConsoleLogFormatterOptions.cs b/src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/SystemdConsoleLogFormatterOptions.cs index 5bc28892dc085e..6d1a9c715ad0b0 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/SystemdConsoleLogFormatterOptions.cs +++ b/src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/SystemdConsoleLogFormatterOptions.cs @@ -7,28 +7,8 @@ namespace Microsoft.Extensions.Logging.Console { - public class SystemdConsoleLogFormatterOptions + public class SystemdConsoleLogFormatterOptions : BaseOptions { public SystemdConsoleLogFormatterOptions() { } - - /// - /// Includes scopes when . - /// - public bool IncludeScopes { get; set; } - - /// - /// Gets or sets value indicating the minimum level of messaged that would get written to Console.Error. - /// - public LogLevel LogToStandardErrorThreshold { get; set; } = LogLevel.None; - - /// - /// Gets or sets format string used to format timestamp in logging messages. Defaults to null. - /// - public string TimestampFormat { get; set; } - - /// - /// Gets or sets indication whether or not UTC timezone should be used to for timestamps in logging messages. Defaults to false. - /// - public bool UseUtcTimestamp { get; set; } } } From a84860f3b85517ac641a4084b86dfb6ab9640047 Mon Sep 17 00:00:00 2001 From: Maryam Ariyan Date: Thu, 21 May 2020 15:52:21 -0700 Subject: [PATCH 12/15] exception messaging in compact remains single line boxing issue - prefer to deprecate options move to FormatterOptions Improve *FormatterOptions names and Helper methods --- .../Microsoft.Extensions.Logging.Console.cs | 39 ++++++++-------- .../src/ConsoleLoggerFactoryExtensions.cs | 46 +++++++++++++++---- .../src/ConsoleLoggerOptions.cs | 17 +++---- .../src/ConsoleLoggerProvider.cs | 28 +++++++---- .../BasicConsoleLogFormatterOptions.cs | 22 +++++++++ ...s => ColoredConsoleLogFormatterOptions.cs} | 4 +- .../src/Formatter/CompactLogFormatter.cs | 20 +++----- .../Formatter/DefaultConsoleLogFormatter.cs | 14 ++---- .../DefaultConsoleLogFormatterOptions.cs | 20 -------- .../src/Formatter/IConsoleLogFormatter.cs | 1 - .../src/Formatter/JsonConsoleLogFormatter.cs | 10 +--- .../JsonConsoleLogFormatterOptions.cs | 2 +- .../Formatter/SystemdConsoleLogFormatter.cs | 14 ++---- .../SystemdConsoleLogFormatterOptions.cs | 14 ------ 14 files changed, 124 insertions(+), 127 deletions(-) create mode 100644 src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/BasicConsoleLogFormatterOptions.cs rename src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/{CompactLogFormatterOptions.cs => ColoredConsoleLogFormatterOptions.cs} (77%) delete mode 100644 src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/DefaultConsoleLogFormatterOptions.cs delete mode 100644 src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/SystemdConsoleLogFormatterOptions.cs diff --git a/src/libraries/Microsoft.Extensions.Logging.Console/ref/Microsoft.Extensions.Logging.Console.cs b/src/libraries/Microsoft.Extensions.Logging.Console/ref/Microsoft.Extensions.Logging.Console.cs index 40c7efb61f426b..16cbc44c39a9c6 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Console/ref/Microsoft.Extensions.Logging.Console.cs +++ b/src/libraries/Microsoft.Extensions.Logging.Console/ref/Microsoft.Extensions.Logging.Console.cs @@ -9,29 +9,30 @@ namespace Microsoft.Extensions.Logging { public static partial class ConsoleLoggerExtensions { - public static Microsoft.Extensions.Logging.ILoggingBuilder AddCompactConsoleLogFormatter(this Microsoft.Extensions.Logging.ILoggingBuilder builder, System.Action configure) { throw null; } public static Microsoft.Extensions.Logging.ILoggingBuilder AddConsole(this Microsoft.Extensions.Logging.ILoggingBuilder builder) { throw null; } public static Microsoft.Extensions.Logging.ILoggingBuilder AddConsole(this Microsoft.Extensions.Logging.ILoggingBuilder builder, System.Action configure) { throw null; } + public static Microsoft.Extensions.Logging.ILoggingBuilder AddConsole(this Microsoft.Extensions.Logging.ILoggingBuilder builder, string formatterName) { throw null; } public static Microsoft.Extensions.Logging.ILoggingBuilder AddConsoleLogFormatter(this Microsoft.Extensions.Logging.ILoggingBuilder builder) where TFormatter : class, Microsoft.Extensions.Logging.Console.IConsoleLogFormatter where TOptions : class { throw null; } public static Microsoft.Extensions.Logging.ILoggingBuilder AddConsoleLogFormatter(this Microsoft.Extensions.Logging.ILoggingBuilder builder, System.Action configure) where TFormatter : class, Microsoft.Extensions.Logging.Console.IConsoleLogFormatter where TOptions : class { throw null; } - public static Microsoft.Extensions.Logging.ILoggingBuilder AddDefaultConsoleLogFormatter(this Microsoft.Extensions.Logging.ILoggingBuilder builder, System.Action configure) { throw null; } - public static Microsoft.Extensions.Logging.ILoggingBuilder AddJsonConsoleLogFormatter(this Microsoft.Extensions.Logging.ILoggingBuilder builder, System.Action configure) { throw null; } - public static Microsoft.Extensions.Logging.ILoggingBuilder AddSystemdConsoleLogFormatter(this Microsoft.Extensions.Logging.ILoggingBuilder builder, System.Action configure) { throw null; } + public static Microsoft.Extensions.Logging.ILoggingBuilder UseCompactConsoleLogFormatter(this Microsoft.Extensions.Logging.ILoggingBuilder builder, System.Action configure) { throw null; } + public static Microsoft.Extensions.Logging.ILoggingBuilder UseDefaultConsoleLogFormatter(this Microsoft.Extensions.Logging.ILoggingBuilder builder, System.Action configure) { throw null; } + public static Microsoft.Extensions.Logging.ILoggingBuilder UseJsonConsoleLogFormatter(this Microsoft.Extensions.Logging.ILoggingBuilder builder, System.Action configure) { throw null; } + public static Microsoft.Extensions.Logging.ILoggingBuilder UseSystemdConsoleLogFormatter(this Microsoft.Extensions.Logging.ILoggingBuilder builder, System.Action configure) { throw null; } } } namespace Microsoft.Extensions.Logging.Console { - public abstract partial class BaseOptions + public partial class BasicConsoleLogFormatterOptions { - protected BaseOptions() { } + public BasicConsoleLogFormatterOptions() { } public bool IncludeScopes { get { throw null; } set { } } public Microsoft.Extensions.Logging.LogLevel LogToStandardErrorThreshold { get { throw null; } set { } } public string TimestampFormat { get { throw null; } set { } } public bool UseUtcTimestamp { get { throw null; } set { } } } - public partial class CompactLogFormatterOptions : Microsoft.Extensions.Logging.Console.BaseOptions + public partial class ColoredConsoleLogFormatterOptions : Microsoft.Extensions.Logging.Console.BasicConsoleLogFormatterOptions { - public CompactLogFormatterOptions() { } + public ColoredConsoleLogFormatterOptions() { } public bool DisableColors { get { throw null; } set { } } } public static partial class ConsoleLogFormatterNames @@ -46,7 +47,7 @@ public enum ConsoleLoggerFormat Default = 0, Systemd = 1, } - public partial class ConsoleLoggerOptions : Microsoft.Extensions.Logging.Console.BaseOptions + public partial class ConsoleLoggerOptions { public ConsoleLoggerOptions() { } [System.ObsoleteAttribute("ConsoleLoggerOptions.DisableColors has been deprecated. Please use DefaultConsoleLogFormatterOptions.DisableColors instead.", false)] @@ -54,6 +55,14 @@ public ConsoleLoggerOptions() { } [System.ObsoleteAttribute("ConsoleLoggerOptions.Format has been deprecated. Please use ConsoleLoggerOptions.FormatterName instead.", false)] public Microsoft.Extensions.Logging.Console.ConsoleLoggerFormat Format { get { throw null; } set { } } public string FormatterName { get { throw null; } set { } } + [System.ObsoleteAttribute("ConsoleLoggerOptions.IncludeScopes has been deprecated..", false)] + public bool IncludeScopes { get { throw null; } set { } } + [System.ObsoleteAttribute("ConsoleLoggerOptions.LogToStandardErrorThreshold has been deprecated..", false)] + public Microsoft.Extensions.Logging.LogLevel LogToStandardErrorThreshold { get { throw null; } set { } } + [System.ObsoleteAttribute("ConsoleLoggerOptions.TimestampFormat has been deprecated..", false)] + public string TimestampFormat { get { throw null; } set { } } + [System.ObsoleteAttribute("ConsoleLoggerOptions.UseUtcTimestamp has been deprecated..", false)] + public bool UseUtcTimestamp { get { throw null; } set { } } } [Microsoft.Extensions.Logging.ProviderAliasAttribute("Console")] public partial class ConsoleLoggerProvider : Microsoft.Extensions.Logging.ILoggerProvider, Microsoft.Extensions.Logging.ISupportExternalScope, System.IDisposable @@ -72,18 +81,12 @@ public readonly partial struct ConsoleMessage public readonly System.ConsoleColor? Foreground; public ConsoleMessage(string message, System.ConsoleColor? background = default(System.ConsoleColor?), System.ConsoleColor? foreground = default(System.ConsoleColor?)) { throw null; } } - public partial class DefaultConsoleLogFormatterOptions : Microsoft.Extensions.Logging.Console.BaseOptions - { - public DefaultConsoleLogFormatterOptions() { } - public bool DisableColors { get { throw null; } set { } } - } public partial interface IConsoleLogFormatter { string Name { get; } - BaseOptions Options { get; } Microsoft.Extensions.Logging.Console.LogMessageEntry Format(Microsoft.Extensions.Logging.LogLevel logLevel, string logName, int eventId, TState state, System.Exception exception, System.Func formatter, Microsoft.Extensions.Logging.IExternalScopeProvider scopeProvider); } - public partial class JsonConsoleLogFormatterOptions : Microsoft.Extensions.Logging.Console.BaseOptions + public partial class JsonConsoleLogFormatterOptions : Microsoft.Extensions.Logging.Console.BasicConsoleLogFormatterOptions { public JsonConsoleLogFormatterOptions() { } public System.Text.Json.JsonSerializerOptions JsonSerializerOptions { get { throw null; } set { } } @@ -95,8 +98,4 @@ public readonly partial struct LogMessageEntry public readonly Microsoft.Extensions.Logging.Console.ConsoleMessage[] Messages; public LogMessageEntry(Microsoft.Extensions.Logging.Console.ConsoleMessage[] messages, bool logAsError = false) { throw null; } } - public partial class SystemdConsoleLogFormatterOptions : Microsoft.Extensions.Logging.Console.BaseOptions - { - public SystemdConsoleLogFormatterOptions() { } - } } diff --git a/src/libraries/Microsoft.Extensions.Logging.Console/src/ConsoleLoggerFactoryExtensions.cs b/src/libraries/Microsoft.Extensions.Logging.Console/src/ConsoleLoggerFactoryExtensions.cs index 99b97b540014df..29516306e56713 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Console/src/ConsoleLoggerFactoryExtensions.cs +++ b/src/libraries/Microsoft.Extensions.Logging.Console/src/ConsoleLoggerFactoryExtensions.cs @@ -30,9 +30,9 @@ public static ILoggingBuilder AddConsole(this ILoggingBuilder builder) builder.AddConfiguration(); builder.AddConsoleLogFormatter(); - builder.AddConsoleLogFormatter(); - builder.AddConsoleLogFormatter(); - builder.AddConsoleLogFormatter(); + builder.AddConsoleLogFormatter(); + builder.AddConsoleLogFormatter(); + builder.AddConsoleLogFormatter(); builder.Services.TryAddEnumerable(ServiceDescriptor.Singleton()); LoggerProviderOptions.RegisterProviderOptions(builder.Services); @@ -57,8 +57,24 @@ public static ILoggingBuilder AddConsole(this ILoggingBuilder builder, Action configure) + + /// + /// Adds a console logger named 'Console' to the factory. + /// + /// The to use. + /// + public static ILoggingBuilder AddConsole(this ILoggingBuilder builder, string formatterName) + { + if (formatterName == null) + { + throw new ArgumentNullException(nameof(formatterName)); + } + + Action configure = (options) => { options.FormatterName = formatterName; }; + return builder.AddConsole(configure); + } + + public static ILoggingBuilder UseCompactConsoleLogFormatter(this ILoggingBuilder builder, Action configure) { if (configure == null) { @@ -68,11 +84,14 @@ public static ILoggingBuilder AddCompactConsoleLogFormatter(this ILoggingBuilder builder.AddConsole(); builder.Services.Configure(configure); + Action configureFormatter = (options) => { options.FormatterName = ConsoleLogFormatterNames.Compact; }; + builder.Services.Configure(configureFormatter); + return builder; } - public static ILoggingBuilder AddDefaultConsoleLogFormatter(this ILoggingBuilder builder, Action configure) - { + public static ILoggingBuilder UseDefaultConsoleLogFormatter(this ILoggingBuilder builder, Action configure) + { if (configure == null) { throw new ArgumentNullException(nameof(configure)); @@ -81,10 +100,13 @@ public static ILoggingBuilder AddDefaultConsoleLogFormatter(this ILoggingBuilder builder.AddConsole(); builder.Services.Configure(configure); + Action configureFormatter = (options) => { options.FormatterName = ConsoleLogFormatterNames.Default; }; + builder.Services.Configure(configureFormatter); + return builder; } - public static ILoggingBuilder AddJsonConsoleLogFormatter(this ILoggingBuilder builder, Action configure) + public static ILoggingBuilder UseJsonConsoleLogFormatter(this ILoggingBuilder builder, Action configure) { if (configure == null) { @@ -94,10 +116,13 @@ public static ILoggingBuilder AddJsonConsoleLogFormatter(this ILoggingBuilder bu builder.AddConsole(); builder.Services.Configure(configure); + Action configureFormatter = (options) => { options.FormatterName = ConsoleLogFormatterNames.Json; }; + builder.Services.Configure(configureFormatter); + return builder; } - public static ILoggingBuilder AddSystemdConsoleLogFormatter(this ILoggingBuilder builder, Action configure) + public static ILoggingBuilder UseSystemdConsoleLogFormatter(this ILoggingBuilder builder, Action configure) { if (configure == null) { @@ -107,6 +132,9 @@ public static ILoggingBuilder AddSystemdConsoleLogFormatter(this ILoggingBuilder builder.AddConsole(); builder.Services.Configure(configure); + Action configureFormatter = (options) => { options.FormatterName = ConsoleLogFormatterNames.Systemd; }; + builder.Services.Configure(configureFormatter); + return builder; } diff --git a/src/libraries/Microsoft.Extensions.Logging.Console/src/ConsoleLoggerOptions.cs b/src/libraries/Microsoft.Extensions.Logging.Console/src/ConsoleLoggerOptions.cs index 10a2afda8c6855..4288eb30f2b9c1 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Console/src/ConsoleLoggerOptions.cs +++ b/src/libraries/Microsoft.Extensions.Logging.Console/src/ConsoleLoggerOptions.cs @@ -10,7 +10,7 @@ namespace Microsoft.Extensions.Logging.Console /// /// Options for a . /// - public class ConsoleLoggerOptions : BaseOptions + public class ConsoleLoggerOptions { [System.ObsoleteAttribute("ConsoleLoggerOptions.DisableColors has been deprecated. Please use DefaultConsoleLogFormatterOptions.DisableColors instead.", false)] public bool DisableColors { get; set; } @@ -44,16 +44,17 @@ public ConsoleLoggerFormat Format /// /// public string FormatterName { get; set; } - } - - public abstract class BaseOptions - { - public bool IncludeScopes { get; set; } + [System.ObsoleteAttribute("ConsoleLoggerOptions.IncludeScopes has been deprecated..", false)] + public bool IncludeScopes { get; set; } + + [System.ObsoleteAttribute("ConsoleLoggerOptions.LogToStandardErrorThreshold has been deprecated..", false)] public Microsoft.Extensions.Logging.LogLevel LogToStandardErrorThreshold { get; set; } - + + [System.ObsoleteAttribute("ConsoleLoggerOptions.TimestampFormat has been deprecated..", false)] public string TimestampFormat { get; set; } - + + [System.ObsoleteAttribute("ConsoleLoggerOptions.UseUtcTimestamp has been deprecated..", false)] public bool UseUtcTimestamp { get; set; } } } diff --git a/src/libraries/Microsoft.Extensions.Logging.Console/src/ConsoleLoggerProvider.cs b/src/libraries/Microsoft.Extensions.Logging.Console/src/ConsoleLoggerProvider.cs index 5895b835bad2a0..3aa2b410cff101 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Console/src/ConsoleLoggerProvider.cs +++ b/src/libraries/Microsoft.Extensions.Logging.Console/src/ConsoleLoggerProvider.cs @@ -76,15 +76,27 @@ private void ReloadLoggerOptions(ConsoleLoggerOptions options) } } - private void UpdateFormatterOptions(IConsoleLogFormatter formatter, ConsoleLoggerOptions fromOptions) + private void UpdateFormatterOptions(IConsoleLogFormatter formatter, ConsoleLoggerOptions deprecatedFromOptions) { - formatter.Options.IncludeScopes = fromOptions.IncludeScopes; - formatter.Options.LogToStandardErrorThreshold = fromOptions.LogToStandardErrorThreshold; - formatter.Options.TimestampFormat = fromOptions.TimestampFormat; - formatter.Options.UseUtcTimestamp = fromOptions.UseUtcTimestamp; - // kept for deprecated api: - if (formatter is DefaultConsoleLogFormatter dFormatter) - dFormatter.FormatterOptions.DisableColors = fromOptions.DisableColors; + if (deprecatedFromOptions.FormatterName != null) + return; + // kept for deprecated apis: + if (formatter is DefaultConsoleLogFormatter defaultFormatter) + { + defaultFormatter.FormatterOptions.DisableColors = deprecatedFromOptions.DisableColors; + defaultFormatter.FormatterOptions.IncludeScopes = deprecatedFromOptions.IncludeScopes; + defaultFormatter.FormatterOptions.LogToStandardErrorThreshold = deprecatedFromOptions.LogToStandardErrorThreshold; + defaultFormatter.FormatterOptions.TimestampFormat = deprecatedFromOptions.TimestampFormat; + defaultFormatter.FormatterOptions.UseUtcTimestamp = deprecatedFromOptions.UseUtcTimestamp; + } + else + if (formatter is SystemdConsoleLogFormatter systemdFormatter) + { + systemdFormatter.FormatterOptions.IncludeScopes = deprecatedFromOptions.IncludeScopes; + systemdFormatter.FormatterOptions.LogToStandardErrorThreshold = deprecatedFromOptions.LogToStandardErrorThreshold; + systemdFormatter.FormatterOptions.TimestampFormat = deprecatedFromOptions.TimestampFormat; + systemdFormatter.FormatterOptions.UseUtcTimestamp = deprecatedFromOptions.UseUtcTimestamp; + } } /// diff --git a/src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/BasicConsoleLogFormatterOptions.cs b/src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/BasicConsoleLogFormatterOptions.cs new file mode 100644 index 00000000000000..d1601d9de308c1 --- /dev/null +++ b/src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/BasicConsoleLogFormatterOptions.cs @@ -0,0 +1,22 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using System.Text; + +namespace Microsoft.Extensions.Logging.Console +{ + public class BasicConsoleLogFormatterOptions + { + public BasicConsoleLogFormatterOptions() { } + + public bool IncludeScopes { get; set; } + + public Microsoft.Extensions.Logging.LogLevel LogToStandardErrorThreshold { get; set; } + + public string TimestampFormat { get; set; } + + public bool UseUtcTimestamp { get; set; } + } +} diff --git a/src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/CompactLogFormatterOptions.cs b/src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/ColoredConsoleLogFormatterOptions.cs similarity index 77% rename from src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/CompactLogFormatterOptions.cs rename to src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/ColoredConsoleLogFormatterOptions.cs index c5e03e0ba7d3b8..131b216647ee93 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/CompactLogFormatterOptions.cs +++ b/src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/ColoredConsoleLogFormatterOptions.cs @@ -8,9 +8,9 @@ namespace Microsoft.Extensions.Logging.Console { - public class CompactLogFormatterOptions : BaseOptions + public class ColoredConsoleLogFormatterOptions : BasicConsoleLogFormatterOptions { - public CompactLogFormatterOptions() { } + public ColoredConsoleLogFormatterOptions() { } /// /// Disables colors when . diff --git a/src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/CompactLogFormatter.cs b/src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/CompactLogFormatter.cs index 8a10e3e659f14e..d41a8eb2ef9a75 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/CompactLogFormatter.cs +++ b/src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/CompactLogFormatter.cs @@ -28,14 +28,14 @@ static CompactLogFormatter() _newLineWithMessagePadding = Environment.NewLine + _messagePadding; } - public CompactLogFormatter(IOptionsMonitor options) + public CompactLogFormatter(IOptionsMonitor options) { FormatterOptions = options.CurrentValue; ReloadLoggerOptions(options.CurrentValue); _optionsReloadToken = options.OnChange(ReloadLoggerOptions); } - private void ReloadLoggerOptions(CompactLogFormatterOptions options) + private void ReloadLoggerOptions(ColoredConsoleLogFormatterOptions options) { FormatterOptions = options; } @@ -45,15 +45,7 @@ public void Dispose() _optionsReloadToken?.Dispose(); } - public BaseOptions Options - { - get - { - return FormatterOptions as BaseOptions; - } - } - - public CompactLogFormatterOptions FormatterOptions { get; set; } + internal ColoredConsoleLogFormatterOptions FormatterOptions { get; set; } public string Name => ConsoleLogFormatterNames.Compact; @@ -123,6 +115,7 @@ private LogMessageEntry FormatHelper(LogLevel logLevel, string logName, { var curString = originalFormat.Substring(prevIndex, curIndex - prevIndex); messages.Add(new ConsoleMessage(curString, null, null)); + // TODO: when DisableColors is true, also uncolor the inner var colors messages.Add(new ConsoleMessage(strings.ElementAt(count).Value.ToString(), null, ConsoleColor.Cyan)); prevIndex += curIndex + strings.ElementAt(count).Key.Length + 2; count++; @@ -186,8 +179,9 @@ private LogMessageEntry FormatHelper(LogLevel logLevel, string logName, { // exception message messages.Add(new ConsoleMessage(" ", null, null)); - messages.Add(new ConsoleMessage(exception.ToString(), null, null)); - // TODO: confirm exception message all in one line? + messages.Add(new ConsoleMessage(exception.ToString().Replace(Environment.NewLine, " "), null, null)); + // TODO: try to improve readability for exception message. + // TODO: maybe use Compact as default? } messages.Add(new ConsoleMessage(Environment.NewLine, null, null)); diff --git a/src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/DefaultConsoleLogFormatter.cs b/src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/DefaultConsoleLogFormatter.cs index 2643ae11811fa9..0b6086c1f79f0d 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/DefaultConsoleLogFormatter.cs +++ b/src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/DefaultConsoleLogFormatter.cs @@ -29,14 +29,14 @@ static DefaultConsoleLogFormatter() _newLineWithMessagePadding = Environment.NewLine + _messagePadding; } - public DefaultConsoleLogFormatter(IOptionsMonitor options) + public DefaultConsoleLogFormatter(IOptionsMonitor options) { FormatterOptions = options.CurrentValue; ReloadLoggerOptions(options.CurrentValue); _optionsReloadToken = options.OnChange(ReloadLoggerOptions); } - private void ReloadLoggerOptions(DefaultConsoleLogFormatterOptions options) + private void ReloadLoggerOptions(ColoredConsoleLogFormatterOptions options) { FormatterOptions = options; } @@ -48,15 +48,7 @@ public void Dispose() public string Name => ConsoleLogFormatterNames.Default; - public BaseOptions Options - { - get - { - return FormatterOptions as BaseOptions; - } - } - - public DefaultConsoleLogFormatterOptions FormatterOptions { get; set; } + internal ColoredConsoleLogFormatterOptions FormatterOptions { get; set; } public LogMessageEntry Format(LogLevel logLevel, string logName, int eventId, TState state, Exception exception, Func formatter, IExternalScopeProvider scopeProvider) { diff --git a/src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/DefaultConsoleLogFormatterOptions.cs b/src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/DefaultConsoleLogFormatterOptions.cs deleted file mode 100644 index 62c0ac1ea57af4..00000000000000 --- a/src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/DefaultConsoleLogFormatterOptions.cs +++ /dev/null @@ -1,20 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using System; -using System.Collections.Generic; -using System.Text; - -namespace Microsoft.Extensions.Logging.Console -{ - public class DefaultConsoleLogFormatterOptions : BaseOptions - { - public DefaultConsoleLogFormatterOptions() { } - - /// - /// Disables colors when . - /// - public bool DisableColors { get; set; } - } -} diff --git a/src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/IConsoleLogFormatter.cs b/src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/IConsoleLogFormatter.cs index 06db89f51f3517..1624035ee592d9 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/IConsoleLogFormatter.cs +++ b/src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/IConsoleLogFormatter.cs @@ -9,7 +9,6 @@ namespace Microsoft.Extensions.Logging.Console public interface IConsoleLogFormatter { string Name { get; } - BaseOptions Options { get; } LogMessageEntry Format(LogLevel logLevel, string logName, int eventId, TState state, Exception exception, Func formatter, IExternalScopeProvider scopeProvider); } } diff --git a/src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/JsonConsoleLogFormatter.cs b/src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/JsonConsoleLogFormatter.cs index 3efaf37640e00d..85a7cc47903ded 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/JsonConsoleLogFormatter.cs +++ b/src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/JsonConsoleLogFormatter.cs @@ -190,15 +190,7 @@ private void GetScopeInformation(Utf8JsonWriter writer, IExternalScopeProvider s } } - public BaseOptions Options - { - get - { - return FormatterOptions as BaseOptions; - } - } - - public JsonConsoleLogFormatterOptions FormatterOptions { get; set; } + internal JsonConsoleLogFormatterOptions FormatterOptions { get; set; } private void ReloadLoggerOptions(JsonConsoleLogFormatterOptions options) { diff --git a/src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/JsonConsoleLogFormatterOptions.cs b/src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/JsonConsoleLogFormatterOptions.cs index 195664a2642a7c..37cb539d21f792 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/JsonConsoleLogFormatterOptions.cs +++ b/src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/JsonConsoleLogFormatterOptions.cs @@ -8,7 +8,7 @@ namespace Microsoft.Extensions.Logging.Console { - public class JsonConsoleLogFormatterOptions : BaseOptions + public class JsonConsoleLogFormatterOptions : BasicConsoleLogFormatterOptions { public JsonConsoleLogFormatterOptions() { } public JsonWriterOptions JsonWriterOptions { get; set; } diff --git a/src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/SystemdConsoleLogFormatter.cs b/src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/SystemdConsoleLogFormatter.cs index 3ed9b40add98c9..bc8fb8bfa81aad 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/SystemdConsoleLogFormatter.cs +++ b/src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/SystemdConsoleLogFormatter.cs @@ -24,14 +24,14 @@ static SystemdConsoleLogFormatter() _messagePadding = new string(' ', logLevelString.Length + _loglevelPadding.Length); } - public SystemdConsoleLogFormatter(IOptionsMonitor options) + public SystemdConsoleLogFormatter(IOptionsMonitor options) { FormatterOptions = options.CurrentValue; ReloadLoggerOptions(options.CurrentValue); _optionsReloadToken = options.OnChange(ReloadLoggerOptions); } - private void ReloadLoggerOptions(SystemdConsoleLogFormatterOptions options) + private void ReloadLoggerOptions(BasicConsoleLogFormatterOptions options) { FormatterOptions = options; } @@ -43,15 +43,7 @@ public void Dispose() public string Name => ConsoleLogFormatterNames.Systemd; - public BaseOptions Options - { - get - { - return FormatterOptions as BaseOptions; - } - } - - public SystemdConsoleLogFormatterOptions FormatterOptions { get; set; } + internal BasicConsoleLogFormatterOptions FormatterOptions { get; set; } public LogMessageEntry Format(LogLevel logLevel, string logName, int eventId, TState state, Exception exception, Func formatter, IExternalScopeProvider scopeProvider) { diff --git a/src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/SystemdConsoleLogFormatterOptions.cs b/src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/SystemdConsoleLogFormatterOptions.cs deleted file mode 100644 index 6d1a9c715ad0b0..00000000000000 --- a/src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/SystemdConsoleLogFormatterOptions.cs +++ /dev/null @@ -1,14 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using System; -using System.Text; - -namespace Microsoft.Extensions.Logging.Console -{ - public class SystemdConsoleLogFormatterOptions : BaseOptions - { - public SystemdConsoleLogFormatterOptions() { } - } -} From d3cfd55874aa9a8eb6eb120858cc7a604155b3e3 Mon Sep 17 00:00:00 2001 From: Maryam Ariyan Date: Tue, 26 May 2020 10:35:01 -0700 Subject: [PATCH 13/15] cleanup --- .../Microsoft.Extensions.Logging.Console.cs | 42 ++- .../src/ConsoleLoggerFactoryExtensions.cs | 25 +- .../src/ConsoleLoggerProvider.cs | 16 +- .../src/Formatter/CompactLogFormatter.cs | 275 ------------------ ...nstants.cs => ConsoleLogFormatterNames.cs} | 7 +- .../Formatter/DefaultConsoleLogFormatter.cs | 160 +++++++++- ...s => DefaultConsoleLogFormatterOptions.cs} | 5 +- .../src/Formatter/JsonConsoleLogFormatter.cs | 2 +- .../JsonConsoleLogFormatterOptions.cs | 3 +- .../Formatter/SystemdConsoleLogFormatter.cs | 6 +- ...s => SystemdConsoleLogFormatterOptions.cs} | 4 +- 11 files changed, 205 insertions(+), 340 deletions(-) delete mode 100644 src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/CompactLogFormatter.cs rename src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/{ConsoleFormatterConstants.cs => ConsoleLogFormatterNames.cs} (59%) rename src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/{ColoredConsoleLogFormatterOptions.cs => DefaultConsoleLogFormatterOptions.cs} (72%) rename src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/{BasicConsoleLogFormatterOptions.cs => SystemdConsoleLogFormatterOptions.cs} (84%) diff --git a/src/libraries/Microsoft.Extensions.Logging.Console/ref/Microsoft.Extensions.Logging.Console.cs b/src/libraries/Microsoft.Extensions.Logging.Console/ref/Microsoft.Extensions.Logging.Console.cs index 16cbc44c39a9c6..49736e21538073 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Console/ref/Microsoft.Extensions.Logging.Console.cs +++ b/src/libraries/Microsoft.Extensions.Logging.Console/ref/Microsoft.Extensions.Logging.Console.cs @@ -14,33 +14,18 @@ public static partial class ConsoleLoggerExtensions public static Microsoft.Extensions.Logging.ILoggingBuilder AddConsole(this Microsoft.Extensions.Logging.ILoggingBuilder builder, string formatterName) { throw null; } public static Microsoft.Extensions.Logging.ILoggingBuilder AddConsoleLogFormatter(this Microsoft.Extensions.Logging.ILoggingBuilder builder) where TFormatter : class, Microsoft.Extensions.Logging.Console.IConsoleLogFormatter where TOptions : class { throw null; } public static Microsoft.Extensions.Logging.ILoggingBuilder AddConsoleLogFormatter(this Microsoft.Extensions.Logging.ILoggingBuilder builder, System.Action configure) where TFormatter : class, Microsoft.Extensions.Logging.Console.IConsoleLogFormatter where TOptions : class { throw null; } - public static Microsoft.Extensions.Logging.ILoggingBuilder UseCompactConsoleLogFormatter(this Microsoft.Extensions.Logging.ILoggingBuilder builder, System.Action configure) { throw null; } - public static Microsoft.Extensions.Logging.ILoggingBuilder UseDefaultConsoleLogFormatter(this Microsoft.Extensions.Logging.ILoggingBuilder builder, System.Action configure) { throw null; } + public static Microsoft.Extensions.Logging.ILoggingBuilder UseDefaultConsoleLogFormatter(this Microsoft.Extensions.Logging.ILoggingBuilder builder, System.Action configure) { throw null; } public static Microsoft.Extensions.Logging.ILoggingBuilder UseJsonConsoleLogFormatter(this Microsoft.Extensions.Logging.ILoggingBuilder builder, System.Action configure) { throw null; } - public static Microsoft.Extensions.Logging.ILoggingBuilder UseSystemdConsoleLogFormatter(this Microsoft.Extensions.Logging.ILoggingBuilder builder, System.Action configure) { throw null; } + public static Microsoft.Extensions.Logging.ILoggingBuilder UseSystemdConsoleLogFormatter(this Microsoft.Extensions.Logging.ILoggingBuilder builder, System.Action configure) { throw null; } } } namespace Microsoft.Extensions.Logging.Console { - public partial class BasicConsoleLogFormatterOptions - { - public BasicConsoleLogFormatterOptions() { } - public bool IncludeScopes { get { throw null; } set { } } - public Microsoft.Extensions.Logging.LogLevel LogToStandardErrorThreshold { get { throw null; } set { } } - public string TimestampFormat { get { throw null; } set { } } - public bool UseUtcTimestamp { get { throw null; } set { } } - } - public partial class ColoredConsoleLogFormatterOptions : Microsoft.Extensions.Logging.Console.BasicConsoleLogFormatterOptions - { - public ColoredConsoleLogFormatterOptions() { } - public bool DisableColors { get { throw null; } set { } } - } public static partial class ConsoleLogFormatterNames { - public const string Compact = "Compact"; - public const string Default = "Default"; - public const string Json = "Json"; - public const string Systemd = "Systemd"; + public const string Default = "default"; + public const string Json = "json"; + public const string Systemd = "systemd"; } public enum ConsoleLoggerFormat { @@ -81,15 +66,20 @@ public readonly partial struct ConsoleMessage public readonly System.ConsoleColor? Foreground; public ConsoleMessage(string message, System.ConsoleColor? background = default(System.ConsoleColor?), System.ConsoleColor? foreground = default(System.ConsoleColor?)) { throw null; } } + public partial class DefaultConsoleLogFormatterOptions : Microsoft.Extensions.Logging.Console.SystemdConsoleLogFormatterOptions + { + public DefaultConsoleLogFormatterOptions() { } + public bool DisableColors { get { throw null; } set { } } + public bool MultiLine { get { throw null; } set { } } + } public partial interface IConsoleLogFormatter { string Name { get; } Microsoft.Extensions.Logging.Console.LogMessageEntry Format(Microsoft.Extensions.Logging.LogLevel logLevel, string logName, int eventId, TState state, System.Exception exception, System.Func formatter, Microsoft.Extensions.Logging.IExternalScopeProvider scopeProvider); } - public partial class JsonConsoleLogFormatterOptions : Microsoft.Extensions.Logging.Console.BasicConsoleLogFormatterOptions + public partial class JsonConsoleLogFormatterOptions : Microsoft.Extensions.Logging.Console.SystemdConsoleLogFormatterOptions { public JsonConsoleLogFormatterOptions() { } - public System.Text.Json.JsonSerializerOptions JsonSerializerOptions { get { throw null; } set { } } public System.Text.Json.JsonWriterOptions JsonWriterOptions { get { throw null; } set { } } } public readonly partial struct LogMessageEntry @@ -98,4 +88,12 @@ public readonly partial struct LogMessageEntry public readonly Microsoft.Extensions.Logging.Console.ConsoleMessage[] Messages; public LogMessageEntry(Microsoft.Extensions.Logging.Console.ConsoleMessage[] messages, bool logAsError = false) { throw null; } } + public partial class SystemdConsoleLogFormatterOptions + { + public SystemdConsoleLogFormatterOptions() { } + public bool IncludeScopes { get { throw null; } set { } } + public Microsoft.Extensions.Logging.LogLevel LogToStandardErrorThreshold { get { throw null; } set { } } + public string TimestampFormat { get { throw null; } set { } } + public bool UseUtcTimestamp { get { throw null; } set { } } + } } diff --git a/src/libraries/Microsoft.Extensions.Logging.Console/src/ConsoleLoggerFactoryExtensions.cs b/src/libraries/Microsoft.Extensions.Logging.Console/src/ConsoleLoggerFactoryExtensions.cs index 29516306e56713..ea2be13fe1cfe3 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Console/src/ConsoleLoggerFactoryExtensions.cs +++ b/src/libraries/Microsoft.Extensions.Logging.Console/src/ConsoleLoggerFactoryExtensions.cs @@ -30,9 +30,8 @@ public static ILoggingBuilder AddConsole(this ILoggingBuilder builder) builder.AddConfiguration(); builder.AddConsoleLogFormatter(); - builder.AddConsoleLogFormatter(); - builder.AddConsoleLogFormatter(); - builder.AddConsoleLogFormatter(); + builder.AddConsoleLogFormatter(); + builder.AddConsoleLogFormatter(); builder.Services.TryAddEnumerable(ServiceDescriptor.Singleton()); LoggerProviderOptions.RegisterProviderOptions(builder.Services); @@ -74,23 +73,7 @@ public static ILoggingBuilder AddConsole(this ILoggingBuilder builder, string fo return builder.AddConsole(configure); } - public static ILoggingBuilder UseCompactConsoleLogFormatter(this ILoggingBuilder builder, Action configure) - { - if (configure == null) - { - throw new ArgumentNullException(nameof(configure)); - } - - builder.AddConsole(); - builder.Services.Configure(configure); - - Action configureFormatter = (options) => { options.FormatterName = ConsoleLogFormatterNames.Compact; }; - builder.Services.Configure(configureFormatter); - - return builder; - } - - public static ILoggingBuilder UseDefaultConsoleLogFormatter(this ILoggingBuilder builder, Action configure) + public static ILoggingBuilder UseDefaultConsoleLogFormatter(this ILoggingBuilder builder, Action configure) { if (configure == null) { @@ -122,7 +105,7 @@ public static ILoggingBuilder UseJsonConsoleLogFormatter(this ILoggingBuilder bu return builder; } - public static ILoggingBuilder UseSystemdConsoleLogFormatter(this ILoggingBuilder builder, Action configure) + public static ILoggingBuilder UseSystemdConsoleLogFormatter(this ILoggingBuilder builder, Action configure) { if (configure == null) { diff --git a/src/libraries/Microsoft.Extensions.Logging.Console/src/ConsoleLoggerProvider.cs b/src/libraries/Microsoft.Extensions.Logging.Console/src/ConsoleLoggerProvider.cs index 3aa2b410cff101..227f3641c4982e 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Console/src/ConsoleLoggerProvider.cs +++ b/src/libraries/Microsoft.Extensions.Logging.Console/src/ConsoleLoggerProvider.cs @@ -62,13 +62,21 @@ public ConsoleLoggerProvider(IOptionsMonitor options, IEnu // warning: ReloadLoggerOptions can be called before the ctor completed,... before registering all of the state used in this method need to be initialized private void ReloadLoggerOptions(ConsoleLoggerOptions options) { - string nameFromFormat = Enum.GetName(typeof(ConsoleLoggerFormat), options?.Format); - _formatters.TryGetValue(options?.FormatterName ?? nameFromFormat, out IConsoleLogFormatter logFormatter); + IConsoleLogFormatter logFormatter = null; + if (options.FormatterName != null) + { + _formatters.TryGetValue(options.FormatterName.ToLower(), out logFormatter); + } + //else + //{ + // string nameFromFormat = Enum.GetName(typeof(ConsoleLoggerFormat), options?.Format); + // _formatters.TryGetValue(nameFromFormat, out IConsoleLogFormatter logFormatter); + // UpdateFormatterOptions(logFormatter, options); + //} if (logFormatter == null) { - logFormatter = _formatters[nameFromFormat]; + logFormatter = _formatters[ConsoleLogFormatterNames.Default]; } - UpdateFormatterOptions(logFormatter, options); foreach (var logger in _loggers) { diff --git a/src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/CompactLogFormatter.cs b/src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/CompactLogFormatter.cs deleted file mode 100644 index d41a8eb2ef9a75..00000000000000 --- a/src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/CompactLogFormatter.cs +++ /dev/null @@ -1,275 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using System; -using System.Text; -using Microsoft.Extensions.Options; -using System.Collections.Generic; -using System.Reflection; -using System.Linq; - -namespace Microsoft.Extensions.Logging.Console -{ - internal class CompactLogFormatter : IConsoleLogFormatter, IDisposable - { - private IDisposable _optionsReloadToken; - private static readonly string _loglevelPadding = ": "; - private static readonly string _messagePadding; - private static readonly string _newLineWithMessagePadding; - - // ConsoleColor does not have a value to specify the 'Default' color - private readonly ConsoleColor? DefaultConsoleColor = null; - - static CompactLogFormatter() - { - var logLevelString = GetLogLevelString(LogLevel.Information); - _messagePadding = new string(' ', logLevelString.Length + _loglevelPadding.Length); - _newLineWithMessagePadding = Environment.NewLine + _messagePadding; - } - - public CompactLogFormatter(IOptionsMonitor options) - { - FormatterOptions = options.CurrentValue; - ReloadLoggerOptions(options.CurrentValue); - _optionsReloadToken = options.OnChange(ReloadLoggerOptions); - } - - private void ReloadLoggerOptions(ColoredConsoleLogFormatterOptions options) - { - FormatterOptions = options; - } - - public void Dispose() - { - _optionsReloadToken?.Dispose(); - } - - internal ColoredConsoleLogFormatterOptions FormatterOptions { get; set; } - - public string Name => ConsoleLogFormatterNames.Compact; - - public LogMessageEntry Format(LogLevel logLevel, string logName, int eventId, TState state, Exception exception, Func formatter, IExternalScopeProvider scopeProvider) - { - var message = formatter(state, exception); - if (!string.IsNullOrEmpty(message) || exception != null) - { - return FormatHelper(logLevel, logName, eventId, message, exception, scopeProvider, state); - } - // TODO: test use case: - return default; - } - - private LogMessageEntry FormatHelper(LogLevel logLevel, string logName, int eventId, string message, Exception exception, IExternalScopeProvider scopeProvider, TState scope) - { - var messages = new List(); - - var logLevelColors = GetLogLevelConsoleColors(logLevel); - var logLevelString = GetLogLevelString(logLevel); - - string timestamp = null; - var timestampFormat = FormatterOptions.TimestampFormat; - if (timestampFormat != null) - { - var dateTime = GetCurrentDateTime(); - timestamp = dateTime.ToString(timestampFormat); - } - if (timestamp != null) - { - messages.Add(new ConsoleMessage(timestamp + " ", null, null)); - } - if (logLevelString != null) - { - messages.Add(new ConsoleMessage(logLevelString + " ", logLevelColors.Background, logLevelColors.Foreground)); - } - - messages.Add(new ConsoleMessage($"{logName}[{eventId}] ", null, null)); - string originalFormat = null; - int count = 0; - - if (scope != null) - { - if (scope is IReadOnlyList> kvpsx) - { - var strings = new List>(); - foreach (var kvp in kvpsx) - { - if (kvp.Key.Contains("{OriginalFormat}")) - { - originalFormat = kvp.Value.ToString(); - } - else - { - strings.Add(kvp); - } - } - int prevIndex = 0; - if (originalFormat != null) - { - foreach (var kvp in kvpsx) - { - if (!kvp.Key.Contains("{OriginalFormat}")) - { - var curIndex = originalFormat.IndexOf("{" + strings.ElementAt(count).Key + "}"); - if (curIndex != -1) - { - var curString = originalFormat.Substring(prevIndex, curIndex - prevIndex); - messages.Add(new ConsoleMessage(curString, null, null)); - // TODO: when DisableColors is true, also uncolor the inner var colors - messages.Add(new ConsoleMessage(strings.ElementAt(count).Value.ToString(), null, ConsoleColor.Cyan)); - prevIndex += curIndex + strings.ElementAt(count).Key.Length + 2; - count++; - } - } - } - } - } - else if (scope is IReadOnlyList> kvps) - { - var strings = new List>(); - foreach (var kvp in kvps) - { - if (kvp.Key.Contains("{OriginalFormat}")) - { - originalFormat = kvp.Value; - } - else - { - strings.Add(kvp); - } - } - int prevIndex = 0; - if (originalFormat != null) - { - foreach (var kvp in kvps) - { - if (!kvp.Key.Contains("{OriginalFormat}")) - { - var curIndex = originalFormat.IndexOf("{" + strings.ElementAt(count).Key + "}"); - if (curIndex != -1) - { - var curString = originalFormat.Substring(prevIndex, curIndex - prevIndex); - messages.Add(new ConsoleMessage(curString, null, null)); - messages.Add(new ConsoleMessage(strings.ElementAt(count).Value, null, ConsoleColor.Cyan)); - prevIndex += curIndex + strings.ElementAt(count).Key.Length + 2; - count++; - } - } - } - } - } - } - - if (!string.IsNullOrEmpty(message)) - { - if (originalFormat == null) - { - messages.Add(new ConsoleMessage(message, null, null)); - } - else if (count == 0) - { - messages.Add(new ConsoleMessage(originalFormat, null, null)); - } - } - - messages.Add(new ConsoleMessage(" ", null, null)); - GetScopeInformation(scopeProvider, messages); - - if (exception != null) - { - // exception message - messages.Add(new ConsoleMessage(" ", null, null)); - messages.Add(new ConsoleMessage(exception.ToString().Replace(Environment.NewLine, " "), null, null)); - // TODO: try to improve readability for exception message. - // TODO: maybe use Compact as default? - } - messages.Add(new ConsoleMessage(Environment.NewLine, null, null)); - - return new LogMessageEntry( - messages: messages.ToArray(), - logAsError: logLevel >= FormatterOptions.LogToStandardErrorThreshold - ); - } - - private DateTime GetCurrentDateTime() - { - return FormatterOptions.UseUtcTimestamp ? DateTime.UtcNow : DateTime.Now; - } - - private static string GetLogLevelString(LogLevel logLevel) - { - switch (logLevel) - { - case LogLevel.Trace: - return "compact_trce"; - case LogLevel.Debug: - return "compact_dbug"; - case LogLevel.Information: - return "compact_info"; - case LogLevel.Warning: - return "compact_warn"; - case LogLevel.Error: - return "compact_fail"; - case LogLevel.Critical: - return "compact_crit"; - default: - throw new ArgumentOutOfRangeException(nameof(logLevel)); - } - } - - private ConsoleColors GetLogLevelConsoleColors(LogLevel logLevel) - { - if (FormatterOptions.DisableColors) - { - return new ConsoleColors(null, null); - } - - // We must explicitly set the background color if we are setting the foreground color, - // since just setting one can look bad on the users console. - switch (logLevel) - { - case LogLevel.Critical: - return new ConsoleColors(ConsoleColor.White, ConsoleColor.Red); - case LogLevel.Error: - return new ConsoleColors(ConsoleColor.Black, ConsoleColor.Red); - case LogLevel.Warning: - return new ConsoleColors(ConsoleColor.Yellow, ConsoleColor.Black); - case LogLevel.Information: - return new ConsoleColors(ConsoleColor.DarkGreen, ConsoleColor.Black); - case LogLevel.Debug: - return new ConsoleColors(ConsoleColor.Gray, ConsoleColor.Black); - case LogLevel.Trace: - return new ConsoleColors(ConsoleColor.Gray, ConsoleColor.Black); - default: - return new ConsoleColors(DefaultConsoleColor, DefaultConsoleColor); - } - } - - private void GetScopeInformation(IExternalScopeProvider scopeProvider, List messages) - { - if (FormatterOptions.IncludeScopes && scopeProvider != null) - { - scopeProvider.ForEachScope((scope, state) => - { - state.Add(new ConsoleMessage("=> ", null, null)); - state.Add(new ConsoleMessage(scope.ToString(), null, ConsoleColor.DarkGray)); - state.Add(new ConsoleMessage(" ", null, null)); - - }, messages); - } - } - - private readonly struct ConsoleColors - { - public ConsoleColors(ConsoleColor? foreground, ConsoleColor? background) - { - Foreground = foreground; - Background = background; - } - - public ConsoleColor? Foreground { get; } - - public ConsoleColor? Background { get; } - } - } -} diff --git a/src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/ConsoleFormatterConstants.cs b/src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/ConsoleLogFormatterNames.cs similarity index 59% rename from src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/ConsoleFormatterConstants.cs rename to src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/ConsoleLogFormatterNames.cs index c094a5e3ec0228..d07d4dd46d8a9d 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/ConsoleFormatterConstants.cs +++ b/src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/ConsoleLogFormatterNames.cs @@ -6,9 +6,8 @@ namespace Microsoft.Extensions.Logging.Console { public static class ConsoleLogFormatterNames { - public const string Compact = nameof(Compact); - public const string Default = nameof(Default); - public const string Json = nameof(Json); - public const string Systemd = nameof(Systemd); + public const string Default = "default"; + public const string Json = "json"; + public const string Systemd = "systemd"; } } diff --git a/src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/DefaultConsoleLogFormatter.cs b/src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/DefaultConsoleLogFormatter.cs index 0b6086c1f79f0d..c488f41a911831 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/DefaultConsoleLogFormatter.cs +++ b/src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/DefaultConsoleLogFormatter.cs @@ -3,8 +3,10 @@ // See the LICENSE file in the project root for more information. using System; -using System.Text; using System.Collections.Generic; +using System.Linq; +using System.Reflection; +using System.Text; using Microsoft.Extensions.Options; namespace Microsoft.Extensions.Logging.Console @@ -29,14 +31,14 @@ static DefaultConsoleLogFormatter() _newLineWithMessagePadding = Environment.NewLine + _messagePadding; } - public DefaultConsoleLogFormatter(IOptionsMonitor options) + public DefaultConsoleLogFormatter(IOptionsMonitor options) { FormatterOptions = options.CurrentValue; ReloadLoggerOptions(options.CurrentValue); _optionsReloadToken = options.OnChange(ReloadLoggerOptions); } - private void ReloadLoggerOptions(ColoredConsoleLogFormatterOptions options) + private void ReloadLoggerOptions(DefaultConsoleLogFormatterOptions options) { FormatterOptions = options; } @@ -48,18 +50,154 @@ public void Dispose() public string Name => ConsoleLogFormatterNames.Default; - internal ColoredConsoleLogFormatterOptions FormatterOptions { get; set; } + internal DefaultConsoleLogFormatterOptions FormatterOptions { get; set; } public LogMessageEntry Format(LogLevel logLevel, string logName, int eventId, TState state, Exception exception, Func formatter, IExternalScopeProvider scopeProvider) { var message = formatter(state, exception); if (!string.IsNullOrEmpty(message) || exception != null) { + if (!FormatterOptions.MultiLine) + { + return FormatHelperCompact(logLevel, logName, eventId, message, exception, scopeProvider, state); + } return Format(logLevel, logName, eventId, message, exception, scopeProvider); } + // TODO: test use case: return default; } + private LogMessageEntry FormatHelperCompact(LogLevel logLevel, string logName, int eventId, string message, Exception exception, IExternalScopeProvider scopeProvider, TState scope) + { + var messages = new List(); + + var logLevelColors = GetLogLevelConsoleColors(logLevel); + var logLevelString = GetLogLevelString(logLevel); + + string timestamp = null; + var timestampFormat = FormatterOptions.TimestampFormat; + if (timestampFormat != null) + { + var dateTime = GetCurrentDateTime(); + timestamp = dateTime.ToString(timestampFormat); + } + if (timestamp != null) + { + messages.Add(new ConsoleMessage(timestamp + " ", null, null)); + } + if (logLevelString != null) + { + messages.Add(new ConsoleMessage(logLevelString + " ", logLevelColors.Background, logLevelColors.Foreground)); + } + + messages.Add(new ConsoleMessage($"{logName}[{eventId}] ", null, null)); + string originalFormat = null; + int count = 0; + + if (scope != null) + { + if (scope is IReadOnlyList> kvpsx) + { + var strings = new List>(); + foreach (var kvp in kvpsx) + { + if (kvp.Key.Contains("{OriginalFormat}")) + { + originalFormat = kvp.Value.ToString(); + } + else + { + strings.Add(kvp); + } + } + int prevIndex = 0; + if (originalFormat != null) + { + foreach (var kvp in kvpsx) + { + if (!kvp.Key.Contains("{OriginalFormat}")) + { + var curIndex = originalFormat.IndexOf("{" + strings.ElementAt(count).Key + "}"); + if (curIndex != -1) + { + var curString = originalFormat.Substring(prevIndex, curIndex - prevIndex); + messages.Add(new ConsoleMessage(curString, null, null)); + // TODO: when DisableColors is true, also uncolor the inner var colors + messages.Add(new ConsoleMessage(strings.ElementAt(count).Value.ToString(), null, ConsoleColor.Cyan)); + prevIndex += curIndex + strings.ElementAt(count).Key.Length + 2; + count++; + } + } + } + } + } + else if (scope is IReadOnlyList> kvps) + { + var strings = new List>(); + foreach (var kvp in kvps) + { + if (kvp.Key.Contains("{OriginalFormat}")) + { + originalFormat = kvp.Value; + } + else + { + strings.Add(kvp); + } + } + int prevIndex = 0; + if (originalFormat != null) + { + foreach (var kvp in kvps) + { + if (!kvp.Key.Contains("{OriginalFormat}")) + { + var curIndex = originalFormat.IndexOf("{" + strings.ElementAt(count).Key + "}"); + if (curIndex != -1) + { + var curString = originalFormat.Substring(prevIndex, curIndex - prevIndex); + messages.Add(new ConsoleMessage(curString, null, null)); + messages.Add(new ConsoleMessage(strings.ElementAt(count).Value, null, ConsoleColor.Cyan)); + prevIndex += curIndex + strings.ElementAt(count).Key.Length + 2; + count++; + } + } + } + } + } + } + + if (!string.IsNullOrEmpty(message)) + { + if (originalFormat == null) + { + messages.Add(new ConsoleMessage(message, null, null)); + } + else if (count == 0) + { + messages.Add(new ConsoleMessage(originalFormat, null, null)); + } + } + + messages.Add(new ConsoleMessage(" ", null, null)); + GetScopeInformation(scopeProvider, messages); + + if (exception != null) + { + // exception message + messages.Add(new ConsoleMessage(" ", null, null)); + messages.Add(new ConsoleMessage(exception.ToString().Replace(Environment.NewLine, " "), null, null)); + // TODO: try to improve readability for exception message. + // TODO: maybe use Compact as default? + } + messages.Add(new ConsoleMessage(Environment.NewLine, null, null)); + + return new LogMessageEntry( + messages: messages.ToArray(), + logAsError: logLevel >= FormatterOptions.LogToStandardErrorThreshold + ); + } + private LogMessageEntry Format(LogLevel logLevel, string logName, int eventId, string message, Exception exception, IExternalScopeProvider scopeProvider) { var logBuilder = _logBuilder; @@ -192,6 +330,20 @@ private ConsoleColors GetLogLevelConsoleColors(LogLevel logLevel) } } + private void GetScopeInformation(IExternalScopeProvider scopeProvider, List messages) + { + if (FormatterOptions.IncludeScopes && scopeProvider != null) + { + scopeProvider.ForEachScope((scope, state) => + { + state.Add(new ConsoleMessage("=> ", null, null)); + state.Add(new ConsoleMessage(scope.ToString(), null, ConsoleColor.DarkGray)); + state.Add(new ConsoleMessage(" ", null, null)); + + }, messages); + } + } + private void GetScopeInformation(StringBuilder stringBuilder, IExternalScopeProvider scopeProvider) { if (FormatterOptions.IncludeScopes && scopeProvider != null) diff --git a/src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/ColoredConsoleLogFormatterOptions.cs b/src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/DefaultConsoleLogFormatterOptions.cs similarity index 72% rename from src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/ColoredConsoleLogFormatterOptions.cs rename to src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/DefaultConsoleLogFormatterOptions.cs index 131b216647ee93..3bf0a036eaddbe 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/ColoredConsoleLogFormatterOptions.cs +++ b/src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/DefaultConsoleLogFormatterOptions.cs @@ -8,13 +8,14 @@ namespace Microsoft.Extensions.Logging.Console { - public class ColoredConsoleLogFormatterOptions : BasicConsoleLogFormatterOptions + public class DefaultConsoleLogFormatterOptions : SystemdConsoleLogFormatterOptions { - public ColoredConsoleLogFormatterOptions() { } + public DefaultConsoleLogFormatterOptions() { } /// /// Disables colors when . /// public bool DisableColors { get; set; } + public bool MultiLine { get; set; } } } diff --git a/src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/JsonConsoleLogFormatter.cs b/src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/JsonConsoleLogFormatter.cs index 85a7cc47903ded..2f72359cdb37b0 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/JsonConsoleLogFormatter.cs +++ b/src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/JsonConsoleLogFormatter.cs @@ -69,7 +69,7 @@ private string WriteJson(LogLevel logLevel, string logName, int eventId, string { foreach (var xx in exception?.StackTrace?.Split(Environment.NewLine)) { - JsonSerializer.Serialize(writer, xx, FormatterOptions.JsonSerializerOptions); + JsonSerializer.Serialize(writer, xx); } } writer.WriteEndArray(); diff --git a/src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/JsonConsoleLogFormatterOptions.cs b/src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/JsonConsoleLogFormatterOptions.cs index 37cb539d21f792..943e1ede59776f 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/JsonConsoleLogFormatterOptions.cs +++ b/src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/JsonConsoleLogFormatterOptions.cs @@ -8,10 +8,9 @@ namespace Microsoft.Extensions.Logging.Console { - public class JsonConsoleLogFormatterOptions : BasicConsoleLogFormatterOptions + public class JsonConsoleLogFormatterOptions : SystemdConsoleLogFormatterOptions { public JsonConsoleLogFormatterOptions() { } public JsonWriterOptions JsonWriterOptions { get; set; } - public JsonSerializerOptions JsonSerializerOptions { get; set; } } } diff --git a/src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/SystemdConsoleLogFormatter.cs b/src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/SystemdConsoleLogFormatter.cs index bc8fb8bfa81aad..86449680a6a898 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/SystemdConsoleLogFormatter.cs +++ b/src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/SystemdConsoleLogFormatter.cs @@ -24,14 +24,14 @@ static SystemdConsoleLogFormatter() _messagePadding = new string(' ', logLevelString.Length + _loglevelPadding.Length); } - public SystemdConsoleLogFormatter(IOptionsMonitor options) + public SystemdConsoleLogFormatter(IOptionsMonitor options) { FormatterOptions = options.CurrentValue; ReloadLoggerOptions(options.CurrentValue); _optionsReloadToken = options.OnChange(ReloadLoggerOptions); } - private void ReloadLoggerOptions(BasicConsoleLogFormatterOptions options) + private void ReloadLoggerOptions(SystemdConsoleLogFormatterOptions options) { FormatterOptions = options; } @@ -43,7 +43,7 @@ public void Dispose() public string Name => ConsoleLogFormatterNames.Systemd; - internal BasicConsoleLogFormatterOptions FormatterOptions { get; set; } + internal SystemdConsoleLogFormatterOptions FormatterOptions { get; set; } public LogMessageEntry Format(LogLevel logLevel, string logName, int eventId, TState state, Exception exception, Func formatter, IExternalScopeProvider scopeProvider) { diff --git a/src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/BasicConsoleLogFormatterOptions.cs b/src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/SystemdConsoleLogFormatterOptions.cs similarity index 84% rename from src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/BasicConsoleLogFormatterOptions.cs rename to src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/SystemdConsoleLogFormatterOptions.cs index d1601d9de308c1..f415a884a27045 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/BasicConsoleLogFormatterOptions.cs +++ b/src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/SystemdConsoleLogFormatterOptions.cs @@ -7,9 +7,9 @@ namespace Microsoft.Extensions.Logging.Console { - public class BasicConsoleLogFormatterOptions + public class SystemdConsoleLogFormatterOptions { - public BasicConsoleLogFormatterOptions() { } + public SystemdConsoleLogFormatterOptions() { } public bool IncludeScopes { get; set; } From 8baee3dcc90672bd011199a6641a967573a1b09b Mon Sep 17 00:00:00 2001 From: Maryam Ariyan Date: Tue, 26 May 2020 10:47:54 -0700 Subject: [PATCH 14/15] rename default to colored --- .../Microsoft.Extensions.Logging.Console.cs | 18 +++++++++--------- .../src/ConsoleLoggerFactoryExtensions.cs | 6 +++--- .../src/ConsoleLoggerOptions.cs | 4 ++-- .../src/ConsoleLoggerProvider.cs | 4 ++-- ...matter.cs => ColoredConsoleLogFormatter.cs} | 12 ++++++------ ...cs => ColoredConsoleLogFormatterOptions.cs} | 4 ++-- .../src/Formatter/ConsoleLogFormatterNames.cs | 2 +- 7 files changed, 25 insertions(+), 25 deletions(-) rename src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/{DefaultConsoleLogFormatter.cs => ColoredConsoleLogFormatter.cs} (97%) rename src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/{DefaultConsoleLogFormatterOptions.cs => ColoredConsoleLogFormatterOptions.cs} (82%) diff --git a/src/libraries/Microsoft.Extensions.Logging.Console/ref/Microsoft.Extensions.Logging.Console.cs b/src/libraries/Microsoft.Extensions.Logging.Console/ref/Microsoft.Extensions.Logging.Console.cs index 49736e21538073..9cab1346c1a8a8 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Console/ref/Microsoft.Extensions.Logging.Console.cs +++ b/src/libraries/Microsoft.Extensions.Logging.Console/ref/Microsoft.Extensions.Logging.Console.cs @@ -14,16 +14,22 @@ public static partial class ConsoleLoggerExtensions public static Microsoft.Extensions.Logging.ILoggingBuilder AddConsole(this Microsoft.Extensions.Logging.ILoggingBuilder builder, string formatterName) { throw null; } public static Microsoft.Extensions.Logging.ILoggingBuilder AddConsoleLogFormatter(this Microsoft.Extensions.Logging.ILoggingBuilder builder) where TFormatter : class, Microsoft.Extensions.Logging.Console.IConsoleLogFormatter where TOptions : class { throw null; } public static Microsoft.Extensions.Logging.ILoggingBuilder AddConsoleLogFormatter(this Microsoft.Extensions.Logging.ILoggingBuilder builder, System.Action configure) where TFormatter : class, Microsoft.Extensions.Logging.Console.IConsoleLogFormatter where TOptions : class { throw null; } - public static Microsoft.Extensions.Logging.ILoggingBuilder UseDefaultConsoleLogFormatter(this Microsoft.Extensions.Logging.ILoggingBuilder builder, System.Action configure) { throw null; } + public static Microsoft.Extensions.Logging.ILoggingBuilder UseColoredConsoleLogFormatter(this Microsoft.Extensions.Logging.ILoggingBuilder builder, System.Action configure) { throw null; } public static Microsoft.Extensions.Logging.ILoggingBuilder UseJsonConsoleLogFormatter(this Microsoft.Extensions.Logging.ILoggingBuilder builder, System.Action configure) { throw null; } public static Microsoft.Extensions.Logging.ILoggingBuilder UseSystemdConsoleLogFormatter(this Microsoft.Extensions.Logging.ILoggingBuilder builder, System.Action configure) { throw null; } } } namespace Microsoft.Extensions.Logging.Console { + public partial class ColoredConsoleLogFormatterOptions : Microsoft.Extensions.Logging.Console.SystemdConsoleLogFormatterOptions + { + public ColoredConsoleLogFormatterOptions() { } + public bool DisableColors { get { throw null; } set { } } + public bool MultiLine { get { throw null; } set { } } + } public static partial class ConsoleLogFormatterNames { - public const string Default = "default"; + public const string Colored = "colored"; public const string Json = "json"; public const string Systemd = "systemd"; } @@ -35,7 +41,7 @@ public enum ConsoleLoggerFormat public partial class ConsoleLoggerOptions { public ConsoleLoggerOptions() { } - [System.ObsoleteAttribute("ConsoleLoggerOptions.DisableColors has been deprecated. Please use DefaultConsoleLogFormatterOptions.DisableColors instead.", false)] + [System.ObsoleteAttribute("ConsoleLoggerOptions.DisableColors has been deprecated. Please use ColoredConsoleLogFormatterOptions.DisableColors instead.", false)] public bool DisableColors { get { throw null; } set { } } [System.ObsoleteAttribute("ConsoleLoggerOptions.Format has been deprecated. Please use ConsoleLoggerOptions.FormatterName instead.", false)] public Microsoft.Extensions.Logging.Console.ConsoleLoggerFormat Format { get { throw null; } set { } } @@ -66,12 +72,6 @@ public readonly partial struct ConsoleMessage public readonly System.ConsoleColor? Foreground; public ConsoleMessage(string message, System.ConsoleColor? background = default(System.ConsoleColor?), System.ConsoleColor? foreground = default(System.ConsoleColor?)) { throw null; } } - public partial class DefaultConsoleLogFormatterOptions : Microsoft.Extensions.Logging.Console.SystemdConsoleLogFormatterOptions - { - public DefaultConsoleLogFormatterOptions() { } - public bool DisableColors { get { throw null; } set { } } - public bool MultiLine { get { throw null; } set { } } - } public partial interface IConsoleLogFormatter { string Name { get; } diff --git a/src/libraries/Microsoft.Extensions.Logging.Console/src/ConsoleLoggerFactoryExtensions.cs b/src/libraries/Microsoft.Extensions.Logging.Console/src/ConsoleLoggerFactoryExtensions.cs index ea2be13fe1cfe3..6dcf3fae7812e5 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Console/src/ConsoleLoggerFactoryExtensions.cs +++ b/src/libraries/Microsoft.Extensions.Logging.Console/src/ConsoleLoggerFactoryExtensions.cs @@ -31,7 +31,7 @@ public static ILoggingBuilder AddConsole(this ILoggingBuilder builder) builder.AddConsoleLogFormatter(); builder.AddConsoleLogFormatter(); - builder.AddConsoleLogFormatter(); + builder.AddConsoleLogFormatter(); builder.Services.TryAddEnumerable(ServiceDescriptor.Singleton()); LoggerProviderOptions.RegisterProviderOptions(builder.Services); @@ -73,7 +73,7 @@ public static ILoggingBuilder AddConsole(this ILoggingBuilder builder, string fo return builder.AddConsole(configure); } - public static ILoggingBuilder UseDefaultConsoleLogFormatter(this ILoggingBuilder builder, Action configure) + public static ILoggingBuilder UseColoredConsoleLogFormatter(this ILoggingBuilder builder, Action configure) { if (configure == null) { @@ -83,7 +83,7 @@ public static ILoggingBuilder UseDefaultConsoleLogFormatter(this ILoggingBuilder builder.AddConsole(); builder.Services.Configure(configure); - Action configureFormatter = (options) => { options.FormatterName = ConsoleLogFormatterNames.Default; }; + Action configureFormatter = (options) => { options.FormatterName = ConsoleLogFormatterNames.Colored; }; builder.Services.Configure(configureFormatter); return builder; diff --git a/src/libraries/Microsoft.Extensions.Logging.Console/src/ConsoleLoggerOptions.cs b/src/libraries/Microsoft.Extensions.Logging.Console/src/ConsoleLoggerOptions.cs index 4288eb30f2b9c1..de9708c188649d 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Console/src/ConsoleLoggerOptions.cs +++ b/src/libraries/Microsoft.Extensions.Logging.Console/src/ConsoleLoggerOptions.cs @@ -12,7 +12,7 @@ namespace Microsoft.Extensions.Logging.Console /// public class ConsoleLoggerOptions { - [System.ObsoleteAttribute("ConsoleLoggerOptions.DisableColors has been deprecated. Please use DefaultConsoleLogFormatterOptions.DisableColors instead.", false)] + [System.ObsoleteAttribute("ConsoleLoggerOptions.DisableColors has been deprecated. Please use ColoredConsoleLogFormatterOptions.DisableColors instead.", false)] public bool DisableColors { get; set; } /// @@ -35,7 +35,7 @@ public ConsoleLoggerFormat Format } else { - FormatterName = ConsoleLogFormatterNames.Default; + FormatterName = ConsoleLogFormatterNames.Colored; } } } diff --git a/src/libraries/Microsoft.Extensions.Logging.Console/src/ConsoleLoggerProvider.cs b/src/libraries/Microsoft.Extensions.Logging.Console/src/ConsoleLoggerProvider.cs index 227f3641c4982e..40277dfd80e050 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Console/src/ConsoleLoggerProvider.cs +++ b/src/libraries/Microsoft.Extensions.Logging.Console/src/ConsoleLoggerProvider.cs @@ -75,7 +75,7 @@ private void ReloadLoggerOptions(ConsoleLoggerOptions options) //} if (logFormatter == null) { - logFormatter = _formatters[ConsoleLogFormatterNames.Default]; + logFormatter = _formatters[ConsoleLogFormatterNames.Colored]; } foreach (var logger in _loggers) @@ -89,7 +89,7 @@ private void UpdateFormatterOptions(IConsoleLogFormatter formatter, ConsoleLogge if (deprecatedFromOptions.FormatterName != null) return; // kept for deprecated apis: - if (formatter is DefaultConsoleLogFormatter defaultFormatter) + if (formatter is ColoredConsoleLogFormatter defaultFormatter) { defaultFormatter.FormatterOptions.DisableColors = deprecatedFromOptions.DisableColors; defaultFormatter.FormatterOptions.IncludeScopes = deprecatedFromOptions.IncludeScopes; diff --git a/src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/DefaultConsoleLogFormatter.cs b/src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/ColoredConsoleLogFormatter.cs similarity index 97% rename from src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/DefaultConsoleLogFormatter.cs rename to src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/ColoredConsoleLogFormatter.cs index c488f41a911831..9e9166087d90b8 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/DefaultConsoleLogFormatter.cs +++ b/src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/ColoredConsoleLogFormatter.cs @@ -11,7 +11,7 @@ namespace Microsoft.Extensions.Logging.Console { - internal class DefaultConsoleLogFormatter : IConsoleLogFormatter, IDisposable + internal class ColoredConsoleLogFormatter : IConsoleLogFormatter, IDisposable { private static readonly string _loglevelPadding = ": "; private static readonly string _messagePadding; @@ -24,21 +24,21 @@ internal class DefaultConsoleLogFormatter : IConsoleLogFormatter, IDisposable [ThreadStatic] private static StringBuilder _logBuilder; - static DefaultConsoleLogFormatter() + static ColoredConsoleLogFormatter() { var logLevelString = GetLogLevelString(LogLevel.Information); _messagePadding = new string(' ', logLevelString.Length + _loglevelPadding.Length); _newLineWithMessagePadding = Environment.NewLine + _messagePadding; } - public DefaultConsoleLogFormatter(IOptionsMonitor options) + public ColoredConsoleLogFormatter(IOptionsMonitor options) { FormatterOptions = options.CurrentValue; ReloadLoggerOptions(options.CurrentValue); _optionsReloadToken = options.OnChange(ReloadLoggerOptions); } - private void ReloadLoggerOptions(DefaultConsoleLogFormatterOptions options) + private void ReloadLoggerOptions(ColoredConsoleLogFormatterOptions options) { FormatterOptions = options; } @@ -48,9 +48,9 @@ public void Dispose() _optionsReloadToken?.Dispose(); } - public string Name => ConsoleLogFormatterNames.Default; + public string Name => ConsoleLogFormatterNames.Colored; - internal DefaultConsoleLogFormatterOptions FormatterOptions { get; set; } + internal ColoredConsoleLogFormatterOptions FormatterOptions { get; set; } public LogMessageEntry Format(LogLevel logLevel, string logName, int eventId, TState state, Exception exception, Func formatter, IExternalScopeProvider scopeProvider) { diff --git a/src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/DefaultConsoleLogFormatterOptions.cs b/src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/ColoredConsoleLogFormatterOptions.cs similarity index 82% rename from src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/DefaultConsoleLogFormatterOptions.cs rename to src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/ColoredConsoleLogFormatterOptions.cs index 3bf0a036eaddbe..ecf33acf6f4429 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/DefaultConsoleLogFormatterOptions.cs +++ b/src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/ColoredConsoleLogFormatterOptions.cs @@ -8,9 +8,9 @@ namespace Microsoft.Extensions.Logging.Console { - public class DefaultConsoleLogFormatterOptions : SystemdConsoleLogFormatterOptions + public class ColoredConsoleLogFormatterOptions : SystemdConsoleLogFormatterOptions { - public DefaultConsoleLogFormatterOptions() { } + public ColoredConsoleLogFormatterOptions() { } /// /// Disables colors when . diff --git a/src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/ConsoleLogFormatterNames.cs b/src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/ConsoleLogFormatterNames.cs index d07d4dd46d8a9d..9d963f628995da 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/ConsoleLogFormatterNames.cs +++ b/src/libraries/Microsoft.Extensions.Logging.Console/src/Formatter/ConsoleLogFormatterNames.cs @@ -6,7 +6,7 @@ namespace Microsoft.Extensions.Logging.Console { public static class ConsoleLogFormatterNames { - public const string Default = "default"; + public const string Colored = "colored"; public const string Json = "json"; public const string Systemd = "systemd"; } From baa7958fde60da4d94acfb6df6d785cde0ae9a11 Mon Sep 17 00:00:00 2001 From: Maryam Ariyan Date: Tue, 26 May 2020 11:15:15 -0700 Subject: [PATCH 15/15] deprecate ConsoleLoggerFormat --- .../ref/Microsoft.Extensions.Logging.Console.cs | 1 + .../src/ConsoleLoggerFormat.cs | 1 + 2 files changed, 2 insertions(+) diff --git a/src/libraries/Microsoft.Extensions.Logging.Console/ref/Microsoft.Extensions.Logging.Console.cs b/src/libraries/Microsoft.Extensions.Logging.Console/ref/Microsoft.Extensions.Logging.Console.cs index 9cab1346c1a8a8..6ccd9a4007a87c 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Console/ref/Microsoft.Extensions.Logging.Console.cs +++ b/src/libraries/Microsoft.Extensions.Logging.Console/ref/Microsoft.Extensions.Logging.Console.cs @@ -33,6 +33,7 @@ public static partial class ConsoleLogFormatterNames public const string Json = "json"; public const string Systemd = "systemd"; } + [System.ObsoleteAttribute("ConsoleLoggerFormat has been deprecated.", false)] public enum ConsoleLoggerFormat { Default = 0, diff --git a/src/libraries/Microsoft.Extensions.Logging.Console/src/ConsoleLoggerFormat.cs b/src/libraries/Microsoft.Extensions.Logging.Console/src/ConsoleLoggerFormat.cs index 5ab4e865c3bfd5..39306a773e9dae 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Console/src/ConsoleLoggerFormat.cs +++ b/src/libraries/Microsoft.Extensions.Logging.Console/src/ConsoleLoggerFormat.cs @@ -7,6 +7,7 @@ namespace Microsoft.Extensions.Logging.Console /// /// Format of messages. /// + [System.ObsoleteAttribute("ConsoleLoggerFormat has been deprecated.", false)] public enum ConsoleLoggerFormat { ///