@@ -8,20 +8,59 @@ open Microsoft.Extensions.Logging.Console
88open Microsoft.Extensions .Logging .Abstractions
99open Microsoft.Extensions .Options
1010
11+ module AnsiColorHelpers =
12+ let private initialConsoleColor = Console.ForegroundColor
13+ // see https://learn.microsoft.com/en-us/dotnet/core/extensions/console-log-formatter#implement-custom-color-formatting
14+ let private ansiForegroundEscapeCodeOfColorConsole color =
15+ match color with
16+ | ConsoleColor.Black -> " \x1B [30m"
17+ | ConsoleColor.DarkRed -> " \x1B [31m"
18+ | ConsoleColor.DarkGreen -> " \x1B [32m"
19+ | ConsoleColor.DarkYellow -> " \x1B [33m"
20+ | ConsoleColor.DarkBlue -> " \x1B [34m"
21+ | ConsoleColor.DarkMagenta -> " \x1B [35m"
22+ | ConsoleColor.DarkCyan -> " \x1B [36m"
23+ | ConsoleColor.Gray -> " \x1B [37m"
24+ | ConsoleColor.Red -> " \x1B [1m\x1B [31m"
25+ | ConsoleColor.Green -> " \x1B [1m\x1B [32m"
26+ | ConsoleColor.Yellow -> " \x1B [1m\x1B [33m"
27+ | ConsoleColor.Blue -> " \x1B [1m\x1B [34m"
28+ | ConsoleColor.Magenta -> " \x1B [1m\x1B [35m"
29+ | ConsoleColor.Cyan -> " \x1B [1m\x1B [36m"
30+ | ConsoleColor.White -> " \x1B [1m\x1B [37m"
31+ | _ ->
32+ #if DEBUG
33+ failwith $" didn't implement ansi code for color: {color}"
34+ #else
35+ // do not break code analyzis to wrong runtime color or such thing for release
36+ " \x1B [37m" // ConsoleColor.Gray
37+ #endif
38+
39+ let consoleColorOfLogLevel logLevel =
40+ match logLevel with
41+ | LogLevel.Error -> ConsoleColor.Red
42+ | LogLevel.Warning -> ConsoleColor.DarkYellow
43+ | LogLevel.Information -> ConsoleColor.Blue
44+ | LogLevel.Trace -> ConsoleColor.Cyan
45+ | _ -> ConsoleColor.Gray
46+
47+ let formatMessageAsAnsiColorizedString ( color : ConsoleColor ) ( message : string ) =
48+ $" {ansiForegroundEscapeCodeOfColorConsole color}{message}{ansiForegroundEscapeCodeOfColorConsole initialConsoleColor}"
49+
1150type CustomOptions () =
1251 inherit ConsoleFormatterOptions()
1352
1453 /// if true: no LogLevel as prefix, colored output according to LogLevel
1554 /// if false: LogLevel as prefix, no colored output
1655 member val UseAnalyzersMsgStyle = false with get, set
56+ member x.UseColoredOutput = x.UseAnalyzersMsgStyle
57+ member x.UseLogLevelAsPrefix = not x.UseAnalyzersMsgStyle
1758
1859type CustomFormatter ( options : IOptionsMonitor < CustomOptions >) as this =
1960 inherit ConsoleFormatter( " customName" )
2061
2162 let mutable optionsReloadToken : IDisposable = null
2263 let mutable formatterOptions = options.CurrentValue
23- let origColor = Console.ForegroundColor
24-
2564 do optionsReloadToken <- options.OnChange( fun x -> this.ReloadLoggerOptions( x))
2665
2766 member private _.ReloadLoggerOptions ( opts : CustomOptions ) = formatterOptions <- opts
@@ -34,14 +73,9 @@ type CustomFormatter(options: IOptionsMonitor<CustomOptions>) as this =
3473 )
3574 =
3675 let message = logEntry.Formatter.Invoke( logEntry.State, logEntry.Exception)
37-
38- if formatterOptions.UseAnalyzersMsgStyle then
39- this.SetColor( textWriter, logEntry.LogLevel)
40- textWriter.WriteLine( message)
41- this.ResetColor()
42- else
76+ if formatterOptions.UseLogLevelAsPrefix then
4377 this.WritePrefix( textWriter, logEntry.LogLevel)
44- textWriter.WriteLine( message)
78+ textWriter.WriteLine message
4579
4680 member private _.WritePrefix ( textWriter : TextWriter , logLevel : LogLevel ) =
4781 match logLevel with
@@ -53,20 +87,6 @@ type CustomFormatter(options: IOptionsMonitor<CustomOptions>) as this =
5387 | LogLevel.Critical -> textWriter.Write( " critical: " )
5488 | _ -> ()
5589
56- // see https://learn.microsoft.com/en-us/dotnet/core/extensions/console-log-formatter
57- member private _.SetColor ( textWriter : TextWriter , logLevel : LogLevel ) =
58- let color =
59- match logLevel with
60- | LogLevel.Error -> " \x1B [1m\x1B [31m" // ConsoleColor.Red
61- | LogLevel.Warning -> " \x1B [33m" // ConsoleColor.DarkYellow
62- | LogLevel.Information -> " \x1B [1m\x1B [34m" // ConsoleColor.Blue
63- | LogLevel.Trace -> " \x1B [1m\x1B [36m" // ConsoleColor.Cyan
64- | _ -> " \x1B [37m" // ConsoleColor.Gray
65-
66- textWriter.Write( color)
67-
68- member private _.ResetColor () = Console.ForegroundColor <- origColor
69-
7090 interface IDisposable with
7191 member _.Dispose () = optionsReloadToken.Dispose()
7292
0 commit comments