Skip to content

Instantly share code, notes, and snippets.

@maryamariyan
Created November 5, 2020 18:08
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save maryamariyan/244d4c91c11075857d8f40f176519df1 to your computer and use it in GitHub Desktop.
Save maryamariyan/244d4c91c11075857d8f40f176519df1 to your computer and use it in GitHub Desktop.
LoggerColorBehavior usage
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net5.0</TargetFramework>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="5.0.0-rc.2.20475.5" />
<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="5.0.0-rc.2.20475.5" />
<PackageReference Include="Microsoft.Extensions.Options" Version="5.0.0-rc.2.20475.5" />
</ItemGroup>
</Project>
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Logging.Abstractions;
using Microsoft.Extensions.Logging.Console;
using Microsoft.Extensions.Options;
using System;
using System.IO;
using System.Threading.Tasks;
namespace ConsoleApp77
{
public static class ConsoleLoggerExtensions
{
public static ILoggingBuilder AddCustomFormatter(this ILoggingBuilder builder, Action<CustomOptions> configure)
{
return builder.AddConsole(o => { o.FormatterName = "customName"; })
.AddConsoleFormatter<CustomFormatter, CustomOptions>(configure);
}
}
public class CustomOptions : SimpleConsoleFormatterOptions
{
public string ArbitraryPrefixOnEachMessage { get; set; }
}
class Program
{
public static void Main(string[] args)
{
using var loggerFactory = LoggerFactory.Create(builder =>
{
builder
//.AddSimpleConsole(x => x.ColorBehavior = LoggerColorBehavior.Disabled);
.AddCustomFormatter(o =>
{
o.ArbitraryPrefixOnEachMessage = "<padded prefix from formatter!> ";
o.ColorBehavior = LoggerColorBehavior.Enabled;
});
});
var logger = loggerFactory.CreateLogger<Program>();
logger.LogInformation("Random log \x1B[42mwith green background\x1B[49m message");
}
}
public class CustomFormatter : ConsoleFormatter, IDisposable
{
private IDisposable _optionsReloadToken;
public CustomFormatter(IOptionsMonitor<CustomOptions> options)
// case insensitive name for the formatter
: base("customName")
{
ReloadLoggerOptions(options.CurrentValue);
_optionsReloadToken = options.OnChange(ReloadLoggerOptions);
}
private void ReloadLoggerOptions(CustomOptions options)
{
FormatterOptions = options;
}
public CustomOptions FormatterOptions { get; set; }
public void Dispose()
{
_optionsReloadToken?.Dispose();
}
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)
{
return;
}
if (DisableColors)
{
textWriter.Write(FormatterOptions.ArbitraryPrefixOnEachMessage);
}
else
{
textWriter.WriteWithColor(FormatterOptions.ArbitraryPrefixOnEachMessage, ConsoleColor.Black, ConsoleColor.Blue);
}
textWriter.WriteLine(message);
}
private bool DisableColors =>
FormatterOptions.ColorBehavior == LoggerColorBehavior.Disabled ||
(FormatterOptions.ColorBehavior == LoggerColorBehavior.Default && System.Console.IsOutputRedirected);
}
public static class TextWriterExtensions
{
public static void WriteWithColor(this TextWriter textWriter, string message, ConsoleColor? background, ConsoleColor? foreground)
{
// Order: backgroundcolor, foregroundcolor, Message, reset foregroundcolor, reset backgroundcolor
if (background.HasValue)
{
textWriter.Write(GetBackgroundColorEscapeCode(background.Value));
}
if (foreground.HasValue)
{
textWriter.Write(GetForegroundColorEscapeCode(foreground.Value));
}
textWriter.Write(message);
if (foreground.HasValue)
{
textWriter.Write(DefaultForegroundColor); // reset to default foreground color
}
if (background.HasValue)
{
textWriter.Write(DefaultBackgroundColor); // reset to the background color
}
}
internal const string DefaultForegroundColor = "\x1B[39m\x1B[22m"; // reset to default foreground color
internal const string DefaultBackgroundColor = "\x1B[49m"; // reset to the background color
internal static string GetForegroundColorEscapeCode(ConsoleColor color)
{
return color switch
{
ConsoleColor.Black => "\x1B[30m",
ConsoleColor.DarkRed => "\x1B[31m",
ConsoleColor.DarkGreen => "\x1B[32m",
ConsoleColor.DarkYellow => "\x1B[33m",
ConsoleColor.DarkBlue => "\x1B[34m",
ConsoleColor.DarkMagenta => "\x1B[35m",
ConsoleColor.DarkCyan => "\x1B[36m",
ConsoleColor.Gray => "\x1B[37m",
ConsoleColor.Red => "\x1B[1m\x1B[31m",
ConsoleColor.Green => "\x1B[1m\x1B[32m",
ConsoleColor.Yellow => "\x1B[1m\x1B[33m",
ConsoleColor.Blue => "\x1B[1m\x1B[34m",
ConsoleColor.Magenta => "\x1B[1m\x1B[35m",
ConsoleColor.Cyan => "\x1B[1m\x1B[36m",
ConsoleColor.White => "\x1B[1m\x1B[37m",
_ => DefaultForegroundColor // default foreground color
};
}
internal static string GetBackgroundColorEscapeCode(ConsoleColor color)
{
return color switch
{
ConsoleColor.Black => "\x1B[40m",
ConsoleColor.DarkRed => "\x1B[41m",
ConsoleColor.DarkGreen => "\x1B[42m",
ConsoleColor.DarkYellow => "\x1B[43m",
ConsoleColor.DarkBlue => "\x1B[44m",
ConsoleColor.DarkMagenta => "\x1B[45m",
ConsoleColor.DarkCyan => "\x1B[46m",
ConsoleColor.Gray => "\x1B[47m",
_ => DefaultBackgroundColor // Use default background color
};
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment