diff --git a/src/BenchmarkDotNet/Loggers/ConsoleLogger.cs b/src/BenchmarkDotNet/Loggers/ConsoleLogger.cs index f02c6f104d..bfb00eba6c 100644 --- a/src/BenchmarkDotNet/Loggers/ConsoleLogger.cs +++ b/src/BenchmarkDotNet/Loggers/ConsoleLogger.cs @@ -1,4 +1,4 @@ -using BenchmarkDotNet.Detectors; +using BenchmarkDotNet.Detectors; using BenchmarkDotNet.Extensions; using BenchmarkDotNet.Helpers; using BenchmarkDotNet.Portability; @@ -21,6 +21,17 @@ public sealed class ConsoleLogger : ILogger return !(OsDetector.IsAndroid() || OsDetector.IsIOS() || RuntimeInformation.IsWasm || OsDetector.IsTvOS()); }); + private static readonly Lazy ConsoleSupports256Colors = new(() => + { + + var colorTerm = Environment.GetEnvironmentVariable("COLORTERM"); + if (colorTerm == "truecolor" || colorTerm == "24bit") + return true; + + var term = Environment.GetEnvironmentVariable("TERM"); + return term != null && term.Contains("256color"); + }); + private readonly bool unicodeSupport; private readonly Dictionary colorScheme; @@ -54,6 +65,15 @@ private void Write(LogKind logKind, Action write, string text) return; } + if (ConsoleSupports256Colors.Value) + { + var colorIndex = Get256Color(logKind); + Console.Write($"\x1b[38;5;{colorIndex}m"); + write(text); + Console.Write("\x1b[0m"); + return; + } + var colorBefore = Console.ForegroundColor; try @@ -71,20 +91,40 @@ private void Write(LogKind logKind, Action write, string text) } private ConsoleColor GetColor(LogKind logKind) => - colorScheme.ContainsKey(logKind) ? colorScheme[logKind] : DefaultColor; + colorScheme.TryGetValue(logKind, out ConsoleColor value) ? value : DefaultColor; + + private static int Get256Color(LogKind logKind) + { + var scheme = Create256ColorScheme(); + return scheme.TryGetValue(logKind, out int value) ? value : 252; + } private static Dictionary CreateColorfulScheme() => - new Dictionary + new() { { LogKind.Default, ConsoleColor.Gray }, - { LogKind.Help, ConsoleColor.DarkGreen }, + { LogKind.Help, ConsoleColor.Cyan }, { LogKind.Header, ConsoleColor.Magenta }, - { LogKind.Result, ConsoleColor.DarkCyan }, - { LogKind.Statistic, ConsoleColor.Cyan }, - { LogKind.Info, ConsoleColor.DarkYellow }, + { LogKind.Result, ConsoleColor.Blue }, + { LogKind.Statistic, ConsoleColor.DarkCyan }, + { LogKind.Info, ConsoleColor.DarkGray }, { LogKind.Error, ConsoleColor.Red }, - { LogKind.Warning, ConsoleColor.Yellow }, - { LogKind.Hint, ConsoleColor.DarkCyan } + { LogKind.Warning, ConsoleColor.DarkYellow }, + { LogKind.Hint, ConsoleColor.DarkMagenta } + }; + + private static Dictionary Create256ColorScheme() => + new() + { + { LogKind.Default, 244 }, // mid gray - readable on both + { LogKind.Help, 36 }, // teal-green + { LogKind.Header, 127 }, // mid magenta + { LogKind.Result, 33 }, // mid blue + { LogKind.Statistic, 30 }, // darker teal - distinct from Result and Help + { LogKind.Info, 130 }, // dark orange/brown - distinct from Warning + { LogKind.Error, 160 }, // darker red - visible on white without blinding + { LogKind.Warning, 166 }, // orange - distinct from Info + { LogKind.Hint, 98 } // muted purple - distinct from Header }; [PublicAPI]