Skip to content

Commit

Permalink
[Group 7] Enable nullable annotations for `Microsoft.Extensions.Loggi…
Browse files Browse the repository at this point in the history
…ng.Console` (#67459)

* First pass

* DisallowNull

* Update ctor for ConsoleLoggerProcessor

* Update ctor for ConsoleLogger

* formatters can be null

* Update src/libraries/Microsoft.Extensions.Logging.Console/src/ConsoleLoggerProvider.cs

Co-authored-by: Eric Erhardt <eric.erhardt@microsoft.com>

* Update src/libraries/Microsoft.Extensions.Logging.Console/src/ConsoleLoggerProcessor.cs

Co-authored-by: Eric Erhardt <eric.erhardt@microsoft.com>

* Remove `#nullable enable`

Co-authored-by: Eric Erhardt <eric.erhardt@microsoft.com>
  • Loading branch information
maxkoshevoi and eerhardt committed Apr 8, 2022
1 parent 3b7303a commit bed8bc7
Show file tree
Hide file tree
Showing 18 changed files with 97 additions and 90 deletions.
@@ -1,8 +1,6 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

#nullable enable

using System;

namespace Microsoft.Extensions.Logging
Expand Down
Expand Up @@ -160,7 +160,7 @@ namespace Microsoft.Extensions.Logging.Abstractions
public string Category { get { throw null; } }
public Microsoft.Extensions.Logging.EventId EventId { get { throw null; } }
public System.Exception? Exception { get { throw null; } }
public System.Func<TState, System.Exception?, string>? Formatter { get { throw null; } }
public System.Func<TState, System.Exception?, string> Formatter { get { throw null; } }
public Microsoft.Extensions.Logging.LogLevel LogLevel { get { throw null; } }
public TState State { get { throw null; } }
}
Expand Down
Expand Up @@ -57,6 +57,6 @@ public LogEntry(LogLevel logLevel, string category, EventId eventId, TState stat
/// <summary>
/// Gets the formatter
/// </summary>
public Func<TState, Exception?, string>? Formatter { get; }
public Func<TState, Exception?, string> Formatter { get; }
}
}
Expand Up @@ -29,7 +29,7 @@ public abstract partial class ConsoleFormatter
{
protected ConsoleFormatter(string name) { }
public string Name { get { throw null; } }
public abstract void Write<TState>(in Microsoft.Extensions.Logging.Abstractions.LogEntry<TState> logEntry, Microsoft.Extensions.Logging.IExternalScopeProvider scopeProvider, System.IO.TextWriter textWriter);
public abstract void Write<TState>(in Microsoft.Extensions.Logging.Abstractions.LogEntry<TState> logEntry, Microsoft.Extensions.Logging.IExternalScopeProvider? scopeProvider, System.IO.TextWriter textWriter);
}
public static partial class ConsoleFormatterNames
{
Expand All @@ -42,7 +42,7 @@ public partial class ConsoleFormatterOptions
public ConsoleFormatterOptions() { }
public bool IncludeScopes { get { throw null; } set { } }
[System.Diagnostics.CodeAnalysis.StringSyntaxAttribute("DateTimeFormat")]
public string TimestampFormat { get { throw null; } set { } }
public string? TimestampFormat { get { throw null; } set { } }
public bool UseUtcTimestamp { get { throw null; } set { } }
}
[System.ObsoleteAttribute("ConsoleLoggerFormat has been deprecated.")]
Expand All @@ -58,12 +58,12 @@ public partial class ConsoleLoggerOptions
public bool DisableColors { get { throw null; } set { } }
[System.ObsoleteAttribute("ConsoleLoggerOptions.Format has been deprecated. Use ConsoleLoggerOptions.FormatterName instead.")]
public Microsoft.Extensions.Logging.Console.ConsoleLoggerFormat Format { get { throw null; } set { } }
public string FormatterName { get { throw null; } set { } }
public string? FormatterName { get { throw null; } set { } }
[System.ObsoleteAttribute("ConsoleLoggerOptions.IncludeScopes has been deprecated. Use ConsoleFormatterOptions.IncludeScopes instead.")]
public bool IncludeScopes { get { throw null; } set { } }
public Microsoft.Extensions.Logging.LogLevel LogToStandardErrorThreshold { get { throw null; } set { } }
[System.ObsoleteAttribute("ConsoleLoggerOptions.TimestampFormat has been deprecated. Use ConsoleFormatterOptions.TimestampFormat instead.")]
public string TimestampFormat { get { throw null; } set { } }
public string? TimestampFormat { get { throw null; } set { } }
[System.ObsoleteAttribute("ConsoleLoggerOptions.UseUtcTimestamp has been deprecated. Use ConsoleFormatterOptions.UseUtcTimestamp instead.")]
public bool UseUtcTimestamp { get { throw null; } set { } }
}
Expand All @@ -72,7 +72,7 @@ public partial class ConsoleLoggerOptions
public partial class ConsoleLoggerProvider : Microsoft.Extensions.Logging.ILoggerProvider, Microsoft.Extensions.Logging.ISupportExternalScope, System.IDisposable
{
public ConsoleLoggerProvider(Microsoft.Extensions.Options.IOptionsMonitor<Microsoft.Extensions.Logging.Console.ConsoleLoggerOptions> options) { }
public ConsoleLoggerProvider(Microsoft.Extensions.Options.IOptionsMonitor<Microsoft.Extensions.Logging.Console.ConsoleLoggerOptions> options, System.Collections.Generic.IEnumerable<Microsoft.Extensions.Logging.Console.ConsoleFormatter> formatters) { }
public ConsoleLoggerProvider(Microsoft.Extensions.Options.IOptionsMonitor<Microsoft.Extensions.Logging.Console.ConsoleLoggerOptions> options, System.Collections.Generic.IEnumerable<Microsoft.Extensions.Logging.Console.ConsoleFormatter>? formatters) { }
public Microsoft.Extensions.Logging.ILogger CreateLogger(string name) { throw null; }
public void Dispose() { }
public void SetScopeProvider(Microsoft.Extensions.Logging.IExternalScopeProvider scopeProvider) { }
Expand Down
@@ -1,6 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>$(NetCoreAppCurrent);$(NetCoreAppMinimum);netstandard2.0;$(NetFrameworkMinimum)</TargetFrameworks>
<Nullable>enable</Nullable>
<IncludePlatformAttributes>true</IncludePlatformAttributes>
</PropertyGroup>

Expand Down
Expand Up @@ -32,6 +32,6 @@ protected ConsoleFormatter(string name!!)
/// <param name="scopeProvider">The provider of scope data.</param>
/// <param name="textWriter">The string writer embedding ansi code for colors.</param>
/// <typeparam name="TState">The type of the object to be written.</typeparam>
public abstract void Write<TState>(in LogEntry<TState> logEntry, IExternalScopeProvider scopeProvider, TextWriter textWriter);
public abstract void Write<TState>(in LogEntry<TState> logEntry, IExternalScopeProvider? scopeProvider, TextWriter textWriter);
}
}
Expand Up @@ -23,7 +23,7 @@ public class ConsoleFormatterOptions
/// Gets or sets format string used to format timestamp in logging messages. Defaults to <c>null</c>.
/// </summary>
[StringSyntax(StringSyntaxAttribute.DateTimeFormat)]
public string TimestampFormat { get; set; }
public string? TimestampFormat { get; set; }

/// <summary>
/// Gets or sets indication whether or not UTC timezone should be used to format timestamps in logging messages. Defaults to <c>false</c>.
Expand Down
Expand Up @@ -2,6 +2,7 @@
// The .NET Foundation licenses this file to you under the MIT license.

using System;
using System.Diagnostics.CodeAnalysis;
using System.IO;
using System.Runtime.Versioning;
using Microsoft.Extensions.Logging.Abstractions;
Expand All @@ -14,21 +15,28 @@ internal sealed class ConsoleLogger : ILogger
private readonly string _name;
private readonly ConsoleLoggerProcessor _queueProcessor;

internal ConsoleLogger(string name!!, ConsoleLoggerProcessor loggerProcessor)
internal ConsoleLogger(
string name!!,
ConsoleLoggerProcessor loggerProcessor,
ConsoleFormatter formatter,
IExternalScopeProvider? scopeProvider,
ConsoleLoggerOptions options)
{
_name = name;
_queueProcessor = loggerProcessor;
Formatter = formatter;
ScopeProvider = scopeProvider;
Options = options;
}

internal ConsoleFormatter Formatter { get; set; }
internal IExternalScopeProvider ScopeProvider { get; set; }

internal IExternalScopeProvider? ScopeProvider { get; set; }
internal ConsoleLoggerOptions Options { get; set; }

[ThreadStatic]
private static StringWriter t_stringWriter;
private static StringWriter? t_stringWriter;

public void Log<TState>(LogLevel logLevel, EventId eventId, TState state, Exception exception, Func<TState, Exception, string> formatter)
public void Log<TState>(LogLevel logLevel, EventId eventId, TState state, Exception? exception, Func<TState, Exception?, string> formatter)
{
if (!IsEnabled(logLevel))
{
Expand Down Expand Up @@ -61,6 +69,6 @@ public bool IsEnabled(LogLevel logLevel)
return logLevel != LogLevel.None;
}

public IDisposable BeginScope<TState>(TState state) => ScopeProvider?.Push(state) ?? NullScope.Instance;
public IDisposable BeginScope<TState>(TState state) where TState : notnull => ScopeProvider?.Push(state) ?? NullScope.Instance;
}
}
Expand Up @@ -39,7 +39,7 @@ public ConsoleLoggerFormat Format
/// <summary>
/// Name of the log message formatter to use. Defaults to "simple" />.
/// </summary>
public string FormatterName { get; set; }
public string? FormatterName { get; set; }

/// <summary>
/// Includes scopes when <see langword="true" />.
Expand All @@ -56,7 +56,7 @@ public ConsoleLoggerFormat Format
/// Gets or sets format string used to format timestamp in logging messages. Defaults to <c>null</c>.
/// </summary>
[System.ObsoleteAttribute("ConsoleLoggerOptions.TimestampFormat has been deprecated. Use ConsoleFormatterOptions.TimestampFormat instead.")]
public string TimestampFormat { get; set; }
public string? TimestampFormat { get; set; }

/// <summary>
/// Gets or sets indication whether or not UTC timezone should be used to format timestamps in logging messages. Defaults to <c>false</c>.
Expand Down
Expand Up @@ -3,6 +3,7 @@

using System;
using System.Collections.Concurrent;
using System.Diagnostics.CodeAnalysis;
using System.Runtime.Versioning;
using System.Threading;

Expand All @@ -16,11 +17,13 @@ internal class ConsoleLoggerProcessor : IDisposable
private readonly BlockingCollection<LogMessageEntry> _messageQueue = new BlockingCollection<LogMessageEntry>(_maxQueuedMessages);
private readonly Thread _outputThread;

public IConsole Console;
public IConsole ErrorConsole;
public IConsole Console { get; }
public IConsole ErrorConsole { get; }

public ConsoleLoggerProcessor()
public ConsoleLoggerProcessor(IConsole console, IConsole errorConsole)
{
Console = console;
ErrorConsole = errorConsole;
// Start Console message queue processor
_outputThread = new Thread(ProcessLogQueue)
{
Expand Down
Expand Up @@ -4,6 +4,7 @@
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using Microsoft.Extensions.Options;
Expand All @@ -22,7 +23,7 @@ public class ConsoleLoggerProvider : ILoggerProvider, ISupportExternalScope
private ConcurrentDictionary<string, ConsoleFormatter> _formatters;
private readonly ConsoleLoggerProcessor _messageQueue;

private IDisposable _optionsReloadToken;
private IDisposable? _optionsReloadToken;
private IExternalScopeProvider _scopeProvider = NullExternalScopeProvider.Instance;

/// <summary>
Expand All @@ -37,7 +38,7 @@ public ConsoleLoggerProvider(IOptionsMonitor<ConsoleLoggerOptions> options)
/// </summary>
/// <param name="options">The options to create <see cref="ConsoleLogger"/> instances with.</param>
/// <param name="formatters">Log formatters added for <see cref="ConsoleLogger"/> insteaces.</param>
public ConsoleLoggerProvider(IOptionsMonitor<ConsoleLoggerOptions> options, IEnumerable<ConsoleFormatter> formatters)
public ConsoleLoggerProvider(IOptionsMonitor<ConsoleLoggerOptions> options, IEnumerable<ConsoleFormatter>? formatters)
{
_options = options;
_loggers = new ConcurrentDictionary<string, ConsoleLogger>();
Expand All @@ -46,18 +47,19 @@ public ConsoleLoggerProvider(IOptionsMonitor<ConsoleLoggerOptions> options, IEnu
ReloadLoggerOptions(options.CurrentValue);
_optionsReloadToken = _options.OnChange(ReloadLoggerOptions);

_messageQueue = new ConsoleLoggerProcessor();

IConsole? console;
IConsole? errorConsole;
if (DoesConsoleSupportAnsi())
{
_messageQueue.Console = new AnsiLogConsole();
_messageQueue.ErrorConsole = new AnsiLogConsole(stdErr: true);
console = new AnsiLogConsole();
errorConsole = new AnsiLogConsole(stdErr: true);
}
else
{
_messageQueue.Console = new AnsiParsingLogConsole();
_messageQueue.ErrorConsole = new AnsiParsingLogConsole(stdErr: true);
console = new AnsiParsingLogConsole();
errorConsole = new AnsiParsingLogConsole(stdErr: true);
}
_messageQueue = new ConsoleLoggerProcessor(console, errorConsole);
}

[UnsupportedOSPlatformGuard("windows")]
Expand All @@ -78,7 +80,8 @@ private static bool DoesConsoleSupportAnsi()
return (consoleMode & Interop.Kernel32.ENABLE_VIRTUAL_TERMINAL_PROCESSING) == Interop.Kernel32.ENABLE_VIRTUAL_TERMINAL_PROCESSING;
}

private void SetFormatters(IEnumerable<ConsoleFormatter> formatters = null)
[MemberNotNull(nameof(_formatters))]
private void SetFormatters(IEnumerable<ConsoleFormatter>? formatters = null)
{
var cd = new ConcurrentDictionary<string, ConsoleFormatter>(StringComparer.OrdinalIgnoreCase);

Expand All @@ -105,7 +108,7 @@ private void SetFormatters(IEnumerable<ConsoleFormatter> formatters = null)
// 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)
{
if (options.FormatterName == null || !_formatters.TryGetValue(options.FormatterName, out ConsoleFormatter logFormatter))
if (options.FormatterName == null || !_formatters.TryGetValue(options.FormatterName, out ConsoleFormatter? logFormatter))
{
#pragma warning disable CS0618
logFormatter = options.Format switch
Expand All @@ -130,7 +133,7 @@ private void ReloadLoggerOptions(ConsoleLoggerOptions options)
/// <inheritdoc />
public ILogger CreateLogger(string name)
{
if (_options.CurrentValue.FormatterName == null || !_formatters.TryGetValue(_options.CurrentValue.FormatterName, out ConsoleFormatter logFormatter))
if (_options.CurrentValue.FormatterName == null || !_formatters.TryGetValue(_options.CurrentValue.FormatterName, out ConsoleFormatter? logFormatter))
{
#pragma warning disable CS0618
logFormatter = _options.CurrentValue.Format switch
Expand All @@ -146,14 +149,9 @@ public ILogger CreateLogger(string name)
}
}

return _loggers.TryGetValue(name, out ConsoleLogger logger) ?
return _loggers.TryGetValue(name, out ConsoleLogger? logger) ?
logger :
_loggers.GetOrAdd(name, new ConsoleLogger(name, _messageQueue)
{
Options = _options.CurrentValue,
ScopeProvider = _scopeProvider,
Formatter = logFormatter,
});
_loggers.GetOrAdd(name, new ConsoleLogger(name, _messageQueue, logFormatter, _scopeProvider, _options.CurrentValue));
}

#pragma warning disable CS0618
Expand Down
Expand Up @@ -17,9 +17,9 @@ public FormatterOptionsMonitor(TOptions options)
_options = options;
}

public TOptions Get(string name) => _options;
public TOptions Get(string? name) => _options;

public IDisposable OnChange(Action<TOptions, string> listener)
public IDisposable? OnChange(Action<TOptions, string> listener)
{
return null;
}
Expand Down
Expand Up @@ -3,6 +3,7 @@

using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Globalization;
using System.IO;
using System.Runtime.InteropServices;
Expand All @@ -15,16 +16,16 @@ namespace Microsoft.Extensions.Logging.Console
{
internal sealed class JsonConsoleFormatter : ConsoleFormatter, IDisposable
{
private IDisposable _optionsReloadToken;
private IDisposable? _optionsReloadToken;

public JsonConsoleFormatter(IOptionsMonitor<JsonConsoleFormatterOptions> options)
: base (ConsoleFormatterNames.Json)
: base(ConsoleFormatterNames.Json)
{
ReloadLoggerOptions(options.CurrentValue);
_optionsReloadToken = options.OnChange(ReloadLoggerOptions);
}

public override void Write<TState>(in LogEntry<TState> logEntry, IExternalScopeProvider scopeProvider, TextWriter textWriter)
public override void Write<TState>(in LogEntry<TState> logEntry, IExternalScopeProvider? scopeProvider, TextWriter textWriter)
{
string message = logEntry.Formatter(logEntry.State, logEntry.Exception);
if (logEntry.Exception == null && message == null)
Expand All @@ -34,7 +35,7 @@ public override void Write<TState>(in LogEntry<TState> logEntry, IExternalScopeP
LogLevel logLevel = logEntry.LogLevel;
string category = logEntry.Category;
int eventId = logEntry.EventId.Id;
Exception exception = logEntry.Exception;
Exception? exception = logEntry.Exception;
const int DefaultBufferSize = 1024;
using (var output = new PooledByteBufferWriter(DefaultBufferSize))
{
Expand Down Expand Up @@ -102,7 +103,7 @@ private static string GetLogLevelString(LogLevel logLevel)
};
}

private void WriteScopeInformation(Utf8JsonWriter writer, IExternalScopeProvider scopeProvider)
private void WriteScopeInformation(Utf8JsonWriter writer, IExternalScopeProvider? scopeProvider)
{
if (FormatterOptions.IncludeScopes && scopeProvider != null)
{
Expand Down Expand Up @@ -185,10 +186,11 @@ private static void WriteItem(Utf8JsonWriter writer, KeyValuePair<string, object
}
}

private static string ToInvariantString(object obj) => Convert.ToString(obj, CultureInfo.InvariantCulture);
private static string? ToInvariantString(object? obj) => Convert.ToString(obj, CultureInfo.InvariantCulture);

internal JsonConsoleFormatterOptions FormatterOptions { get; set; }

[MemberNotNull(nameof(FormatterOptions))]
private void ReloadLoggerOptions(JsonConsoleFormatterOptions options)
{
FormatterOptions = options;
Expand Down
@@ -1,9 +1,9 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFrameworks>$(NetCoreAppCurrent);$(NetCoreAppMinimum);netstandard2.0;$(NetFrameworkMinimum)</TargetFrameworks>
<Nullable>enable</Nullable>
<EnableDefaultItems>true</EnableDefaultItems>
<Nullable>annotations</Nullable>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<DefineConstants>$(DefineConstants);NO_SUPPRESS_GC_TRANSITION</DefineConstants>
<!-- Use targeting pack references instead of granular ones in the project file. -->
Expand Down

0 comments on commit bed8bc7

Please sign in to comment.