1 /** 2 Copyright: Copyright (c) 2018, Joakim Brännström. All rights reserved. 3 License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost Software License 1.0) 4 Author: Joakim Brännström (joakim.brannstrom@gmx.com) 5 6 Handles console logging in pretty colors. 7 8 The module disables colors when stdout and stderr isn't a TTY that support 9 colors. This is to avoid ASCII escape sequences in piped output. 10 */ 11 module colorlog; 12 13 import std.stdio : writefln, stderr, stdout; 14 import logger = std.experimental.logger; 15 import std.experimental.logger : LogLevel; 16 17 public import my.term_color; 18 19 /// The verbosity level of the logging to use. 20 enum VerboseMode { 21 /// Info+ 22 info, 23 /// Trace+ 24 trace, 25 /// Warnings+ 26 warning, 27 } 28 29 /** Configure `std.experimental.logger` with a colorlog instance. 30 */ 31 void confLogger(VerboseMode mode) @safe { 32 final switch (mode) { 33 case VerboseMode.info: 34 logger.globalLogLevel = logger.LogLevel.info; 35 logger.sharedLog = new SimpleLogger(logger.LogLevel.info); 36 break; 37 case VerboseMode.trace: 38 logger.globalLogLevel = logger.LogLevel.all; 39 logger.sharedLog = new DebugLogger(logger.LogLevel.all); 40 break; 41 case VerboseMode.warning: 42 logger.globalLogLevel = logger.LogLevel.warning; 43 logger.sharedLog = new SimpleLogger(logger.LogLevel.info); 44 break; 45 } 46 } 47 48 // The width of the prefix. 49 private immutable _prefixWidth = 8; 50 51 class SimpleLogger : logger.Logger { 52 this(const LogLevel lvl = LogLevel.warning) @safe { 53 super(lvl); 54 initColors; 55 } 56 57 override void writeLogMsg(ref LogEntry payload) @trusted { 58 auto out_ = stderr; 59 auto use_color = Color.red; 60 auto use_mode = Mode.bold; 61 const use_bg = Background.black; 62 63 switch (payload.logLevel) { 64 case LogLevel.trace: 65 out_ = stdout; 66 use_color = Color.white; 67 use_mode = Mode.init; 68 break; 69 case LogLevel.info: 70 out_ = stdout; 71 use_color = Color.white; 72 break; 73 default: 74 } 75 76 import std.conv : to; 77 78 out_.writefln("%s: %s", payload.logLevel.to!string.color(use_color) 79 .bg(use_bg).mode(use_mode), payload.msg); 80 } 81 } 82 83 class DebugLogger : logger.Logger { 84 this(const logger.LogLevel lvl = LogLevel.trace) @safe { 85 super(lvl); 86 initColors; 87 } 88 89 override void writeLogMsg(ref LogEntry payload) @trusted { 90 auto out_ = stderr; 91 auto use_color = Color.red; 92 auto use_mode = Mode.bold; 93 const use_bg = Background.black; 94 95 switch (payload.logLevel) { 96 case LogLevel.trace: 97 out_ = stdout; 98 use_color = Color.white; 99 use_mode = Mode.init; 100 break; 101 case LogLevel.info: 102 out_ = stdout; 103 use_color = Color.white; 104 break; 105 default: 106 } 107 108 import std.conv : to; 109 110 out_.writefln("%s: %s [%s:%d]", payload.logLevel.to!string.color(use_color) 111 .bg(use_bg).mode(use_mode), payload.msg, payload.funcName, payload.line); 112 } 113 }