2020-07-23 02:24:18 +02:00
using System ;
2021-07-14 23:20:30 +02:00
using System.Collections.Generic ;
2023-11-30 22:57:43 +01:00
using System.IO ;
2020-07-23 02:24:18 +02:00
namespace ExtremelySimpleLogger {
2020-07-23 02:46:34 +02:00
/// <summary>
2023-11-30 22:57:43 +01:00
/// A <see cref="Sink"/> that writes log output to <see cref="Console.Out"/> or <see cref="Console.Error"/>.
2023-12-01 10:54:00 +01:00
/// This class is a variation of the <see cref="WriterSink"/>.
2020-07-23 02:46:34 +02:00
/// </summary>
2020-07-23 02:24:18 +02:00
public class ConsoleSink : Sink {
2020-07-29 14:23:23 +02:00
/// <summary>
2021-07-14 23:20:30 +02:00
/// The <see cref="ConsoleColors"/> that each <see cref="LogLevel"/> is displayed with using this console sink.
2022-01-17 12:49:50 +01:00
/// To edit and query this collection, you can also use <see cref="SetColor"/> and <see cref="GetColor"/>.
2020-07-29 14:23:23 +02:00
/// </summary>
2022-01-17 12:49:50 +01:00
public readonly Dictionary < LogLevel , ConsoleColor > ConsoleColors = new Dictionary < LogLevel , ConsoleColor > {
2021-07-14 23:20:30 +02:00
{ LogLevel . Warn , ConsoleColor . DarkYellow } ,
{ LogLevel . Error , ConsoleColor . DarkRed } ,
{ LogLevel . Fatal , ConsoleColor . DarkRed }
} ;
2023-11-30 22:57:43 +01:00
private readonly TextWriter console ;
2023-12-01 13:17:46 +01:00
private readonly bool useAnsiCodes ;
2023-11-30 22:57:43 +01:00
/// <summary>
/// Creates a new console sink with the given settings.
/// </summary>
/// <param name="error">Whether to log to <see cref="Console.Error"/> instead of <see cref="Console.Out"/>.</param>
2023-12-01 13:17:46 +01:00
/// <param name="useAnsiCodes">Whether to wrap log output text in ANSI escape codes using <see cref="Extensions.WrapAnsiCode"/> instead of using the <see cref="Console.ForegroundColor"/> and <see cref="Console.ResetColor"/>. This may work better on some terminals.</param>
public ConsoleSink ( bool error = false , bool useAnsiCodes = false ) {
2023-11-30 22:57:43 +01:00
this . console = error ? Console . Error : Console . Out ;
2023-12-01 13:17:46 +01:00
this . useAnsiCodes = useAnsiCodes ;
2023-11-30 22:57:43 +01:00
}
2021-07-14 23:20:30 +02:00
2020-07-29 14:23:23 +02:00
/// <summary>
2021-07-14 23:20:30 +02:00
/// Sets the <see cref="ConsoleColor"/> that text with the given <see cref="LogLevel"/> should be displayed with.
/// To set the default color for the log level, simply pass a <see cref="Nullable{ConsoleColor}"/> with no value to <paramref name="color"/>.
2020-07-29 14:23:23 +02:00
/// </summary>
2021-07-14 23:20:30 +02:00
/// <param name="level">The log level to set the color for</param>
/// <param name="color">The color to use, or a <see cref="Nullable{ConsoleColor}"/> with no value to clear the current color</param>
2021-07-14 23:29:13 +02:00
/// <returns>This instance, for chaining</returns>
public virtual ConsoleSink SetColor ( LogLevel level , ConsoleColor ? color ) {
2021-07-14 23:20:30 +02:00
if ( color . HasValue ) {
this . ConsoleColors [ level ] = color . Value ;
} else {
this . ConsoleColors . Remove ( level ) ;
}
2021-07-14 23:29:13 +02:00
return this ;
2021-07-14 23:20:30 +02:00
}
/// <summary>
/// Returns the <see cref="ConsoleColor"/> that text with the given <see cref="LogLevel"/> is displayed with.
/// If text is displayed with the default console color, a <see cref="Nullable{ConsoleColor}"/> without a value is returned.
/// </summary>
/// <param name="level">The log level whose color to query</param>
/// <returns>The console color that text with the log level is displayed with, or a <see cref="Nullable{ConsoleColor}"/> with no value if no color is set</returns>
public virtual ConsoleColor ? GetColor ( LogLevel level ) {
if ( this . ConsoleColors . TryGetValue ( level , out var color ) )
return color ;
return null ;
}
2020-07-29 14:23:23 +02:00
2020-07-23 02:46:34 +02:00
/// <summary>
2022-10-05 18:13:29 +02:00
/// Logs the given message, which has already been formatted using <see cref="Sink.Formatter"/> or <see cref="Logger.DefaultFormatter"/>.
2020-07-23 02:46:34 +02:00
/// </summary>
2020-07-29 14:23:23 +02:00
/// <param name="logger">The logger that the message was passed to</param>
/// <param name="level">The importance level of this message</param>
2020-07-23 02:46:34 +02:00
/// <param name="s">The message to log</param>
2020-07-29 14:23:23 +02:00
protected override void Log ( Logger logger , LogLevel level , string s ) {
2023-12-01 10:54:00 +01:00
lock ( this . console ) {
2021-07-14 23:29:13 +02:00
var color = this . GetColor ( level ) ;
2023-12-01 13:17:46 +01:00
if ( color . HasValue ) {
if ( this . useAnsiCodes ) {
s = s . WrapAnsiCode ( color . Value ) ;
} else {
Console . ForegroundColor = color . Value ;
}
}
2023-11-30 22:57:43 +01:00
this . console . WriteLine ( s ) ;
2023-12-01 13:17:46 +01:00
if ( color . HasValue & & ! this . useAnsiCodes )
2021-07-14 23:20:30 +02:00
Console . ResetColor ( ) ;
2020-07-29 14:23:23 +02:00
}
2020-07-23 02:24:18 +02:00
}
}
2023-11-30 22:57:43 +01:00
}