I just found a very compelling alternative solution to the LogLevel disabling problem. This was one of the reasons for the delay of std.log and the current solution still isn't great [1].

This idea here achieves
- fine grained control over log levels (per module/package)
- zero overhead for statically disabled log levels
- zero (almost) boilerplate (works even with the global stdlog)
- and it establishes a nice convention to enable logging for a library
  `pkg.logLevel = LogLevel.info;`

Basically it works by declaring a logLevel in a module or package.
Then the std.logger module does a reverse lookup of that declaration.

```d
module mymod;

import std.logger;

// can be anything that converts to a LogLevel
// calls with lower log level can be optimized away if this is a compile time constant
// runtime values also work nicely but incur a small overhead
// if this declaration is not present, logLevel from the package is used or the default LogLevel.

enum logLevel = LogLevel.critical;

void foo()
{
    info("information from foo"); // optimized out
    fatal("error");               // logs
}
```

https://gist.github.com/MartinNowak/443f11aa017d14007c35

There is a tiny gotcha, this works because the logger module imports the calling module. So we'd need to avoid module constructors in the logger module or use a workaround [2].

Also it can lead to additional imports when the whole package is imported to resolve logLevel. This can be avoided though by declaring logLevel in a separate module and making it available in every module of a package.

```d
module mypkg.loglevel;

LogLevel logLevel;
```
```d
module mypkg.foo.bar;

public import mypkg.logLevel;

void baz(T)(T t)
{
    info("baz");
}
```

[1]: http://forum.dlang.org/post/m2p3r6$148j$1...@digitalmars.com
[2]: https://github.com/D-Programming-Language/phobos/blob/9a46840c2b36beb6711244ec4340c117fc91a0f1/std/stdiobase.d

Reply via email to