// Written in the D programming language.
/**
Source: $(PHOBOSSRC std/logger/core.d)
*/
module std.logger.core;

import core.atomic : atomicLoad, atomicOp, atomicStore, MemoryOrder;
import core.sync.mutex : Mutex;
import std.datetime.date : DateTime;
import std.datetime.systime : Clock, SysTime;
import std.range.primitives;
import std.traits;

import std.logger.filelogger;

/+
    Don’t forget to update the documentation of `std.logger` (`package.d`)
    when changing this test. This is a copy of example code found in its
    doc comment.
 +/
@system unittest
{
    assert(globalLogLevel == LogLevel.all);
    assert((cast() sharedLog).logLevel == LogLevel.info);
}

/** This functions is used at runtime to determine if a `LogLevel` is
active. The same previously defined version statements are used to disable
certain levels. Again the version statements are associated with a compile
unit and can therefore not disable logging in other compile units.
pure bool isLoggingEnabled()(LogLevel ll) @safe nothrow @nogc
*/
bool isLoggingEnabled()(LogLevel ll, LogLevel loggerLL,
    LogLevel globalLL, lazy bool condition = true) @safe
{
    return ll >= globalLL
        && ll >= loggerLL
        && ll != LogLevel.off
        && globalLL != LogLevel.off
        && loggerLL != LogLevel.off
        && condition;
}

/* This function formates a `SysTime` into an `OutputRange`.

The `SysTime` is formatted similar to
$(LREF std.datatime.DateTime.toISOExtString) except the fractional second part.
The fractional second part is in milliseconds and is always 3 digits.
*/
void systimeToISOString(OutputRange)(OutputRange o, const ref SysTime time)
if (isOutputRange!(OutputRange,string))
{
    import std.format.write : formattedWrite;

    const auto dt = cast(DateTime) time;
    const auto fsec = time.fracSecs.total!"msecs";

    formattedWrite(o, "%04d-%02d-%02dT%02d:%02d:%02d.%03d",
        dt.year, dt.month, dt.day, dt.hour, dt.minute, dt.second,
        fsec);
}

/** This function logs data.

In order for the data to be processed, the `LogLevel` of the log call must
be greater or equal to the `LogLevel` of the `sharedLog` and the
`defaultLogLevel`; additionally the condition passed must be `true`.

Params:
  ll = The `LogLevel` used by this log call.
  condition = The condition must be `true` for the data to be logged.
  args = The data that should be logged.

Example:
--------------------
log(LogLevel.warning, true, "Hello World", 3.1415);
--------------------
*/
void log(int line = __LINE__, string file = __FILE__,
    string funcName = __FUNCTION__, string prettyFuncName = __PRETTY_FUNCTION__,
    string moduleName = __MODULE__, A...)(const LogLevel ll,
    lazy bool condition, lazy A args)
if (args.length != 1)
{
    stdThreadLocalLog.log!(line, file, funcName, prettyFuncName, moduleName)
        (ll, condition, args);
}

/// Ditto
void log(T, string moduleName = __MODULE__)(const LogLevel ll,
    lazy bool condition, lazy T arg, int line = __LINE__, string file = __FILE__,
    string funcName = __FUNCTION__, string prettyFuncName = __PRETTY_FUNCTION__)
{
    stdThreadLocalLog.log!(T,moduleName)(ll, condition, arg, line, file, funcName,
        prettyFuncName);
}

/** This function logs data.

In order for the data to be processed the `LogLevel` of the log call must
be greater or equal to the `LogLevel` of the `sharedLog`.

Params:
  ll = The `LogLevel` used by this log call.
  args = The data that should be logged.

Example:
--------------------
log(LogLevel.warning, "Hello World", 3.1415);
--------------------
*/
void log(int line = __LINE__, string file = __FILE__,
    string funcName = __FUNCTION__, string prettyFuncName = __PRETTY_FUNCTION__,
    string moduleName = __MODULE__, A...)(const LogLevel ll, lazy A args)
if (args.length > 1 && !is(Unqual!(A[0]) : bool))
{
    stdThreadLocalLog.log!(line, file, funcName, prettyFuncName, moduleName)
        (ll, args);
}

/// Ditto
void log(T, string moduleName = __MODULE__)(const LogLevel ll, lazy T arg,
    int line = __LINE__, string file = __FILE__, string funcName = __FUNCTION__,
    string prettyFuncName = __PRETTY_FUNCTION__)
{
    stdThreadLocalLog.log!T(ll, arg, line, file, funcName, prettyFuncName,
        moduleName);
}

/** This function logs data.

In order for the data to be processed the `LogLevel` of the
`sharedLog` must be greater or equal to the `defaultLogLevel`
add the condition passed must be `true`.

Params:
  condition = The condition must be `true` for the data to be logged.
  args = The data that should be logged.

Example:
--------------------
log(true, "Hello World", 3.1415);
--------------------
*/
void log(int line = __LINE__, string file = __FILE__,
    string funcName = __FUNCTION__, string prettyFuncName = __PRETTY_FUNCTION__,
    string moduleName = __MODULE__, A...)(lazy bool condition, lazy A args)
if (args.length != 1)
{
    stdThreadLocalLog.log!(line, file, funcName, prettyFuncName, moduleName)
        (stdThreadLocalLog.logLevel, condition, args);
}

/// Ditto
void log(T, string moduleName = __MODULE__)(lazy bool condition, lazy T arg,
    int line = __LINE__, string file = __FILE__, string funcName = __FUNCTION__,
    string prettyFuncName = __PRETTY_FUNCTION__)
{
    stdThreadLocalLog.log!(T,moduleName)(stdThreadLocalLog.logLevel,
        condition, arg, line, file, funcName, prettyFuncName);
}

/** This function logs data.

In order for the data to be processed the `LogLevel` of the
`sharedLog` must be greater or equal to the `defaultLogLevel`.

Params:
  args = The data that should be logged.

Example:
--------------------
log("Hello World", 3.1415);
--------------------
*/
void log(int line = __LINE__, string file = __FILE__,
    string funcName = __FUNCTION__, string prettyFuncName = __PRETTY_FUNCTION__,
    string moduleName = __MODULE__, A...)(lazy A args)
if ((args.length > 1 && !is(Unqual!(A[0]) : bool)
    && !is(Unqual!(A[0]) == LogLevel))
    || args.length == 0)
{
    stdThreadLocalLog.log!(line, file, funcName,
       prettyFuncName, moduleName)(stdThreadLocalLog.logLevel, args);
}

void log(T)(lazy T arg, int line = __LINE__, string file = __FILE__,
    string funcName = __FUNCTION__, string prettyFuncName = __PRETTY_FUNCTION__,
    string moduleName = __MODULE__)
{
    stdThreadLocalLog.log!T(stdThreadLocalLog.logLevel, arg, line, file,
        funcName, prettyFuncName, moduleName);
}

/** This function logs data in a `printf`-style manner.

In order for the data to be processed the `LogLevel` of the log call must
be greater or equal to the `LogLevel` of the `sharedLog` and the
`defaultLogLevel` additionally the condition passed must be `true`.

Params:
  ll = The `LogLevel` used by this log call.
  condition = The condition must be `true` for the data to be logged.
  msg = The `printf`-style string.
  args = The data that should be logged.

Example:
--------------------
logf(LogLevel.warning, true, "Hello World %f", 3.1415);
--------------------
*/
void logf(int line = __LINE__, string file = __FILE__,
    string funcName = __FUNCTION__,
    string prettyFuncName = __PRETTY_FUNCTION__,
    string moduleName = __MODULE__, A...)(const LogLevel ll,
    lazy bool condition, lazy string msg, lazy A args)
{
    stdThreadLocalLog.logf!(line, file, funcName, prettyFuncName, moduleName)
        (ll, condition, msg, args);
}

/** This function logs data in a `printf`-style manner.

In order for the data to be processed the `LogLevel` of the log call must
be greater or equal to the `LogLevel` of the `sharedLog` and the
`defaultLogLevel`.

Params:
  ll = The `LogLevel` used by this log call.
  msg = The `printf`-style string.
  args = The data that should be logged.

Example:
--------------------
logf(LogLevel.warning, "Hello World %f", 3.1415);
--------------------
*/
void logf(int line = __LINE__, string file = __FILE__,
    string funcName = __FUNCTION__, string prettyFuncName = __PRETTY_FUNCTION__,
    string moduleName = __MODULE__, A...)(const LogLevel ll, lazy string msg,
        lazy A args)
{
    stdThreadLocalLog.logf!(line, file, funcName, prettyFuncName, moduleName)
        (ll, msg, args);
}

/** This function logs data in a `printf`-style manner.

In order for the data to be processed the `LogLevel` of the log call must
be greater or equal to the `defaultLogLevel` additionally the condition
passed must be `true`.

Params:
  condition = The condition must be `true` for the data to be logged.
  msg = The `printf`-style string.
  args = The data that should be logged.

Example:
--------------------
logf(true, "Hello World %f", 3.1415);
--------------------
*/
void logf(int line = __LINE__, string file = __FILE__,
    string funcName = __FUNCTION__, string prettyFuncName = __PRETTY_FUNCTION__,
    string moduleName = __MODULE__, A...)(lazy bool condition,
        lazy string msg, lazy A args)
{
    stdThreadLocalLog.logf!(line, file, funcName, prettyFuncName, moduleName)
        (stdThreadLocalLog.logLevel, condition, msg, args);
}

/** This function logs data in a `printf`-style manner.

In order for the data to be processed the `LogLevel` of the log call must
be greater or equal to the `defaultLogLevel`.

Params:
  msg = The `printf`-style string.
  args = The data that should be logged.

Example:
--------------------
logf("Hello World %f", 3.1415);
--------------------
*/
void logf(int line = __LINE__, string file = __FILE__,
    string funcName = __FUNCTION__,
    string prettyFuncName = __PRETTY_FUNCTION__,
    string moduleName = __MODULE__, A...)(lazy string msg, lazy A args)
{
    stdThreadLocalLog.logf!(line, file, funcName,prettyFuncName, moduleName)
        (stdThreadLocalLog.logLevel, msg, args);
}

/** This template provides the global log functions with the `LogLevel`
is encoded in the function name.

The aliases following this template create the public names of these log
functions.
*/
template defaultLogFunction(LogLevel ll)
{
    void defaultLogFunction(int line = __LINE__, string file = __FILE__,
        string funcName = __FUNCTION__,
        string prettyFuncName = __PRETTY_FUNCTION__,
        string moduleName = __MODULE__, A...)(lazy A args)
    if ((args.length > 0 && !is(Unqual!(A[0]) : bool)) || args.length == 0)
    {
            stdThreadLocalLog.memLogFunctions!(ll).logImpl!(line, file, funcName,
                prettyFuncName, moduleName)(args);
    }

    void defaultLogFunction(int line = __LINE__, string file = __FILE__,
        string funcName = __FUNCTION__,
        string prettyFuncName = __PRETTY_FUNCTION__,
        string moduleName = __MODULE__, A...)(lazy bool condition, lazy A args)
    {
        stdThreadLocalLog.memLogFunctions!(ll).logImpl!(line, file, funcName,
            prettyFuncName, moduleName)(condition, args);
    }
}

/** This function logs data to the `stdThreadLocalLog`, optionally depending
on a condition.

In order for the resulting log message to be logged the `LogLevel` must
be greater or equal than the `LogLevel` of the `stdThreadLocalLog` and
must be greater or equal than the global `LogLevel`.
Additionally the `LogLevel` must be greater or equal than the `LogLevel`
of the `stdSharedLogger`.
If a condition is given, it must evaluate to `true`.

Params:
  condition = The condition must be `true` for the data to be logged.
  args = The data that should be logged.

Example:
--------------------
trace(1337, "is number");
info(1337, "is number");
error(1337, "is number");
critical(1337, "is number");
fatal(1337, "is number");
trace(true, 1337, "is number");
info(false, 1337, "is number");
error(true, 1337, "is number");
critical(false, 1337, "is number");
fatal(true, 1337, "is number");
--------------------
*/
alias trace = defaultLogFunction!(LogLevel.trace);
/// Ditto
alias info = defaultLogFunction!(LogLevel.info);
/// Ditto
alias warning = defaultLogFunction!(LogLevel.warning);
/// Ditto
alias error = defaultLogFunction!(LogLevel.error);
/// Ditto
alias critical = defaultLogFunction!(LogLevel.critical);
/// Ditto
alias fatal = defaultLogFunction!(LogLevel.fatal);

/** This template provides the global `printf`-style log functions with
the `LogLevel` is encoded in the function name.

The aliases following this template create the public names of the log
functions.
*/
template defaultLogFunctionf(LogLevel ll)
{
    void defaultLogFunctionf(int line = __LINE__, string file = __FILE__,
        string funcName = __FUNCTION__,
        string prettyFuncName = __PRETTY_FUNCTION__,
        string moduleName = __MODULE__, A...)(lazy string msg, lazy A args)
    {
        stdThreadLocalLog.memLogFunctions!(ll).logImplf!(line, file, funcName,
            prettyFuncName, moduleName)(msg, args);
    }

    void defaultLogFunctionf(int line = __LINE__, string file = __FILE__,
        string funcName = __FUNCTION__,
        string prettyFuncName = __PRETTY_FUNCTION__,
        string moduleName = __MODULE__, A...)(lazy bool condition,
            lazy string msg, lazy A args)
    {
        stdThreadLocalLog.memLogFunctions!(ll).logImplf!(line, file, funcName,
            prettyFuncName, moduleName)(condition, msg, args);
    }
}

/** This function logs data to the `sharedLog` in a `printf`-style
manner.

In order for the resulting log message to be logged the `LogLevel` must
be greater or equal than the `LogLevel` of the `sharedLog` and
must be greater or equal than the global `LogLevel`.
Additionally the `LogLevel` must be greater or equal than the `LogLevel`
of the `stdSharedLogger`.

Params:
  msg = The `printf`-style string.
  args = The data that should be logged.

Example:
--------------------
tracef("is number %d", 1);
infof("is number %d", 2);
errorf("is number %d", 3);
criticalf("is number %d", 4);
fatalf("is number %d", 5);
--------------------

The second version of the function logs data to the `sharedLog` in a $(D
printf)-style manner.

In order for the resulting log message to be logged the `LogLevel` must
be greater or equal than the `LogLevel` of the `sharedLog` and
must be greater or equal than the global `LogLevel`.
Additionally the `LogLevel` must be greater or equal than the `LogLevel`
of the `stdSharedLogger`.

Params:
  condition = The condition must be `true` for the data to be logged.
  msg = The `printf`-style string.
  args = The data that should be logged.

Example:
--------------------
tracef(false, "is number %d", 1);
infof(false, "is number %d", 2);
errorf(true, "is number %d", 3);
criticalf(true, "is number %d", 4);
fatalf(someFunct(), "is number %d", 5);
--------------------
*/
alias tracef = defaultLogFunctionf!(LogLevel.trace);
/// Ditto
alias infof = defaultLogFunctionf!(LogLevel.info);
/// Ditto
alias warningf = defaultLogFunctionf!(LogLevel.warning);
/// Ditto
alias errorf = defaultLogFunctionf!(LogLevel.error);
/// Ditto
alias criticalf = defaultLogFunctionf!(LogLevel.critical);
/// Ditto
alias fatalf = defaultLogFunctionf!(LogLevel.fatal);

private struct MsgRange
{
    import std.traits : isSomeString, isSomeChar;

    private Logger log;

    this(Logger log) @safe
    {
        this.log = log;
    }

    void put(T)(T msg) @safe
    if (isSomeString!T)
    {
        log.logMsgPart(msg);
    }

    void put(dchar elem) @safe
    {
        import std.utf : encode;
        char[4] buffer;
        size_t len = encode(buffer, elem);
        log.logMsgPart(buffer[0 .. len]);
    }
}

private void formatString(A...)(MsgRange oRange, A args)
{
    import std.format.write : formattedWrite;

    foreach (arg; args)
    {
        formattedWrite(oRange, "%s", arg);
    }
}

@system unittest
{
    void dummy() @safe
    {
        auto tl = new TestLogger();
        auto dst = MsgRange(tl);
        formatString(dst, "aaa", "bbb");
    }

    dummy();
}

/**
There are eight usable logging level. These level are $(I all), $(I trace),
$(I info), $(I warning), $(I error), $(I critical), $(I fatal), and $(I off).
If a log function with `LogLevel.fatal` is called the shutdown handler of
that logger is called.
*/
enum LogLevel : ubyte
{
    all = 1, /** Lowest possible assignable `LogLevel`. */
    trace = 32, /** `LogLevel` for tracing the execution of the program. */
    info = 64, /** This level is used to display information about the
                program. */
    warning = 96, /** warnings about the program should be displayed with this
                   level. */
    error = 128, /** Information about errors should be logged with this
                   level.*/
    critical = 160, /** Messages that inform about critical errors should be
                    logged with this level. */
    fatal = 192,   /** Log messages that describe fatal errors should use this
                  level. */
    off = ubyte.max /** Highest possible `LogLevel`. */
}

/** This class is the base of every logger. In order to create a new kind of
logger a deriving class needs to implement the `writeLogMsg` method. By
default this is not thread-safe.

It is also possible to `override` the three methods `beginLogMsg`,
`logMsgPart` and `finishLogMsg` together, this option gives more
flexibility.
*/
abstract class Logger
{
    import std.array : appender, Appender;
    import std.concurrency : thisTid, Tid;

    /** LogEntry is a aggregation combining all information associated
    with a log message. This aggregation will be passed to the method
    writeLogMsg.
    */
    protected struct LogEntry
    {
        /// the filename the log function was called from
        string file;
        /// the line number the log function was called from
        int line;
        /// the name of the function the log function was called from
        string funcName;
        /// the pretty formatted name of the function the log function was
        /// called from
        string prettyFuncName;
        /// the name of the module the log message is coming from
        string moduleName;
        /// the `LogLevel` associated with the log message
        LogLevel logLevel;
        /// thread id of the log message
        Tid threadId;
        /// the time the message was logged
        SysTime timestamp;
        /// the message of the log message
        string msg;
        /// A refernce to the `Logger` used to create this `LogEntry`
        Logger logger;
    }

    /**
    Every subclass of `Logger` has to call this constructor from their
    constructor. It sets the `LogLevel`, and creates a fatal handler. The fatal
    handler will throw an `Error` if a log call is made with level
    `LogLevel.fatal`.

    Params:
         lv = `LogLevel` to use for this `Logger` instance.
    */
    this(this This)(LogLevel lv)
    {
        this.logLevel_ = lv;
        this.fatalHandler_ = delegate() {
            throw new Error("A fatal log message was logged");
        };

        this.mutex = new typeof(mutex)();
    }

    /** A custom logger must implement this method in order to work in a
    `MultiLogger` and `ArrayLogger`.

    Params:
      payload = All information associated with call to log function.

    See_Also: beginLogMsg, logMsgPart, finishLogMsg
    */
    abstract protected void writeLogMsg(ref LogEntry payload) @safe;

    /* The default implementation will use an `std.array.appender`
    internally to construct the message string. This means dynamic,
    GC memory allocation. A logger can avoid this allocation by
    reimplementing `beginLogMsg`, `logMsgPart` and `finishLogMsg`.
    `beginLogMsg` is always called first, followed by any number of calls
    to `logMsgPart` and one call to `finishLogMsg`.

    As an example for such a custom `Logger` compare this:
    ----------------
    class CLogger : Logger
    {
        override void beginLogMsg(string file, int line, string funcName,
            string prettyFuncName, string moduleName, LogLevel logLevel,
            Tid threadId, SysTime timestamp)
        {
            ... logic here
        }

        override void logMsgPart(const(char)[] msg)
        {
            ... logic here
        }

        override void finishLogMsg()
        {
            ... logic here
        }

        void writeLogMsg(ref LogEntry payload)
        {
            this.beginLogMsg(payload.file, payload.line, payload.funcName,
                payload.prettyFuncName, payload.moduleName, payload.logLevel,
                payload.threadId, payload.timestamp, payload.logger);

            this.logMsgPart(payload.msg);
            this.finishLogMsg();
        }
    }
    ----------------
    */
    protected void beginLogMsg(string file, int line, string funcName,
        string prettyFuncName, string moduleName, LogLevel logLevel,
        Tid threadId, SysTime timestamp, Logger logger)
        @safe
    {
        msgAppender = appender!string();
        header = LogEntry(file, line, funcName, prettyFuncName,
            moduleName, logLevel, threadId, timestamp, null, logger);
    }

    /** Logs a part of the log message. */
    protected void logMsgPart(scope const(char)[] msg) @safe
    {
       msgAppender.put(msg);
    }

    /** Signals that the message has been written and no more calls to
    `logMsgPart` follow. */
    protected void finishLogMsg() @safe
    {
        header.msg = msgAppender.data;
        this.writeLogMsg(header);
    }

    /** The `LogLevel` determines if the log call are processed or dropped
    by the `Logger`. In order for the log call to be processed the
    `LogLevel` of the log call must be greater or equal to the `LogLevel`
    of the `logger`.

    These two methods set and get the `LogLevel` of the used `Logger`.

    Example:
    -----------
    auto f = new FileLogger(stdout);
    f.logLevel = LogLevel.info;
    assert(f.logLevel == LogLevel.info);
    -----------
    */
    @property final LogLevel logLevel() const pure @safe @nogc
    {
        return trustedLoad(this.logLevel_);
    }

    /// Ditto
    @property final void logLevel(const LogLevel lv) @safe @nogc
    {
        atomicStore(this.logLevel_, lv);
    }

    /** This `delegate` is called in case a log message with
    `LogLevel.fatal` gets logged.

    By default an `Error` will be thrown.
    */
    @property final void delegate() fatalHandler() @safe @nogc
    {
        synchronized (mutex) return this.fatalHandler_;
    }

    /// Ditto
    @property final void fatalHandler(void delegate() @safe fh) @safe @nogc
    {
        synchronized (mutex) this.fatalHandler_ = fh;
    }

    /** This method allows forwarding log entries from one logger to another.

    `forwardMsg` will ensure proper synchronization and then call
    `writeLogMsg`. This is an API for implementing your own loggers and
    should not be called by normal user code. A notable difference from other
    logging functions is that the `globalLogLevel` wont be evaluated again
    since it is assumed that the caller already checked that.
    */
    void forwardMsg(ref LogEntry payload) @trusted
    {
        if (isLoggingEnabled(payload.logLevel, this.logLevel_,
            globalLogLevel))
        {
            this.writeLogMsg(payload);

            if (payload.logLevel == LogLevel.fatal)
                this.fatalHandler_();
        }
    }

    /** This template provides the log functions for the `Logger` `class`
    with the `LogLevel` encoded in the function name.

    For further information see the two functions defined inside of this
    template.

    The aliases following this template create the public names of these log
    functions.
    */
    template memLogFunctions(LogLevel ll)
    {
        /** This function logs data to the used `Logger`.

        In order for the resulting log message to be logged the `LogLevel`
        must be greater or equal than the `LogLevel` of the used `Logger`
        and must be greater or equal than the global `LogLevel`.

        Params:
          args = The data that should be logged.

        Example:
        --------------------
        auto s = new FileLogger(stdout);
        s.trace(1337, "is number");
        s.info(1337, "is number");
        s.error(1337, "is number");
        s.critical(1337, "is number");
        s.fatal(1337, "is number");
        --------------------
        */
        void logImpl(int line = __LINE__, string file = __FILE__,
            string funcName = __FUNCTION__,
            string prettyFuncName = __PRETTY_FUNCTION__,
            string moduleName = __MODULE__, A...)(lazy A args)
        if (args.length == 0 || (args.length > 0 && !is(A[0] : bool)))
        {
            synchronized (mutex)
            {
                if (isLoggingEnabled(ll, this.logLevel_, globalLogLevel))
                {
                    this.beginLogMsg(file, line, funcName, prettyFuncName,
                        moduleName, ll, thisTid, Clock.currTime, this);

                    auto writer = MsgRange(this);
                    formatString(writer, args);

                    this.finishLogMsg();

                    static if (ll == LogLevel.fatal)
                        this.fatalHandler_();
                }
            }
        }

        /** This function logs data to the used `Logger` depending on a
        condition.

        In order for the resulting log message to be logged the `LogLevel` must
        be greater or equal than the `LogLevel` of the used `Logger` and
        must be greater or equal than the global `LogLevel` additionally the
        condition passed must be `true`.

        Params:
          condition = The condition must be `true` for the data to be logged.
          args = The data that should be logged.

        Example:
        --------------------
        auto s = new FileLogger(stdout);
        s.trace(true, 1337, "is number");
        s.info(false, 1337, "is number");
        s.error(true, 1337, "is number");
        s.critical(false, 1337, "is number");
        s.fatal(true, 1337, "is number");
        --------------------
        */
        void logImpl(int line = __LINE__, string file = __FILE__,
            string funcName = __FUNCTION__,
            string prettyFuncName = __PRETTY_FUNCTION__,
            string moduleName = __MODULE__, A...)(lazy bool condition,
                lazy A args)
        {
            synchronized (mutex)
            {
                if (isLoggingEnabled(ll, this.logLevel_, globalLogLevel,
                                     condition))
                {
                    this.beginLogMsg(file, line, funcName, prettyFuncName,
                        moduleName, ll, thisTid, Clock.currTime, this);

                    auto writer = MsgRange(this);
                    formatString(writer, args);

                    this.finishLogMsg();

                    static if (ll == LogLevel.fatal)
                        this.fatalHandler_();
                }
            }
        }

        /** This function logs data to the used `Logger` in a
        `printf`-style manner.

        In order for the resulting log message to be logged the `LogLevel`
        must be greater or equal than the `LogLevel` of the used `Logger`
        and must be greater or equal than the global `LogLevel` additionally
           the passed condition must be `true`.

        Params:
          condition = The condition must be `true` for the data to be logged.
          msg = The `printf`-style string.
          args = The data that should be logged.

        Example:
        --------------------
        auto s = new FileLogger(stderr);
        s.tracef(true, "is number %d", 1);
        s.infof(true, "is number %d", 2);
        s.errorf(false, "is number %d", 3);
        s.criticalf(someFunc(), "is number %d", 4);
        s.fatalf(true, "is number %d", 5);
        --------------------
        */
        void logImplf(int line = __LINE__, string file = __FILE__,
            string funcName = __FUNCTION__,
            string prettyFuncName = __PRETTY_FUNCTION__,
            string moduleName = __MODULE__, A...)(lazy bool condition,
                lazy string msg, lazy A args)
        {
            synchronized (mutex)
            {
                import std.format.write : formattedWrite;

                if (isLoggingEnabled(ll, this.logLevel_, globalLogLevel,
                                     condition))
                {
                    this.beginLogMsg(file, line, funcName, prettyFuncName,
                        moduleName, ll, thisTid, Clock.currTime, this);

                    auto writer = MsgRange(this);
                    formattedWrite(writer, msg, args);

                    this.finishLogMsg();

                    static if (ll == LogLevel.fatal)
                        this.fatalHandler_();
                }
            }
        }

        /** This function logs data to the used `Logger` in a
        `printf`-style manner.

        In order for the resulting log message to be logged the `LogLevel` must
        be greater or equal than the `LogLevel` of the used `Logger` and
        must be greater or equal than the global `LogLevel`.

        Params:
          msg = The `printf`-style string.
          args = The data that should be logged.

        Example:
        --------------------
        auto s = new FileLogger(stderr);
        s.tracef("is number %d", 1);
        s.infof("is number %d", 2);
        s.errorf("is number %d", 3);
        s.criticalf("is number %d", 4);
        s.fatalf("is number %d", 5);
        --------------------
        */
        void logImplf(int line = __LINE__, string file = __FILE__,
            string funcName = __FUNCTION__,
            string prettyFuncName = __PRETTY_FUNCTION__,
            string moduleName = __MODULE__, A...)(lazy string msg, lazy A args)
        {
            synchronized (mutex)
            {
                import std.format.write : formattedWrite;

                if (isLoggingEnabled(ll, this.logLevel_, globalLogLevel))
                {
                    this.beginLogMsg(file, line, funcName, prettyFuncName,
                        moduleName, ll, thisTid, Clock.currTime, this);

                    auto writer = MsgRange(this);
                    formattedWrite(writer, msg, args);

                    this.finishLogMsg();

                    static if (ll == LogLevel.fatal)
                        this.fatalHandler_();
                }
            }
        }
    }

    /// Ditto
    alias trace = memLogFunctions!(LogLevel.trace).logImpl;
    /// Ditto
    alias tracef = memLogFunctions!(LogLevel.trace).logImplf;
    /// Ditto
    alias info = memLogFunctions!(LogLevel.info).logImpl;
    /// Ditto
    alias infof = memLogFunctions!(LogLevel.info).logImplf;
    /// Ditto
    alias warning = memLogFunctions!(LogLevel.warning).logImpl;
    /// Ditto
    alias warningf = memLogFunctions!(LogLevel.warning).logImplf;
    /// Ditto
    alias error = memLogFunctions!(LogLevel.error).logImpl;
    /// Ditto
    alias errorf = memLogFunctions!(LogLevel.error).logImplf;
    /// Ditto
    alias critical = memLogFunctions!(LogLevel.critical).logImpl;
    /// Ditto
    alias criticalf = memLogFunctions!(LogLevel.critical).logImplf;
    /// Ditto
    alias fatal = memLogFunctions!(LogLevel.fatal).logImpl;
    /// Ditto
    alias fatalf = memLogFunctions!(LogLevel.fatal).logImplf;

    /** This method logs data with the `LogLevel` of the used `Logger`.

    This method takes a `bool` as first argument. In order for the
    data to be processed the `bool` must be `true` and the `LogLevel`
    of the Logger must be greater or equal to the global `LogLevel`.

    Params:
      args = The data that should be logged.
      condition = The condition must be `true` for the data to be logged.
      args = The data that is to be logged.

    Returns: The logger used by the logging function as reference.

    Example:
    --------------------
    auto l = new StdioLogger();
    l.log(1337);
    --------------------
    */
    void log(int line = __LINE__, string file = __FILE__,
        string funcName = __FUNCTION__,
        string prettyFuncName = __PRETTY_FUNCTION__,
        string moduleName = __MODULE__, A...)(const LogLevel ll,
        lazy bool condition, lazy A args)
    if (args.length != 1)
    {
        synchronized (mutex)
        {
            if (isLoggingEnabled(ll, this.logLevel_, globalLogLevel, condition))
            {
                this.beginLogMsg(file, line, funcName, prettyFuncName,
                    moduleName, ll, thisTid, Clock.currTime, this);

                auto writer = MsgRange(this);
                formatString(writer, args);

                this.finishLogMsg();

                if (ll == LogLevel.fatal)
                    this.fatalHandler_();
            }
        }
    }

    /// Ditto
    void log(T, string moduleName = __MODULE__)(const LogLevel ll,
        lazy bool condition, lazy T args, int line = __LINE__,
        string file = __FILE__, string funcName = __FUNCTION__,
        string prettyFuncName = __PRETTY_FUNCTION__)
    {
        synchronized (mutex)
        {
            if (isLoggingEnabled(ll, this.logLevel_, globalLogLevel, condition))
            {
                this.beginLogMsg(file, line, funcName, prettyFuncName,
                    moduleName, ll, thisTid, Clock.currTime, this);
                auto writer = MsgRange(this);
                formatString(writer, args);

                this.finishLogMsg();

                if (ll == LogLevel.fatal)
                    this.fatalHandler_();
            }
        }
    }

    /** This function logs data to the used `Logger` with a specific
    `LogLevel`.

    In order for the resulting log message to be logged the `LogLevel`
    must be greater or equal than the `LogLevel` of the used `Logger`
    and must be greater or equal than the global `LogLevel`.

    Params:
      ll = The specific `LogLevel` used for logging the log message.
      args = The data that should be logged.

    Example:
    --------------------
    auto s = new FileLogger(stdout);
    s.log(LogLevel.trace, 1337, "is number");
    s.log(LogLevel.info, 1337, "is number");
    s.log(LogLevel.warning, 1337, "is number");
    s.log(LogLevel.error, 1337, "is number");
    s.log(LogLevel.fatal, 1337, "is number");
    --------------------
    */
    void log(int line = __LINE__, string file = __FILE__,
        string funcName = __FUNCTION__,
        string prettyFuncName = __PRETTY_FUNCTION__,
        string moduleName = __MODULE__, A...)(const LogLevel ll, lazy A args)
    if ((args.length > 1 && !is(Unqual!(A[0]) : bool)) || args.length == 0)
    {
        synchronized (mutex)
        {
            if (isLoggingEnabled(ll, this.logLevel_, globalLogLevel))
            {
                this.beginLogMsg(file, line, funcName, prettyFuncName,
                    moduleName, ll, thisTid, Clock.currTime, this);

                auto writer = MsgRange(this);
                formatString(writer, args);

                this.finishLogMsg();

                if (ll == LogLevel.fatal)
                    this.fatalHandler_();
            }
        }
    }

    /// Ditto
    void log(T)(const LogLevel ll, lazy T args, int line = __LINE__,
        string file = __FILE__, string funcName = __FUNCTION__,
        string prettyFuncName = __PRETTY_FUNCTION__,
        string moduleName = __MODULE__)
    {
        synchronized (mutex)
        {
            if (isLoggingEnabled(ll, this.logLevel_, globalLogLevel))
            {
                this.beginLogMsg(file, line, funcName, prettyFuncName,
                    moduleName, ll, thisTid, Clock.currTime, this);
                auto writer = MsgRange(this);
                formatString(writer, args);

                this.finishLogMsg();

                if (ll == LogLevel.fatal)
                    this.fatalHandler_();
            }
        }
    }

    /** This function logs data to the used `Logger` depending on a
    explicitly passed condition with the `LogLevel` of the used
    `Logger`.

    In order for the resulting log message to be logged the `LogLevel`
    of the used `Logger` must be greater or equal than the global
    `LogLevel` and the condition must be `true`.

    Params:
      condition = The condition must be `true` for the data to be logged.
      args = The data that should be logged.

    Example:
    --------------------
    auto s = new FileLogger(stdout);
    s.log(true, 1337, "is number");
    s.log(true, 1337, "is number");
    s.log(true, 1337, "is number");
    s.log(false, 1337, "is number");
    s.log(false, 1337, "is number");
    --------------------
    */
    void log(int line = __LINE__, string file = __FILE__,
        string funcName = __FUNCTION__,
        string prettyFuncName = __PRETTY_FUNCTION__,
        string moduleName = __MODULE__, A...)(lazy bool condition, lazy A args)
    if (args.length != 1)
    {
        synchronized (mutex)
        {
            if (isLoggingEnabled(this.logLevel_, this.logLevel_,
                globalLogLevel, condition))
            {
                this.beginLogMsg(file, line, funcName, prettyFuncName,
                    moduleName, this.logLevel_, thisTid, Clock.currTime, this);

                auto writer = MsgRange(this);
                formatString(writer, args);

                this.finishLogMsg();

                if (this.logLevel_ == LogLevel.fatal)
                    this.fatalHandler_();
            }
        }
    }

    /// Ditto
    void log(T)(lazy bool condition, lazy T args, int line = __LINE__,
        string file = __FILE__, string funcName = __FUNCTION__,
        string prettyFuncName = __PRETTY_FUNCTION__,
        string moduleName = __MODULE__)
    {
        synchronized (mutex)
        {
            if (isLoggingEnabled(this.logLevel_, this.logLevel_, globalLogLevel,
                condition))
            {
                this.beginLogMsg(file, line, funcName, prettyFuncName,
                    moduleName, this.logLevel_, thisTid, Clock.currTime, this);
                auto writer = MsgRange(this);
                formatString(writer, args);

                this.finishLogMsg();

                if (this.logLevel_ == LogLevel.fatal)
                    this.fatalHandler_();
            }
        }
    }

    /** This function logs data to the used `Logger` with the `LogLevel`
    of the used `Logger`.

    In order for the resulting log message to be logged the `LogLevel`
    of the used `Logger` must be greater or equal than the global
    `LogLevel`.

    Params:
      args = The data that should be logged.

    Example:
    --------------------
    auto s = new FileLogger(stdout);
    s.log(1337, "is number");
    s.log(info, 1337, "is number");
    s.log(1337, "is number");
    s.log(1337, "is number");
    s.log(1337, "is number");
    --------------------
    */
    void log(int line = __LINE__, string file = __FILE__,
        string funcName = __FUNCTION__,
        string prettyFuncName = __PRETTY_FUNCTION__,
        string moduleName = __MODULE__, A...)(lazy A args)
    if ((args.length > 1
        && !is(Unqual!(A[0]) : bool)
        && !is(immutable A[0] == immutable LogLevel))
        || args.length == 0)
    {
        synchronized (mutex)
        {
            if (isLoggingEnabled(this.logLevel_, this.logLevel_,
                globalLogLevel))
            {
                this.beginLogMsg(file, line, funcName, prettyFuncName,
                    moduleName, this.logLevel_, thisTid, Clock.currTime, this);
                auto writer = MsgRange(this);
                formatString(writer, args);

                this.finishLogMsg();

                if (this.logLevel_ == LogLevel.fatal)
                    this.fatalHandler_();
            }
        }
    }

    /// Ditto
    void log(T)(lazy T arg, int line = __LINE__, string file = __FILE__,
        string funcName = __FUNCTION__,
        string prettyFuncName = __PRETTY_FUNCTION__,
        string moduleName = __MODULE__)
    {
        synchronized (mutex)
        {
            if (isLoggingEnabled(this.logLevel_, this.logLevel_, globalLogLevel))
            {
                this.beginLogMsg(file, line, funcName, prettyFuncName,
                    moduleName, this.logLevel_, thisTid, Clock.currTime, this);
                auto writer = MsgRange(this);
                formatString(writer, arg);

                this.finishLogMsg();

                if (this.logLevel_ == LogLevel.fatal)
                    this.fatalHandler_();
            }
        }
    }

    /** This function logs data to the used `Logger` with a specific
    `LogLevel` and depending on a condition in a `printf`-style manner.

    In order for the resulting log message to be logged the `LogLevel`
    must be greater or equal than the `LogLevel` of the used `Logger`
    and must be greater or equal than the global `LogLevel` and the
    condition must be `true`.

    Params:
      ll = The specific `LogLevel` used for logging the log message.
      condition = The condition must be `true` for the data to be logged.
      msg = The format string used for this log call.
      args = The data that should be logged.

    Example:
    --------------------
    auto s = new FileLogger(stdout);
    s.logf(LogLevel.trace, true ,"%d %s", 1337, "is number");
    s.logf(LogLevel.info, true ,"%d %s", 1337, "is number");
    s.logf(LogLevel.warning, true ,"%d %s", 1337, "is number");
    s.logf(LogLevel.error, false ,"%d %s", 1337, "is number");
    s.logf(LogLevel.fatal, true ,"%d %s", 1337, "is number");
    --------------------
    */
    void logf(int line = __LINE__, string file = __FILE__,
        string funcName = __FUNCTION__,
        string prettyFuncName = __PRETTY_FUNCTION__,
        string moduleName = __MODULE__, A...)(const LogLevel ll,
        lazy bool condition, lazy string msg, lazy A args)
    {
        synchronized (mutex)
        {
            import std.format.write : formattedWrite;

            if (isLoggingEnabled(ll, this.logLevel_, globalLogLevel, condition))
            {
                this.beginLogMsg(file, line, funcName, prettyFuncName,
                    moduleName, ll, thisTid, Clock.currTime, this);

                auto writer = MsgRange(this);
                formattedWrite(writer, msg, args);

                this.finishLogMsg();

                if (ll == LogLevel.fatal)
                    this.fatalHandler_();
            }
        }
    }

    /** This function logs data to the used `Logger` with a specific
    `LogLevel` in a `printf`-style manner.

    In order for the resulting log message to be logged the `LogLevel`
    must be greater or equal than the `LogLevel` of the used `Logger`
    and must be greater or equal than the global `LogLevel`.

    Params:
      ll = The specific `LogLevel` used for logging the log message.
      msg = The format string used for this log call.
      args = The data that should be logged.

    Example:
    --------------------
    auto s = new FileLogger(stdout);
    s.logf(LogLevel.trace, "%d %s", 1337, "is number");
    s.logf(LogLevel.info, "%d %s", 1337, "is number");
    s.logf(LogLevel.warning, "%d %s", 1337, "is number");
    s.logf(LogLevel.error, "%d %s", 1337, "is number");
    s.logf(LogLevel.fatal, "%d %s", 1337, "is number");
    --------------------
    */
    void logf(int line = __LINE__, string file = __FILE__,
        string funcName = __FUNCTION__,
        string prettyFuncName = __PRETTY_FUNCTION__,
        string moduleName = __MODULE__, A...)(const LogLevel ll,
            lazy string msg, lazy A args)
    {
        synchronized (mutex)
        {
            import std.format.write : formattedWrite;

            if (isLoggingEnabled(ll, this.logLevel_, globalLogLevel))
            {
                this.beginLogMsg(file, line, funcName, prettyFuncName,
                    moduleName, ll, thisTid, Clock.currTime, this);

                auto writer = MsgRange(this);
                formattedWrite(writer, msg, args);

                this.finishLogMsg();

                if (ll == LogLevel.fatal)
                    this.fatalHandler_();
            }
        }
    }

    /** This function logs data to the used `Logger` depending on a
    condition with the `LogLevel` of the used `Logger` in a
    `printf`-style manner.

    In order for the resulting log message to be logged the `LogLevel`
    of the used `Logger` must be greater or equal than the global
    `LogLevel` and the condition must be `true`.

    Params:
      condition = The condition must be `true` for the data to be logged.
      msg = The format string used for this log call.
      args = The data that should be logged.

    Example:
    --------------------
    auto s = new FileLogger(stdout);
    s.logf(true ,"%d %s", 1337, "is number");
    s.logf(true ,"%d %s", 1337, "is number");
    s.logf(true ,"%d %s", 1337, "is number");
    s.logf(false ,"%d %s", 1337, "is number");
    s.logf(true ,"%d %s", 1337, "is number");
    --------------------
    */
    void logf(int line = __LINE__, string file = __FILE__,
        string funcName = __FUNCTION__,
        string prettyFuncName = __PRETTY_FUNCTION__,
        string moduleName = __MODULE__, A...)(lazy bool condition,
            lazy string msg, lazy A args)
    {
        synchronized (mutex)
        {
            import std.format.write : formattedWrite;

            if (isLoggingEnabled(this.logLevel_, this.logLevel_, globalLogLevel,
                condition))
            {
                this.beginLogMsg(file, line, funcName, prettyFuncName,
                    moduleName, this.logLevel_, thisTid, Clock.currTime, this);

                auto writer = MsgRange(this);
                formattedWrite(writer, msg, args);

                this.finishLogMsg();

                if (this.logLevel_ == LogLevel.fatal)
                    this.fatalHandler_();
            }
        }
    }

    /** This method logs data to the used `Logger` with the `LogLevel`
    of the this `Logger` in a `printf`-style manner.

    In order for the data to be processed the `LogLevel` of the `Logger`
    must be greater or equal to the global `LogLevel`.

    Params:
      msg = The format string used for this log call.
      args = The data that should be logged.

    Example:
    --------------------
    auto s = new FileLogger(stdout);
    s.logf("%d %s", 1337, "is number");
    s.logf("%d %s", 1337, "is number");
    s.logf("%d %s", 1337, "is number");
    s.logf("%d %s", 1337, "is number");
    s.logf("%d %s", 1337, "is number");
    --------------------
    */
    void logf(int line = __LINE__, string file = __FILE__,
        string funcName = __FUNCTION__,
        string prettyFuncName = __PRETTY_FUNCTION__,
        string moduleName = __MODULE__, A...)(lazy string msg, lazy A args)
    {
        synchronized (mutex)
        {
            import std.format.write : formattedWrite;

            if (isLoggingEnabled(this.logLevel_, this.logLevel_,
                globalLogLevel))
            {
                this.beginLogMsg(file, line, funcName, prettyFuncName,
                    moduleName, this.logLevel_, thisTid, Clock.currTime, this);

                auto writer = MsgRange(this);
                formattedWrite(writer, msg, args);

                this.finishLogMsg();

                if (this.logLevel_ == LogLevel.fatal)
                    this.fatalHandler_();
            }
        }
    }

    private void delegate() @safe fatalHandler_;
    private shared LogLevel logLevel_ = LogLevel.info;
    private Mutex mutex;

    protected Appender!string msgAppender;
    protected LogEntry header;
}

// Thread Global

private shared Logger stdSharedDefaultLogger;
private shared Logger stdSharedLogger;
private shared LogLevel stdLoggerGlobalLogLevel = LogLevel.all;

/* This method returns the global default Logger.
 * Marked @trusted because of excessive reliance on __gshared data
 */
private @property shared(Logger) defaultSharedLoggerImpl() @trusted
{
    import core.lifetime : emplace;
    import std.stdio : stderr;

    __gshared align(__traits(classInstanceAlignment, FileLogger))
        void[__traits(classInstanceSize, FileLogger)] _buffer = void;

    import std.concurrency : initOnce;
    initOnce!stdSharedDefaultLogger({
        auto buffer = cast(ubyte[]) _buffer;
        return cast(shared) emplace!(FileLogger)(buffer, stderr, LogLevel.info);
    }());

    return atomicLoad(stdSharedDefaultLogger);
}

/** This property sets and gets the default `Logger`. Unless set to another
logger by the user, the default logger's log level is LogLevel.info.

Example:
-------------
sharedLog = new shared FileLogger(yourFile);
-------------
The example sets a new `FileLogger` as new `sharedLog`.

If at some point you want to use the original default logger again, you can
use $(D sharedLog = null;). This will put back the original.

Note:
While getting and setting `sharedLog` is thread-safe, it has to be considered
that the returned reference is only a current snapshot and in the following
code, you must make sure no other thread reassigns to it between reading and
writing `sharedLog`.

`sharedLog` is only thread-safe if the used `Logger` is thread-safe.
The default `Logger` is thread-safe.
-------------
if (sharedLog !is myLogger)
    sharedLog = new shared myLogger;
-------------
*/
@property shared(Logger) sharedLog() @safe
{
    // If we have set up our own logger use that
    if (auto logger = atomicLoad!(MemoryOrder.seq)(stdSharedLogger))
    {
        return atomicLoad(logger);
    }
    else
    {
        // Otherwise resort to the default logger
        return defaultSharedLoggerImpl;
    }
}

/// Ditto
@property void sharedLog(shared(Logger) logger) @safe
{
    atomicStore!(MemoryOrder.seq)(stdSharedLogger, atomicLoad(logger));
}

/** These methods get and set the global `LogLevel`.

Every log message with a `LogLevel` lower than the global `LogLevel`
will be discarded before it reaches `writeLogMessage` method of any
`Logger`.
*/
/* Implementation note:
For any public logging call, the global log level shall only be queried once on
entry. Otherwise when another thread changes the level, we would work with
different levels at different spots in the code.
*/
@property LogLevel globalLogLevel() @safe @nogc
{
    return trustedLoad(stdLoggerGlobalLogLevel);
}

/// Ditto
@property void globalLogLevel(LogLevel ll) @safe
{
    trustedStore(stdLoggerGlobalLogLevel, ll);
}

// Thread Local

/** The `StdForwardLogger` will always forward anything to the sharedLog.

The `StdForwardLogger` will not throw if data is logged with $(D
LogLevel.fatal).
*/
class StdForwardLogger : Logger
{
    /** The default constructor for the `StdForwardLogger`.

    Params:
      lv = The `LogLevel` for the `MultiLogger`. By default the $(D
          LogLevel) is `all`.
    */
    this(const LogLevel lv = LogLevel.all) @safe
    {
        super(lv);
        this.fatalHandler = delegate() {};
    }

    override protected void writeLogMsg(ref LogEntry payload) @trusted
    {
        synchronized (sharedLog.mutex)
        {
            (cast() sharedLog).forwardMsg(payload);
        }
    }
}

///
@safe unittest
{
    auto nl1 = new StdForwardLogger(LogLevel.all);
}

@safe unittest
{
    import core.thread : Thread, msecs;

    static class RaceLogger : Logger
    {
        int value;
        this() @safe shared
        {
            super(LogLevel.init);
        }
        override void writeLogMsg(ref LogEntry payload) @safe
        {
            import core.thread : Thread, msecs;
            if (payload.msg == "foo")
            {
                value = 42;
                () @trusted { Thread.sleep(100.msecs); }();
                assert(value == 42, "Another thread changed the value");
            }
            else
            {
                () @trusted { Thread.sleep(50.msecs); } ();
                value = 13;
            }
        }
    }

    auto oldSharedLog = sharedLog;

    sharedLog = new shared RaceLogger;
    scope(exit)
    {
        sharedLog = oldSharedLog;
    }
    Thread toWaitFor;
    () @trusted { toWaitFor = new Thread(() { log("foo"); }).start(); }();
    log("bar");

    () @trusted
    {
        toWaitFor.join();
    }();
}

/** This `LogLevel` is unqiue to every thread.

The thread local `Logger` will use this `LogLevel` to filter log calls
every same way as presented earlier.
*/
//public LogLevel threadLogLevel = LogLevel.all;
private Logger stdLoggerThreadLogger;
private Logger stdLoggerDefaultThreadLogger;

/* This method returns the thread local default Logger.
*/
private @property Logger stdThreadLocalLogImpl() @trusted
{
    import core.lifetime : emplace;

    static align(__traits(classInstanceAlignment, StdForwardLogger))
        void[__traits(classInstanceSize, StdForwardLogger)] buffer;

    if (stdLoggerDefaultThreadLogger is null)
    {
        stdLoggerDefaultThreadLogger = emplace!StdForwardLogger(buffer, LogLevel.all);
    }
    return stdLoggerDefaultThreadLogger;
}

/** This function returns a thread unique `Logger`, that by default
propagates all data logged to it to the `sharedLog`.

These properties can be used to set and get this `Logger`. Every
modification to this `Logger` will only be visible in the thread the
modification has been done from.

This `Logger` is called by the free standing log functions. This allows to
create thread local redirections and still use the free standing log
functions.
*/
@property Logger stdThreadLocalLog() @safe
{
    // If we have set up our own logger use that
    if (auto logger = stdLoggerThreadLogger)
        return logger;
    else
        // Otherwise resort to the default logger
        return stdThreadLocalLogImpl;
}

/// Ditto
@property void stdThreadLocalLog(Logger logger) @safe
{
    stdLoggerThreadLogger = logger;
}

/// Ditto
@system unittest
{
    import std.logger.filelogger : FileLogger;
    import std.file : deleteme, remove;
    Logger l = stdThreadLocalLog;
    stdThreadLocalLog = new FileLogger(deleteme ~ "-someFile.log");
    scope(exit) remove(deleteme ~ "-someFile.log");

    auto tempLog = stdThreadLocalLog;
    stdThreadLocalLog = l;
    destroy(tempLog);
}

@safe unittest
{
    LogLevel ll = globalLogLevel;
    globalLogLevel = LogLevel.fatal;
    assert(globalLogLevel == LogLevel.fatal);
    globalLogLevel = ll;
}

package class TestLogger : Logger
{
    int line = -1;
    string file = null;
    string func = null;
    string prettyFunc = null;
    string msg = null;
    LogLevel lvl;

    this(const LogLevel lv = LogLevel.all) @safe
    {
        super(lv);
    }

    override protected void writeLogMsg(ref LogEntry payload) @safe
    {
        this.line = payload.line;
        this.file = payload.file;
        this.func = payload.funcName;
        this.prettyFunc = payload.prettyFuncName;
        this.lvl = payload.logLevel;
        this.msg = payload.msg;
    }
}

version (StdUnittest) private void testFuncNames(Logger logger) @safe
{
    string s = "I'm here";
    logger.log(s);
}

@safe unittest
{
    auto tl1 = new TestLogger();
    testFuncNames(tl1);
    assert(tl1.func == "std.logger.core.testFuncNames", tl1.func);
    assert(tl1.prettyFunc ==
        "void std.logger.core.testFuncNames(Logger logger) @safe",
        tl1.prettyFunc);
    assert(tl1.msg == "I'm here", tl1.msg);
}

@safe unittest
{
    auto tl1 = new TestLogger(LogLevel.all);
    tl1.log();
    assert(tl1.line == __LINE__ - 1);
    tl1.log(true);
    assert(tl1.line == __LINE__ - 1);
    tl1.log(false);
    assert(tl1.line == __LINE__ - 3);
    tl1.log(LogLevel.info);
    assert(tl1.line == __LINE__ - 1);
    tl1.log(LogLevel.off);
    assert(tl1.line == __LINE__ - 3);
    tl1.log(LogLevel.info, true);
    assert(tl1.line == __LINE__ - 1);
    tl1.log(LogLevel.info, false);
    assert(tl1.line == __LINE__ - 3);

    auto oldunspecificLogger = sharedLog;
    scope(exit) {
        sharedLog = atomicLoad(oldunspecificLogger);
    }

    () @trusted {
        sharedLog = cast(shared) tl1;
    }();

    log();
    assert(tl1.line == __LINE__ - 1);

    log(LogLevel.info);
    assert(tl1.line == __LINE__ - 1);

    log(true);
    assert(tl1.line == __LINE__ - 1);

    log(LogLevel.warning, true);
    assert(tl1.line == __LINE__ - 1);

    trace();
    assert(tl1.line == __LINE__ - 1);
}

@safe unittest
{
    import std.logger.multilogger : MultiLogger;

    auto tl1 = new TestLogger;
    auto tl2 = new TestLogger;

    auto ml = new MultiLogger();
    ml.insertLogger("one", tl1);
    ml.insertLogger("two", tl2);

    string msg = "Hello Logger World";
    ml.log(msg);
    int lineNumber = __LINE__ - 1;
    assert(tl1.msg == msg);
    assert(tl1.line == lineNumber);
    assert(tl2.msg == msg);
    assert(tl2.line == lineNumber);

    ml.removeLogger("one");
    ml.removeLogger("two");
    auto n = ml.removeLogger("one");
    assert(n is null);
}

@safe unittest
{
    bool errorThrown = false;
    auto tl = new TestLogger;
    auto dele = delegate() {
        errorThrown = true;
    };
    tl.fatalHandler = dele;
    tl.fatal();
    assert(errorThrown);
}

@safe unittest
{
    import std.conv : to;
    import std.exception : assertThrown, assertNotThrown;
    import std.format : format;

    auto l = new TestLogger(LogLevel.all);
    string msg = "Hello Logger World";
    l.log(msg);
    int lineNumber = __LINE__ - 1;
    assert(l.msg == msg);
    assert(l.line == lineNumber);
    assert(l.logLevel == LogLevel.all);

    l.log(true, msg);
    lineNumber = __LINE__ - 1;
    assert(l.msg == msg, l.msg);
    assert(l.line == lineNumber);
    assert(l.logLevel == LogLevel.all);

    l.log(false, msg);
    assert(l.msg == msg);
    assert(l.line == lineNumber, to!string(l.line));
    assert(l.logLevel == LogLevel.all);

    msg = "%s Another message";
    l.logf(msg, "Yet");
    lineNumber = __LINE__ - 1;
    assert(l.msg == msg.format("Yet"));
    assert(l.line == lineNumber);
    assert(l.logLevel == LogLevel.all);

    l.logf(true, msg, "Yet");
    lineNumber = __LINE__ - 1;
    assert(l.msg == msg.format("Yet"));
    assert(l.line == lineNumber);
    assert(l.logLevel == LogLevel.all);

    l.logf(false, msg, "Yet");
    assert(l.msg == msg.format("Yet"));
    assert(l.line == lineNumber);
    assert(l.logLevel == LogLevel.all);

    () @trusted {
        assertThrown!Throwable(l.logf(LogLevel.fatal, msg, "Yet"));
    } ();
    lineNumber = __LINE__ - 2;
    assert(l.msg == msg.format("Yet"));
    assert(l.line == lineNumber);
    assert(l.logLevel == LogLevel.all);

    () @trusted {
        assertThrown!Throwable(l.logf(LogLevel.fatal, true, msg, "Yet"));
    } ();
    lineNumber = __LINE__ - 2;
    assert(l.msg == msg.format("Yet"));
    assert(l.line == lineNumber);
    assert(l.logLevel == LogLevel.all);

    assertNotThrown(l.logf(LogLevel.fatal, false, msg, "Yet"));
    assert(l.msg == msg.format("Yet"));
    assert(l.line == lineNumber);
    assert(l.logLevel == LogLevel.all);

    Logger oldunspecificLogger;
    () @trusted {
        oldunspecificLogger = cast() sharedLog;
    }();

    assert(oldunspecificLogger.logLevel == LogLevel.info,
         to!string(oldunspecificLogger.logLevel));

    assert(l.logLevel == LogLevel.all);

    () @trusted {
        sharedLog = cast(shared) l;
    }();

    assert(globalLogLevel == LogLevel.all,
            to!string(globalLogLevel));

    scope(exit)
    {
        () @trusted {
            sharedLog = atomicLoad(cast(shared) oldunspecificLogger);
        }();
    }

    () @trusted {
        assert((cast() sharedLog).logLevel == LogLevel.all);
    }();

    assert(stdThreadLocalLog.logLevel == LogLevel.all);
    assert(globalLogLevel == LogLevel.all);

    msg = "Another message";
    log(msg);
    lineNumber = __LINE__ - 1;
    assert(l.logLevel == LogLevel.all);
    assert(l.line == lineNumber, to!string(l.line));
    assert(l.msg == msg, l.msg);

    log(true, msg);
    lineNumber = __LINE__ - 1;
    assert(l.msg == msg);
    assert(l.line == lineNumber);
    assert(l.logLevel == LogLevel.all);

    log(false, msg);
    assert(l.msg == msg);
    assert(l.line == lineNumber);
    assert(l.logLevel == LogLevel.all);

    msg = "%s Another message";
    logf(msg, "Yet");
    lineNumber = __LINE__ - 1;
    assert(l.msg == msg.format("Yet"));
    assert(l.line == lineNumber);
    assert(l.logLevel == LogLevel.all);

    logf(true, msg, "Yet");
    lineNumber = __LINE__ - 1;
    assert(l.msg == msg.format("Yet"));
    assert(l.line == lineNumber);
    assert(l.logLevel == LogLevel.all);

    logf(false, msg, "Yet");
    assert(l.msg == msg.format("Yet"));
    assert(l.line == lineNumber);
    assert(l.logLevel == LogLevel.all);

    msg = "%s Another message";
    () @trusted {
        assertThrown!Throwable(logf(LogLevel.fatal, msg, "Yet"));
    } ();
    lineNumber = __LINE__ - 2;
    assert(l.msg == msg.format("Yet"), l.msg);
    assert(l.line == lineNumber);
    assert(l.logLevel == LogLevel.all);

    () @trusted {
        assertThrown!Throwable(logf(LogLevel.fatal, true, msg, "Yet"));
    } ();
    lineNumber = __LINE__ - 2;
    assert(l.msg == msg.format("Yet"));
    assert(l.line == lineNumber);
    assert(l.logLevel == LogLevel.all);

    assertNotThrown(logf(LogLevel.fatal, false, msg, "Yet"));
    assert(l.msg == msg.format("Yet"));
    assert(l.line == lineNumber);
    assert(l.logLevel == LogLevel.all);
}

