On Saturday, 30 May 2020 at 18:17:21 UTC, mw wrote:

A related question: how to log to multiple destinations? e.g. both console & log file? any examples?

Thanks.

```D
auto multiLogger = new MultiLogger();
multiLogger.insertLogger("console", new FileLogger(stdout, LogLevel.all)); multiLogger.insertLogger("file", new FileLogger(outputFile, LogLevel.all));

sharedLog = multiLogger;
```
If you are missing color output for log level , you can use this ConsoleLogger

```D
import std.experimental.logger;

/// Extends FileLogger to log only to stdout and colorize log level
class ConsoleLogger : FileLogger
{
    import std.concurrency : Tid;
    import std.datetime.systime : SysTime;
    import std.format : formattedWrite;

    this(const LogLevel lv = LogLevel.all)
    {
        import std.stdio : stdout;
        super(stdout, lv);
    }

/* This method overrides the base class method in order to log to a file without requiring heap allocated memory. Additionally, the `FileLogger`
    local mutex is logged to serialize the log calls.
    */
override protected void beginLogMsg(string file, int line, string funcName,
    string prettyFuncName, string moduleName, LogLevel logLevel,
    Tid threadId, SysTime timestamp, Logger logger)
    @safe
    {
        import std.string : lastIndexOf;
        ptrdiff_t fnIdx = file.lastIndexOf('/') + 1;
        ptrdiff_t funIdx = funcName.lastIndexOf('.') + 1;

        auto lt = this.file_.lockingTextWriter();
        systimeToISOString(lt, timestamp);

        colorizeLogLevel(lt, logLevel);
formattedWrite(lt, " %s:%u:%s ", file[fnIdx .. $], line, funcName[funIdx .. $]);
    }

private void colorizeLogLevel(Writer)(auto ref Writer lt, LogLevel logLevel) @safe
    {
        import std.conv : to;
        auto logLevelStr = logLevel.to!string;

        switch (logLevel) {

            case LogLevel.all:
formattedWrite(lt, " [\033[1;37;40m%s\033[0m] ", logLevelStr);
            break;

            case LogLevel.trace:
formattedWrite(lt, " [\033[1;37;40m%s\033[0m] ", logLevelStr);
            break;

            case LogLevel.info:
formattedWrite(lt, " [\033[1;32;40m%s\033[0m] ", logLevelStr);
            break;

            case LogLevel.warning:
formattedWrite(lt, " [\033[1;33;40m%s\033[0m] ", logLevelStr);
            break;

            case LogLevel.error:
formattedWrite(lt, " [\033[1;31;40m%s\033[0m] ", logLevelStr);
            break;

            case LogLevel.critical:
formattedWrite(lt, " [\033[1;37;41m%s\033[0m]", logLevelStr);
            break;

            case LogLevel.fatal:
formattedWrite(lt, " [\033[1;25;37;41m%s\033[0m] ", logLevelStr);
            break;

            default:
formattedWrite(lt, " [\033[1;37;40m%s\033[0m] ", logLevelStr);
        }
    }
}
```


Reply via email to