slf4d 2.1.1

Simple Logging Facade For D

To use this package, run the following command in your project's root directory:

Manual usage
Put the following dependency into your project's dependences section:


alt="SLF4D Banner Image"
style="max-width: 300px"



DUB DUB DUB GitHub Workflow Status (with branch)

Simple Logging Facade for D, inspired by SLF4J. Add it to your project with dub add slf4d, and start logging sensibly!

Read the documentation here!

SLF4D provides a common interface and core logging features, while allowing third-party providers to handle log messages produced at runtime. Take a look at the following example, where we get a logger from SLF4D and write an info message.

import slf4d;

void main() {
    auto log = getLogger();"Hello world!");

You can also define a module-level logger instead, using a static this initializer:

import slf4d;

private Logger log;
static this {
    log = getLogger();

void main() {"Hello world!");

Logging Methods

The following table gives a brief outline of the available logging methods provided by an SLF4D Logger struct obtained via log = getLogger(); | Level | Basic | Formatted | |--- |--- |--- | | TRACE | log.trace("Message") | log.traceF!"Message %d"(42) | | DEBUG | log.debug_("Message")* | log.debugF!"Message %d"(42) | | INFO |"Message") | log.infoF!"Message %d"(42) | | WARN | log.warn("Message") | log.warnF!"Message %d"(42) | | ERROR | log.error("Message") | log.errorF!"Message %d"(42) |

* Because debug is a keyword in D, debug_ is used as the method name.

Each basic function also accepts an Exception as an argument:

try {
} catch (Exception e) {
    log.warn("Uh oh, something went wrong.", e);
    // Or let SLF4D derive the message from the exception:


In addition to the log methods described above, the Logger also provides a set of builder methods that give you a LogBuilder with a fluent interface for building log messages.

| Level | Method | |--- |--- | | TRACE | log.traceBuilder() | | DEBUG | log.debugBuilder() | | INFO | log.infoBuilder() | | WARN | log.warnBuilder() | | ERROR | log.errorBuilder() |

Here's an example of how a builder can be used:

auto log = getLogger();
    .msg("This is a warning message.")
    .exc(new Exception("Oh no!"))

Configuring the Provider

By default, SLF4D uses a built-in logging provider that simply writes log messages to stdout and stderr. However, if you'd like to use a third-party logging provider instead, or create your own custom provider, all you need to do is call configureLoggingProvider() when your application starts, to set the shared logging provider to use.

import slf4d;
import some_slf4d_provider;

void main() {
    configureLoggingProvider(new shared CustomProvider());
    auto log = getLogger(); // Logger configured using provider.


SLF4D is designed to be easy-to-use in unit testing, and it comes with a few purpose-built components to facilitate this.

  • The slf4d.testing_provider package defines a TestingLoggingProvider class that be used to help with recording any log messages that were sent to it.
  • Under the hood, it uses a CachingLogHandler from slf4d.handler which is a thread-safe handler for storing logged messages in memory for inspection.

Here's an example.

unittest {
    import slf4d;
    import slf4d.testing_provider;
    // Setup SLF4D using our testing provider.
    auto provider = new shared TestingLoggingProvider();


    assert(provider.messages.length == 3);
    assert(provider.messages[0].level == Levels.INFO);
    assert(provider.messages[1].message == "Hello world!");

    // Reset the testing provider to clear all log messages.


    // Check that there are no warn/error messages.
    foreach (msg; provider.messages) {
        assert(msg.level.value < Levels.WARN.value);

Making a Custom Provider

To create a logging provider, simply implement the LoggingProvider interface defined in slf4d.provider. Note that your logging factory and handler should be shared, that is, they will be shared among all threads of an application which uses your provider. Consider using a mutex or synchronized in your handler or factory if it needs to access a shared resource.

Why SLF4D?

First, let me ask a question: Is there a single unanimously chosen logging library for the D language? Currently, that answer is "no", and as long as it stays like that, and I imagine it will, then SLF4D can be of use.

SLF4D is not a logger itself, but a common interface that any library or end-user application can plug into. The goal is to allow anyone to support structured logging in their D project, while giving developers the freedom to choose how log messages are handled when you go to run your program. By logging with SLF4D, you make your D modules' log messages compatible with all available logging providers.

D developers; if this message resonates with you, consider adding SFL4D logging to your project!


The versioning of SLF4D follows the Semantic Versioning principles which are, in short:

  • Version numbers formatted as <Major>.<Minor>.<Patch>, e.g. 1.2.3
  • Major version increases when an incompatible change is introduced.
  • Minor version increases when backwards-compatible functionality is introduced.
  • Patch version increases when backwards-compatible bug-fixes are introduced.

More specifically in the context of this library, major version upgrades may introduce a breaking change to either the logging interface or the provider/message handling, but all breaking changes and incompatibilities must be defined in a changelog file for each release. See the changelogs directory for the comprehensive list of all changelogs.

  • Andrew Lalis
2.1.1 2023-Mar-20
2.1.0 2023-Mar-10
2.0.0 2023-Mar-04
1.3.1 2023-Mar-03
1.3.0 2023-Mar-01
Show all 13 versions
Download Stats:
  • 0 downloads today

  • 0 downloads this week

  • 0 downloads this month

  • 0 downloads total

Short URL: