This browser is no longer supported.
Upgrade to Microsoft Edge to take advantage of the latest features, security updates, and technical support.
Note
Access to this page requires authorization. You can trysigning in orchanging directories.
Access to this page requires authorization. You can trychanging directories.
There are manylogging providers available for common logging needs. You may need to implement a customILoggerProvider when one of the available providers doesn't suit your application needs. In this article, you'll learn how to implement a custom logging provider that can be used to colorize logs in the console.
Tip
The custom logging provider example source code is available in theDocs GitHub repo. For more information, seeGitHub: .NET Docs - Console Custom Logging.
The sample creates different color console entries per log level and event ID using the following configuration type:
using Microsoft.Extensions.Logging;public sealed class ColorConsoleLoggerConfiguration{ public int EventId { get; set; } public Dictionary<LogLevel, ConsoleColor> LogLevelToColorMap { get; set; } = new() { [LogLevel.Information] = ConsoleColor.Green };}The preceding code sets the default level toInformation, the color toGreen, and theEventId is implicitly0.
TheILogger implementation category name is typically the logging source. For example, the type where the logger is created:
using Microsoft.Extensions.Logging;public sealed class ColorConsoleLogger( string name, Func<ColorConsoleLoggerConfiguration> getCurrentConfig) : ILogger{ public IDisposable? BeginScope<TState>(TState state) where TState : notnull => default!; public bool IsEnabled(LogLevel logLevel) => getCurrentConfig().LogLevelToColorMap.ContainsKey(logLevel); public void Log<TState>( LogLevel logLevel, EventId eventId, TState state, Exception? exception, Func<TState, Exception?, string> formatter) { if (!IsEnabled(logLevel)) { return; } ColorConsoleLoggerConfiguration config = getCurrentConfig(); if (config.EventId == 0 || config.EventId == eventId.Id) { ConsoleColor originalColor = Console.ForegroundColor; Console.ForegroundColor = config.LogLevelToColorMap[logLevel]; Console.WriteLine($"[{eventId.Id,2}: {logLevel,-12}]"); Console.ForegroundColor = originalColor; Console.Write($" {name} - "); Console.ForegroundColor = config.LogLevelToColorMap[logLevel]; Console.Write($"{formatter(state, exception)}"); Console.ForegroundColor = originalColor; Console.WriteLine(); } }}The preceding code:
_getCurrentConfig().LogLevelToColorMap.ContainsKey(logLevel) inIsEnabled, so eachlogLevel has a unique logger. In this implementation, each log level requires an explicit configuration entry to log.It's a good practice to callILogger.IsEnabled withinILogger.Log implementations sinceLog can be called by any consumer, and there are no guarantees that it was previously checked. TheIsEnabled method should be very fast in most implementations.
TState state,Exception? exception,The logger is instantiated with thename and aFunc<ColorConsoleLoggerConfiguration>, which returns the current config—this handles updates to the config values as monitored through theIOptionsMonitor<TOptions>.OnChange callback.
Important
TheILogger.Log implementation checks if theconfig.EventId value is set. Whenconfig.EventId is not set or when it matches the exactlogEntry.EventId, the logger logs in color.
TheILoggerProvider object is responsible for creating logger instances. It's not necessary to create a logger instance per category, but it makes sense for some loggers, like NLog or log4net. This strategy allows you to choose different logging output targets per category, as in the following example:
using System.Collections.Concurrent;using System.Runtime.Versioning;using Microsoft.Extensions.Logging;using Microsoft.Extensions.Options;[UnsupportedOSPlatform("browser")][ProviderAlias("ColorConsole")]public sealed class ColorConsoleLoggerProvider : ILoggerProvider{ private readonly IDisposable? _onChangeToken; private ColorConsoleLoggerConfiguration _currentConfig; private readonly ConcurrentDictionary<string, ColorConsoleLogger> _loggers = new(StringComparer.OrdinalIgnoreCase); public ColorConsoleLoggerProvider( IOptionsMonitor<ColorConsoleLoggerConfiguration> config) { _currentConfig = config.CurrentValue; _onChangeToken = config.OnChange(updatedConfig => _currentConfig = updatedConfig); } public ILogger CreateLogger(string categoryName) => _loggers.GetOrAdd(categoryName, name => new ColorConsoleLogger(name, GetCurrentConfig)); private ColorConsoleLoggerConfiguration GetCurrentConfig() => _currentConfig; public void Dispose() { _loggers.Clear(); _onChangeToken?.Dispose(); }}In the preceding code,CreateLogger creates a single instance of theColorConsoleLogger per category name and stores it in theConcurrentDictionary<TKey,TValue>. Additionally, theIOptionsMonitor<TOptions> interface is required to update changes to the underlyingColorConsoleLoggerConfiguration object.
To control the configuration of theColorConsoleLogger, you define an alias on its provider:
[UnsupportedOSPlatform("browser")][ProviderAlias("ColorConsole")]public sealed class ColorConsoleLoggerProvider : ILoggerProviderTheColorConsoleLoggerProvider class defines two class-scoped attributes:
ColorConsoleLogger type isnot supported in the"browser"."ColorConsole" key.The configuration can be specified with any validconfiguration provider. Consider the followingappsettings.json file:
{ "Logging": { "ColorConsole": { "LogLevelToColorMap": { "Information": "DarkGreen", "Warning": "Cyan", "Error": "Red" } } }}This configures the log levels to the following values:
TheInformation log level is set toDarkGreen, which overrides the default value set in theColorConsoleLoggerConfiguration object.
By convention, registering services for dependency injection happens as part of the startup routine of an application. The registration occurs in theProgram class, or could be delegated to aStartup class. In this example, you'll register directly from theProgram.cs.
To add the custom logging provider and corresponding logger, add anILoggerProvider withILoggingBuilder from theHostingHostBuilderExtensions.ConfigureLogging(IHostBuilder, Action<ILoggingBuilder>):
using Microsoft.Extensions.DependencyInjection;using Microsoft.Extensions.Hosting;using Microsoft.Extensions.Logging;HostApplicationBuilder builder = Host.CreateApplicationBuilder(args);builder.Logging.ClearProviders();builder.Logging.AddColorConsoleLogger(configuration =>{ // Replace warning value from appsettings.json of "Cyan" configuration.LogLevelToColorMap[LogLevel.Warning] = ConsoleColor.DarkCyan; // Replace warning value from appsettings.json of "Red" configuration.LogLevelToColorMap[LogLevel.Error] = ConsoleColor.DarkRed;});using IHost host = builder.Build();var logger = host.Services.GetRequiredService<ILogger<Program>>();logger.LogDebug(1, "Does this line get hit?"); // Not loggedlogger.LogInformation(3, "Nothing to see here."); // Logs in ConsoleColor.DarkGreenlogger.LogWarning(5, "Warning... that was odd."); // Logs in ConsoleColor.DarkCyanlogger.LogError(7, "Oops, there was an error."); // Logs in ConsoleColor.DarkRedlogger.LogTrace(5, "== 120."); // Not loggedawait host.RunAsync();TheILoggingBuilder creates one or moreILogger instances. TheILogger instances are used by the framework to log the information.
The configuration from theappsettings.json file overrides the following values:
By convention, extension methods onILoggingBuilder are used to register the custom provider:
using Microsoft.Extensions.DependencyInjection;using Microsoft.Extensions.DependencyInjection.Extensions;using Microsoft.Extensions.Logging;using Microsoft.Extensions.Logging.Configuration;public static class ColorConsoleLoggerExtensions{ public static ILoggingBuilder AddColorConsoleLogger( this ILoggingBuilder builder) { builder.AddConfiguration(); builder.Services.TryAddEnumerable( ServiceDescriptor.Singleton<ILoggerProvider, ColorConsoleLoggerProvider>()); LoggerProviderOptions.RegisterProviderOptions <ColorConsoleLoggerConfiguration, ColorConsoleLoggerProvider>(builder.Services); return builder; } public static ILoggingBuilder AddColorConsoleLogger( this ILoggingBuilder builder, Action<ColorConsoleLoggerConfiguration> configure) { builder.AddColorConsoleLogger(); builder.Services.Configure(configure); return builder; }}Running this simple application will render color output to the console window similar to the following image:

Was this page helpful?
Need help with this topic?
Want to try using Ask Learn to clarify or guide you through this topic?
Was this page helpful?
Want to try using Ask Learn to clarify or guide you through this topic?