@system unittest // default logger
{
    import std.file : deleteme, exists, remove;
    import std.stdio : File;
    import std.string : indexOf;

    string filename = deleteme ~ __FUNCTION__ ~ ".tempLogFile";
    FileLogger l = new FileLogger(filename);
    auto oldunspecificLogger = sharedLog;

    sharedLog = cast(shared) l;

    scope(exit)
    {
        remove(filename);
        assert(!exists(filename));
        sharedLog = atomicLoad(oldunspecificLogger);
        globalLogLevel = LogLevel.all;
    }

    string notWritten = "this should not be written to file";
    string written = "this should be written to file";

    globalLogLevel = LogLevel.critical;
    assert(globalLogLevel == LogLevel.critical);

    log(LogLevel.warning, notWritten);
    log(LogLevel.critical, written);

    l.file.flush();
    l.file.close();

    auto file = File(filename, "r");
    assert(!file.eof);

    string readLine = file.readln();
    assert(readLine.indexOf(written) != -1, readLine);
    assert(readLine.indexOf(notWritten) == -1, readLine);
    file.close();
}

@system unittest
{
    import std.file : deleteme, remove;
    import std.stdio : File;
    import std.string : indexOf;

    string filename = deleteme ~ __FUNCTION__ ~ ".tempLogFile";
    auto oldunspecificLogger = sharedLog;

    scope(exit)
    {
        remove(filename);
        sharedLog = atomicLoad(oldunspecificLogger);
        globalLogLevel = LogLevel.all;
    }

    string notWritten = "this should not be written to file";
    string written = "this should be written to file";

    auto l = new FileLogger(filename);
    sharedLog = cast(shared) l;

    () @trusted {
        (cast() sharedLog).logLevel = LogLevel.critical;
    }();

    log(LogLevel.error, false, notWritten);
    log(LogLevel.critical, true, written);
    destroy(l);

    auto file = File(filename, "r");
    auto readLine = file.readln();
    assert(!readLine.empty, readLine);
    assert(readLine.indexOf(written) != -1);
    assert(readLine.indexOf(notWritten) == -1);
    file.close();
}

@safe unittest
{
    import std.conv : to;

    auto tl = new TestLogger(LogLevel.all);
    int l = __LINE__;
    tl.info("a");
    assert(tl.line == l+1);
    assert(tl.msg == "a");
    assert(tl.logLevel == LogLevel.all);
    assert(globalLogLevel == LogLevel.all);
    l = __LINE__;
    tl.trace("b");
    assert(tl.msg == "b", tl.msg);
    assert(tl.line == l+1, to!string(tl.line));
}

// testing possible log conditions
@safe unittest
{
    import std.conv : to;
    import std.format : format;
    import std.string : indexOf;

    auto oldunspecificLogger = sharedLog;

    auto mem = new TestLogger;
    mem.fatalHandler = delegate() {};

    () @trusted {
        sharedLog = cast(shared) mem;
    }();

    scope(exit)
    {
        sharedLog = atomicLoad(oldunspecificLogger);
        globalLogLevel = LogLevel.all;
    }

    int value = 0;
    foreach (gll; [cast(LogLevel) LogLevel.all, LogLevel.trace,
            LogLevel.info, LogLevel.warning, LogLevel.error,
            LogLevel.critical, LogLevel.fatal, LogLevel.off])
    {

        globalLogLevel = gll;

        foreach (ll; [cast(LogLevel) LogLevel.all, LogLevel.trace,
                LogLevel.info, LogLevel.warning, LogLevel.error,
                LogLevel.critical, LogLevel.fatal, LogLevel.off])
        {

            mem.logLevel = ll;

            foreach (cond; [true, false])
            {
                foreach (condValue; [true, false])
                {
                    foreach (memOrG; [true, false])
                    {
                        foreach (prntf; [true, false])
                        {
                            foreach (ll2; [cast(LogLevel) LogLevel.all, LogLevel.trace,
                                    LogLevel.info, LogLevel.warning,
                                    LogLevel.error, LogLevel.critical,
                                    LogLevel.fatal, LogLevel.off])
                            {
                                foreach (singleMulti; 0 .. 2)
                                {
                                    int lineCall;
                                    mem.msg = "-1";
                                    if (memOrG)
                                    {
                                        if (prntf)
                                        {
                                            if (cond)
                                            {
                                                if (singleMulti == 0)
                                                {
                                                    mem.logf(ll2, condValue, "%s",
                                                        value);
                                                    lineCall = __LINE__;
                                                }
                                                else
                                                {
                                                    mem.logf(ll2, condValue,
                                                        "%d %d", value, value);
                                                    lineCall = __LINE__;
                                                }
                                            }
                                            else
                                            {
                                                if (singleMulti == 0)
                                                {
                                                    mem.logf(ll2, "%s", value);
                                                    lineCall = __LINE__;
                                                }
                                                else
                                                {
                                                    mem.logf(ll2, "%d %d",
                                                        value, value);
                                                    lineCall = __LINE__;
                                                }
                                            }
                                        }
                                        else
                                        {
                                            if (cond)
                                            {
                                                if (singleMulti == 0)
                                                {
                                                    mem.log(ll2, condValue,
                                                        to!string(value));
                                                    lineCall = __LINE__;
                                                }
                                                else
                                                {
                                                    mem.log(ll2, condValue,
                                                        to!string(value), value);
                                                    lineCall = __LINE__;
                                                }
                                            }
                                            else
                                            {
                                                if (singleMulti == 0)
                                                {
                                                    mem.log(ll2, to!string(value));
                                                    lineCall = __LINE__;
                                                }
                                                else
                                                {
                                                    mem.log(ll2,
                                                        to!string(value),
                                                        value);
                                                    lineCall = __LINE__;
                                                }
                                            }
                                        }
                                    }
                                    else
                                    {
                                        if (prntf)
                                        {
                                            if (cond)
                                            {
                                                if (singleMulti == 0)
                                                {
                                                    logf(ll2, condValue, "%s",
                                                        value);
                                                    lineCall = __LINE__;
                                                }
                                                else
                                                {
                                                    logf(ll2, condValue,
                                                        "%s %d", value, value);
                                                    lineCall = __LINE__;
                                                }
                                            }
                                            else
                                            {
                                                if (singleMulti == 0)
                                                {
                                                    logf(ll2, "%s", value);
                                                    lineCall = __LINE__;
                                                }
                                                else
                                                {
                                                    logf(ll2, "%s %s", value,
                                                        value);
                                                    lineCall = __LINE__;
                                                }
                                            }
                                        }
                                        else
                                        {
                                            if (cond)
                                            {
                                                if (singleMulti == 0)
                                                {
                                                    log(ll2, condValue,
                                                        to!string(value));
                                                    lineCall = __LINE__;
                                                }
                                                else
                                                {
                                                    log(ll2, condValue, value,
                                                        to!string(value));
                                                    lineCall = __LINE__;
                                                }
                                            }
                                            else
                                            {
                                                if (singleMulti == 0)
                                                {
                                                    log(ll2, to!string(value));
                                                    lineCall = __LINE__;
                                                }
                                                else
                                                {
                                                    log(ll2, value,
                                                        to!string(value));
                                                    lineCall = __LINE__;
                                                }
                                            }
                                        }
                                    }

                                    string valueStr = to!string(value);
                                    ++value;

                                    bool ll2Off = (ll2 != LogLevel.off);
                                    bool gllOff = (gll != LogLevel.off);
                                    bool llOff = (ll != LogLevel.off);
                                    bool condFalse = (cond ? condValue : true);
                                    bool ll2VSgll = (ll2 >= gll);
                                    bool ll2VSll = (ll2 >= ll);

                                    bool shouldLog = ll2Off && gllOff && llOff
                                        && condFalse && ll2VSgll && ll2VSll;

                                    /*
                                    writefln(
                                        "go(%b) ll2o(%b) c(%b) lg(%b) ll(%b) s(%b)"
                                        , gll != LogLevel.off, ll2 != LogLevel.off,
                                        cond ? condValue : true,
                                        ll2 >= gll, ll2 >= ll, shouldLog);
                                    */


                                    if (shouldLog)
                                    {
                                        assert(mem.msg.indexOf(valueStr) != -1,
                                            format(
                                            "lineCall(%d) ll2Off(%u) gll(%u) ll(%u) ll2(%u) " ~
                                            "cond(%b) condValue(%b)" ~
                                            " memOrG(%b) shouldLog(%b) %s == %s" ~
                                            " %b %b %b %b %b",
                                            lineCall, ll2Off, gll, ll, ll2, cond,
                                            condValue, memOrG, shouldLog, mem.msg,
                                            valueStr, gllOff, llOff, condFalse,
                                            ll2VSgll, ll2VSll
                                        ));
                                    }
                                    else
                                    {
                                        assert(mem.msg.indexOf(valueStr),
                                            format(
                                            "lineCall(%d) ll2Off(%u) gll(%u) ll(%u) ll2(%u) " ~
                                            "cond(%b) condValue(%b)" ~
                                            " memOrG(%b) shouldLog(%b) %s == %s" ~
                                            " %b %b %b %b %b",
                                            lineCall, ll2Off, gll, ll, ll2, cond,
                                            condValue, memOrG, shouldLog, mem.msg,
                                            valueStr, gllOff, llOff, condFalse,
                                            ll2VSgll, ll2VSll
                                        ));
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}

// more testing
@safe unittest
{
    import std.conv : to;
    import std.format : format;
    import std.string : indexOf;

    auto oldunspecificLogger = sharedLog;

    auto mem = new TestLogger;
    mem.fatalHandler = delegate() {};

    () @trusted {
        sharedLog = cast(shared) mem;
    }();

    scope(exit)
    {
        sharedLog = atomicLoad(oldunspecificLogger);
        globalLogLevel = LogLevel.all;
    }

    int value = 0;
    foreach (gll; [cast(LogLevel) LogLevel.all, LogLevel.trace,
            LogLevel.info, LogLevel.warning, LogLevel.error,
            LogLevel.critical, LogLevel.fatal, LogLevel.off])
    {

        globalLogLevel = gll;

        foreach (ll; [cast(LogLevel) LogLevel.all, LogLevel.trace,
                LogLevel.info, LogLevel.warning, LogLevel.error,
                LogLevel.critical, LogLevel.fatal, LogLevel.off])
        {
            mem.logLevel = ll;

            foreach (tll; [cast(LogLevel) LogLevel.all, LogLevel.trace,
                    LogLevel.info, LogLevel.warning, LogLevel.error,
                    LogLevel.critical, LogLevel.fatal, LogLevel.off])
            {
                stdThreadLocalLog.logLevel = tll;

                foreach (cond; [true, false])
                {
                    foreach (condValue; [true, false])
                    {
                        foreach (memOrG; [true, false])
                        {
                            foreach (prntf; [true, false])
                            {
                                foreach (singleMulti; 0 .. 2)
                                {
                                    int lineCall;
                                    mem.msg = "-1";
                                    if (memOrG)
                                    {
                                        if (prntf)
                                        {
                                            if (cond)
                                            {
                                                if (singleMulti == 0)
                                                {
                                                    mem.logf(condValue, "%s",
                                                        value);
                                                    lineCall = __LINE__;
                                                }
                                                else
                                                {
                                                    mem.logf(condValue,
                                                        "%d %d", value, value);
                                                    lineCall = __LINE__;
                                                }
                                            }
                                            else
                                            {
                                                if (singleMulti == 0)
                                                {
                                                    mem.logf("%s", value);
                                                    lineCall = __LINE__;
                                                }
                                                else
                                                {
                                                    mem.logf("%d %d",
                                                        value, value);
                                                    lineCall = __LINE__;
                                                }
                                            }
                                        }
                                        else
                                        {
                                            if (cond)
                                            {
                                                if (singleMulti == 0)
                                                {
                                                    mem.log(condValue,
                                                        to!string(value));
                                                    lineCall = __LINE__;
                                                }
                                                else
                                                {
                                                    mem.log(condValue,
                                                        to!string(value), value);
                                                    lineCall = __LINE__;
                                                }
                                            }
                                            else
                                            {
                                                if (singleMulti == 0)
                                                {
                                                    mem.log(to!string(value));
                                                    lineCall = __LINE__;
                                                }
                                                else
                                                {
                                                    mem.log(to!string(value),
                                                        value);
                                                    lineCall = __LINE__;
                                                }
                                            }
                                        }
                                    }
                                    else
                                    {
                                        if (prntf)
                                        {
                                            if (cond)
                                            {
                                                if (singleMulti == 0)
                                                {
                                                    logf(condValue, "%s", value);
                                                    lineCall = __LINE__;
                                                }
                                                else
                                                {
                                                    logf(condValue, "%s %d", value,
                                                        value);
                                                    lineCall = __LINE__;
                                                }
                                            }
                                            else
                                            {
                                                if (singleMulti == 0)
                                                {
                                                    logf("%s", value);
                                                    lineCall = __LINE__;
                                                }
                                                else
                                                {
                                                    logf("%s %s", value, value);
                                                    lineCall = __LINE__;
                                                }
                                            }
                                        }
                                        else
                                        {
                                            if (cond)
                                            {
                                                if (singleMulti == 0)
                                                {
                                                    log(condValue,
                                                        to!string(value));
                                                    lineCall = __LINE__;
                                                }
                                                else
                                                {
                                                    log(condValue, value,
                                                        to!string(value));
                                                    lineCall = __LINE__;
                                                }
                                            }
                                            else
                                            {
                                                if (singleMulti == 0)
                                                {
                                                    log(to!string(value));
                                                    lineCall = __LINE__;
                                                }
                                                else
                                                {
                                                    log(value, to!string(value));
                                                    lineCall = __LINE__;
                                                }
                                            }
                                        }
                                    }

                                    string valueStr = to!string(value);
                                    ++value;

                                    bool gllOff = (gll != LogLevel.off);
                                    bool llOff = (ll != LogLevel.off);
                                    bool tllOff = (tll != LogLevel.off);
                                    bool llVSgll = (ll >= gll);
                                    bool tllVSll =
                                        (stdThreadLocalLog.logLevel >= ll);
                                    bool condFalse = (cond ? condValue : true);

                                    bool shouldLog = gllOff && llOff
                                        && (memOrG ? true : tllOff)
                                        && (memOrG ?
                                            (ll >= gll) :
                                            (tll >= gll && tll >= ll))
                                        && condFalse;

                                    if (shouldLog)
                                    {
                                        assert(mem.msg.indexOf(valueStr) != -1,
                                            format("\ngll(%s) ll(%s) tll(%s) " ~
                                                "cond(%s) condValue(%s) " ~
                                                "memOrG(%s) prntf(%s) " ~
                                                "singleMulti(%s)",
                                                gll, ll, tll, cond, condValue,
                                                memOrG, prntf, singleMulti)
                                            ~ format(" gllOff(%s) llOff(%s) " ~
                                                "llVSgll(%s) tllVSll(%s) " ~
                                                "tllOff(%s) condFalse(%s) "
                                                ~ "shoudlLog(%s)",
                                                gll != LogLevel.off,
                                                ll != LogLevel.off, llVSgll,
                                                tllVSll, tllOff, condFalse,
                                                shouldLog)
                                            ~ format("msg(%s) line(%s) " ~
                                                "lineCall(%s) valueStr(%s)",
                                                mem.msg, mem.line, lineCall,
                                                valueStr)
                                        );
                                    }
                                    else
                                    {
                                        assert(mem.msg.indexOf(valueStr) == -1,
                                            format("\ngll(%s) ll(%s) tll(%s) " ~
                                                "cond(%s) condValue(%s) " ~
                                                "memOrG(%s) prntf(%s) " ~
                                                "singleMulti(%s)",
                                                gll, ll, tll, cond, condValue,
                                                memOrG, prntf, singleMulti)
                                            ~ format(" gllOff(%s) llOff(%s) " ~
                                                "llVSgll(%s) tllVSll(%s) " ~
                                                "tllOff(%s) condFalse(%s) "
                                                ~ "shoudlLog(%s)",
                                                gll != LogLevel.off,
                                                ll != LogLevel.off, llVSgll,
                                                tllVSll, tllOff, condFalse,
                                                shouldLog)
                                            ~ format("msg(%s) line(%s) " ~
                                                "lineCall(%s) valueStr(%s)",
                                                mem.msg, mem.line, lineCall,
                                                valueStr)
                                        );
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}

// testing more possible log conditions
@safe unittest
{
    bool fatalLog;
    auto mem = new TestLogger;
    mem.fatalHandler = delegate() { fatalLog = true; };
    auto oldunspecificLogger = sharedLog;

    stdThreadLocalLog.logLevel = LogLevel.all;

    () @trusted {
        sharedLog = cast(shared) mem;
    }();

    scope(exit)
    {
        sharedLog = atomicLoad(oldunspecificLogger);
        globalLogLevel = LogLevel.all;
    }

    foreach (gll; [cast(LogLevel) LogLevel.all, LogLevel.trace,
            LogLevel.info, LogLevel.warning, LogLevel.error,
            LogLevel.critical, LogLevel.fatal, LogLevel.off])
    {

        globalLogLevel = gll;

        foreach (ll; [cast(LogLevel) LogLevel.all, LogLevel.trace,
                LogLevel.info, LogLevel.warning, LogLevel.error,
                LogLevel.critical, LogLevel.fatal, LogLevel.off])
        {
            mem.logLevel = ll;

            foreach (tll; [cast(LogLevel) LogLevel.all, LogLevel.trace,
                    LogLevel.info, LogLevel.warning, LogLevel.error,
                    LogLevel.critical, LogLevel.fatal, LogLevel.off])
            {
                stdThreadLocalLog.logLevel = tll;

                foreach (cond; [true, false])
                {
                    assert(globalLogLevel == gll);
                    assert(mem.logLevel == ll);

                    bool gllVSll = LogLevel.trace >= globalLogLevel;
                    bool llVSgll = ll >= globalLogLevel;
                    bool lVSll = LogLevel.trace >= ll;
                    bool gllOff = globalLogLevel != LogLevel.off;
                    bool llOff = mem.logLevel != LogLevel.off;
                    bool tllOff = stdThreadLocalLog.logLevel != LogLevel.off;
                    bool tllVSll = tll >= ll;
                    bool tllVSgll = tll >= gll;
                    bool lVSgll = LogLevel.trace >= tll;

                    bool test = llVSgll && gllVSll && lVSll && gllOff && llOff && cond;
                    bool testG = gllOff && llOff && tllOff && lVSgll && tllVSll && tllVSgll && cond;

                    mem.line = -1;
                    /*
                    writefln("gll(%3u) ll(%3u) cond(%b) test(%b)",
                        gll, ll, cond, test);
                    writefln("%b %b %b %b %b %b test2(%b)", llVSgll, gllVSll, lVSll,
                        gllOff, llOff, cond, test2);
                    */

                    mem.trace(__LINE__); int line = __LINE__;
                    assert(test ? mem.line == line : true); line = -1;

                    trace(__LINE__); line = __LINE__;
                    assert(testG ? mem.line == line : true); line = -1;

                    mem.trace(cond, __LINE__); line = __LINE__;
                    assert(test ? mem.line == line : true); line = -1;

                    trace(cond, __LINE__); line = __LINE__;
                    assert(testG ? mem.line == line : true); line = -1;

                    mem.tracef("%d", __LINE__); line = __LINE__;
                    assert(test ? mem.line == line : true); line = -1;

                    tracef("%d", __LINE__); line = __LINE__;
                    assert(testG ? mem.line == line : true); line = -1;

                    mem.tracef(cond, "%d", __LINE__); line = __LINE__;
                    assert(test ? mem.line == line : true); line = -1;

                    tracef(cond, "%d", __LINE__); line = __LINE__;
                    assert(testG ? mem.line == line : true); line = -1;

                    llVSgll = ll >= globalLogLevel;
                    lVSll = LogLevel.info >= ll;
                    lVSgll = LogLevel.info >= tll;
                    test = llVSgll && gllVSll && lVSll && gllOff && llOff && cond;
                    testG = gllOff && llOff && tllOff && tllVSll && tllVSgll &&
                        lVSgll && cond;

                    mem.info(__LINE__); line = __LINE__;
                    assert(test ? mem.line == line : true); line = -1;

                    info(__LINE__); line = __LINE__;
                    assert(testG ? mem.line == line : true); line = -1;

                    mem.info(cond, __LINE__); line = __LINE__;
                    assert(test ? mem.line == line : true); line = -1;

                    info(cond, __LINE__); line = __LINE__;
                    assert(testG ? mem.line == line : true); line = -1;

                    mem.infof("%d", __LINE__); line = __LINE__;
                    assert(test ? mem.line == line : true); line = -1;

                    infof("%d", __LINE__); line = __LINE__;
                    assert(testG ? mem.line == line : true); line = -1;

                    mem.infof(cond, "%d", __LINE__); line = __LINE__;
                    assert(test ? mem.line == line : true); line = -1;

                    infof(cond, "%d", __LINE__); line = __LINE__;
                    assert(testG ? mem.line == line : true); line = -1;

                    llVSgll = ll >= globalLogLevel;
                    lVSll = LogLevel.warning >= ll;
                    lVSgll = LogLevel.warning >= tll;
                    test = llVSgll && gllVSll && lVSll && gllOff && llOff && cond;
                    testG = gllOff && llOff && tllOff && tllVSll && tllVSgll &&
                        lVSgll && cond;

                    mem.warning(__LINE__); line = __LINE__;
                    assert(test ? mem.line == line : true); line = -1;

                    warning(__LINE__); line = __LINE__;
                    assert(testG ? mem.line == line : true); line = -1;

                    mem.warning(cond, __LINE__); line = __LINE__;
                    assert(test ? mem.line == line : true); line = -1;

                    warning(cond, __LINE__); line = __LINE__;
                    assert(testG ? mem.line == line : true); line = -1;

                    mem.warningf("%d", __LINE__); line = __LINE__;
                    assert(test ? mem.line == line : true); line = -1;

                    warningf("%d", __LINE__); line = __LINE__;
                    assert(testG ? mem.line == line : true); line = -1;

                    mem.warningf(cond, "%d", __LINE__); line = __LINE__;
                    assert(test ? mem.line == line : true); line = -1;

                    warningf(cond, "%d", __LINE__); line = __LINE__;
                    assert(testG ? mem.line == line : true); line = -1;

                    llVSgll = ll >= globalLogLevel;
                    lVSll = LogLevel.critical >= ll;
                    lVSgll = LogLevel.critical >= tll;
                    test = llVSgll && gllVSll && lVSll && gllOff && llOff && cond;
                    testG = gllOff && llOff && tllOff && tllVSll && tllVSgll &&
                        lVSgll && cond;

                    mem.critical(__LINE__); line = __LINE__;
                    assert(test ? mem.line == line : true); line = -1;

                    critical(__LINE__); line = __LINE__;
                    assert(testG ? mem.line == line : true); line = -1;

                    mem.critical(cond, __LINE__); line = __LINE__;
                    assert(test ? mem.line == line : true); line = -1;

                    critical(cond, __LINE__); line = __LINE__;
                    assert(testG ? mem.line == line : true); line = -1;

                    mem.criticalf("%d", __LINE__); line = __LINE__;
                    assert(test ? mem.line == line : true); line = -1;

                    criticalf("%d", __LINE__); line = __LINE__;
                    assert(testG ? mem.line == line : true); line = -1;

                    mem.criticalf(cond, "%d", __LINE__); line = __LINE__;
                    assert(test ? mem.line == line : true); line = -1;

                    criticalf(cond, "%d", __LINE__); line = __LINE__;
                    assert(testG ? mem.line == line : true); line = -1;

                    llVSgll = ll >= globalLogLevel;
                    lVSll = LogLevel.fatal >= ll;
                    lVSgll = LogLevel.fatal >= tll;
                    test = llVSgll && gllVSll && lVSll && gllOff && llOff && cond;
                    testG = gllOff && llOff && tllOff && tllVSll && tllVSgll &&
                        lVSgll && cond;

                    mem.fatal(__LINE__); line = __LINE__;
                    assert(test ? mem.line == line : true); line = -1;
                    assert(test ? fatalLog : true);
                    fatalLog = false;

                    fatal(__LINE__); line = __LINE__;
                    assert(testG ? mem.line == line : true); line = -1;
                    assert(testG ? fatalLog : true);
                    fatalLog = false;

                    mem.fatal(cond, __LINE__); line = __LINE__;
                    assert(test ? mem.line == line : true); line = -1;
                    assert(test ? fatalLog : true);
                    fatalLog = false;

                    fatal(cond, __LINE__); line = __LINE__;
                    assert(testG ? mem.line == line : true); line = -1;
                    assert(testG ? fatalLog : true);
                    fatalLog = false;

                    mem.fatalf("%d", __LINE__); line = __LINE__;
                    assert(test ? mem.line == line : true); line = -1;
                    assert(test ? fatalLog : true);
                    fatalLog = false;

                    fatalf("%d", __LINE__); line = __LINE__;
                    assert(testG ? mem.line == line : true); line = -1;
                    assert(testG ? fatalLog : true);
                    fatalLog = false;

                    mem.fatalf(cond, "%d", __LINE__); line = __LINE__;
                    assert(test ? mem.line == line : true); line = -1;
                    assert(test ? fatalLog : true);
                    fatalLog = false;

                    fatalf(cond, "%d", __LINE__); line = __LINE__;
                    assert(testG ? mem.line == line : true); line = -1;
                    assert(testG ? fatalLog : true);
                    fatalLog = false;
                }
            }
        }
    }
}

// Issue #5
@safe unittest
{
    import std.string : indexOf;

    auto oldunspecificLogger = sharedLog;

    scope(exit)
    {
        sharedLog = atomicLoad(oldunspecificLogger);
        globalLogLevel = LogLevel.all;
    }

    auto tl = new TestLogger(LogLevel.info);

    () @trusted {
        sharedLog = cast(shared) tl;
    }();

    trace("trace");
    assert(tl.msg.indexOf("trace") == -1);
}

// Issue #5
@safe unittest
{
    import std.logger.multilogger : MultiLogger;
    import std.string : indexOf;

    stdThreadLocalLog.logLevel = LogLevel.all;

    auto oldunspecificLogger = sharedLog;

    scope(exit)
    {
        sharedLog = atomicLoad(oldunspecificLogger);
        globalLogLevel = LogLevel.all;
    }

    auto logger = new MultiLogger(LogLevel.error);

    auto tl = new TestLogger(LogLevel.info);
    logger.insertLogger("required", tl);

    () @trusted {
        sharedLog = cast(shared) logger;
    }();

    trace("trace");
    assert(tl.msg.indexOf("trace") == -1);
    info("info");
    assert(tl.msg.indexOf("info") == -1);
    error("error");
    assert(tl.msg.indexOf("error") == 0);
}

@system unittest
{
    import std.exception : assertThrown;
    auto tl = new TestLogger();
    assertThrown!Throwable(tl.fatal("fatal"));
}

// log objects with non-safe toString
@system unittest
{
    struct Test
    {
        string toString() const @system
        {
            return "test";
        }
    }

    auto tl = new TestLogger();
    tl.info(Test.init);
    assert(tl.msg == "test");
}

// Workaround for atomics not allowed in @safe code
private auto trustedLoad(T)(ref shared T value) @trusted
{
    return atomicLoad!(MemoryOrder.acq)(value);
}

// ditto
private void trustedStore(T)(ref shared T dst, ref T src) @trusted
{
    atomicStore!(MemoryOrder.rel)(dst, src);
}

// check that thread-local logging does not propagate
// to shared logger
@system unittest
{
    import core.thread, std.concurrency;

    static shared logged_count = 0;

    class TestLog : Logger
    {
        Tid tid;

        this()
        {
            super (LogLevel.trace);
            this.tid = thisTid;
        }

        override void writeLogMsg(ref LogEntry payload) @trusted
        {
            assert(thisTid == this.tid);
            atomicOp!"+="(logged_count, 1);
        }
    }

    class IgnoredLog : Logger
    {
        this()
        {
            super (LogLevel.trace);
        }

        override void writeLogMsg(ref LogEntry payload) @trusted
        {
            assert(false);
        }
    }

    auto oldSharedLog = sharedLog;
    scope(exit)
    {
        sharedLog = atomicLoad(oldSharedLog);
    }

    () @trusted {
        sharedLog = cast(shared) new IgnoredLog;
    }();

    Thread[] spawned;

    foreach (i; 0 .. 4)
    {
        spawned ~= new Thread({
            stdThreadLocalLog = new TestLog;
            trace("zzzzzzzzzz");
        });
        spawned[$-1].start();
    }

    foreach (t; spawned)
        t.join();

    assert(atomicOp!"=="(logged_count, 4));
}

@safe unittest
{
    auto dl = () @trusted {
        return cast(FileLogger) cast() sharedLog;
    }();
    assert(dl !is null);
    assert(dl.logLevel == LogLevel.info);
    assert(globalLogLevel == LogLevel.all);

    auto tl = cast(StdForwardLogger) stdThreadLocalLog;
    assert(tl !is null);
    stdThreadLocalLog.logLevel = LogLevel.all;
}

// https://issues.dlang.org/show_bug.cgi?id=14940
@safe unittest
{
    import std.typecons : Nullable;

    Nullable!int a = 1;
    auto l = new TestLogger();
    l.infof("log: %s", a);
    assert(l.msg == "log: 1");
}

// Ensure @system toString methods work
@system unittest
{
    enum SystemToStringMsg = "SystemToString";
    static struct SystemToString
    {
        string toString() @system
        {
            return SystemToStringMsg;
        }
    }

    auto tl = new TestLogger();

    SystemToString sts;
    tl.logf("%s", sts);
    assert(tl.msg == SystemToStringMsg);
}

// https://issues.dlang.org/show_bug.cgi?id=17328
@safe unittest
{
    import std.format : format;

    ubyte[] data = [0];
    string s = format("%(%02x%)", data); // format 00
    assert(s == "00");

    auto tl = new TestLogger();

    tl.infof("%(%02x%)", data);    // infof    000

    size_t i;
    string fs = tl.msg;
    for (; i < s.length; ++i)
    {
        assert(s[s.length - 1 - i] == fs[fs.length - 1 - i], fs);
    }
    assert(fs.length == 2);
}

// https://issues.dlang.org/show_bug.cgi?id=15954
@safe unittest
{
    import std.conv : to;
    auto tl = new TestLogger();
    tl.log("123456789".to!wstring);
    assert(tl.msg == "123456789");
}

// https://issues.dlang.org/show_bug.cgi?id=16256
@safe unittest
{
    import std.conv : to;
    auto tl = new TestLogger();
    tl.log("123456789"d);
    assert(tl.msg == "123456789");
}

// https://issues.dlang.org/show_bug.cgi?id=15517
@system unittest
{
    import std.file : exists, remove, tempDir;
    import std.path : buildPath;
    import std.stdio : File;
    import std.string : indexOf;

    string fn = tempDir.buildPath("logfile.log");
    if (exists(fn))
    {
        remove(fn);
    }

    auto oldShared = sharedLog;
    scope(exit)
    {
        sharedLog = atomicLoad(oldShared);
        if (exists(fn))
        {
            remove(fn);
        }
    }

    auto ts = [ "Test log 1", "Test log 2", "Test log 3"];

    auto fl = new FileLogger(fn);

    () @trusted {
        sharedLog = cast(shared) fl;
    }();

    assert(exists(fn));

    foreach (t; ts)
    {
        log(t);
    }

    auto f = File(fn);
    auto l = f.byLine();
    assert(!l.empty);
    size_t idx;
    foreach (it; l)
    {
        assert(it.indexOf(ts[idx]) != -1, it);
        ++idx;
    }

    assert(exists(fn));
    fl.file.close();
}
