Thread overview
SLF4D - A proposal for a common logging interface for Dub projects
Feb 22, 2023
Andrew
Feb 24, 2023
psyscout
Feb 24, 2023
Tobias Pankrath
Feb 25, 2023
Andrew
Feb 25, 2023
max haughton
Feb 25, 2023
Andrew
February 22, 2023

I've been spending some time in the last few weeks to prototype a logging framework that's inspired by SLF4J. To that end, I've created SLF4D, which provides a common logging interface, and a pluggable architecture to allow third-parties to handle log messages generated by any logger in an application.

Here's a short example of how it can be used in your code:

import slf4d;

void main() {
  auto log = getLogger();
  log.info("This is an info message.");
  log.errorF!"This is an error message: %d"(42);
}

The library includes a default "logging provider" that just outputs formatted messages to stdout and stderr, but a third-party provider can be used by calling configureLoggingProvider(provider).

The idea is that I can create logging providers to wrap the various logging facilities available in the D ecosystem already (Phobos, Vibe-D, etc.), so SLF4D can serve as a common interface to any provider.

I'd appreciate any feedback on this so far! This first version should be mostly stable, but there may of course be bugs. Thanks!

February 24, 2023

On Wednesday, 22 February 2023 at 21:46:32 UTC, Andrew wrote:

>

I've been spending some time in the last few weeks to prototype a logging framework that's inspired by SLF4J. To that end, I've created SLF4D, which provides a

Hi Andrew,

this looks great.
I have a Java background, so it resonates :)

Thank you for your effort!

February 24, 2023
On Wednesday, 22 February 2023 at 21:46:32 UTC, Andrew wrote:
> I've been spending some time in the last few weeks to prototype a logging framework that's inspired by [SLF4J](https://www.slf4j.org/). To that end, I've created [SLF4D](https://github.com/andrewlalis/slf4d), which provides a common logging interface, and a pluggable architecture to allow third-parties to handle log messages generated by any logger in an application.
>

Why not std.experimental.logger?
February 25, 2023

On Friday, 24 February 2023 at 22:01:18 UTC, Tobias Pankrath wrote:

>

Why not std.experimental.logger?

There are a few reasons that I had for this:

  • There are already quite a few different logging implementations entrenched in the D ecosystem besides just std.logger (it's no longer experimental!), and I don't think everyone is going to push to std.logger just by virtue of it being in phobos.
  • std.logger uses a mutable public shared logger instance. I personally don't like this approach, and I think it's cleaner if the logging configuration for an entire application is setup in one place, on application startup. That's why with SLF4D you (optionally) configure a logging provider as soon as you enter main().
  • The base Logger from std.logger is a class when, in my opinion, it doesn't need to be, if you want to provide extensible ways for handling the log messages that an application produces. It's easier for developers to learn to use a simple struct and its fixed set of methods, than to understand a type hierarchy.
  • std.logger makes some approaches towards filtering, formatting, and distributing log messages, but it still seems very primitive to me, compared to mature logging frameworks in other languages (primarily python and java), and I would rather have the application logic completely separated from the logic controlling what happens to log messages after they're created.
February 25, 2023

On Saturday, 25 February 2023 at 07:52:09 UTC, Andrew wrote:

>

[...]

On the contrary I would argue that it's much easier (not necessarily better) to provide extensibility using classes. Nobody ever got fired for writing a class, as the saying goes.

February 25, 2023

On Saturday, 25 February 2023 at 09:32:18 UTC, max haughton wrote:

>

On the contrary I would argue that it's much easier (not necessarily better) to provide extensibility using classes. Nobody ever got fired for writing a class, as the saying goes.

I'd actually sort of agree with you here, but my opinion (which isn't necessarily correct, mind you) is that it's better to provide a fixed interface (a struct with a set of pre-defined methods) for developers to use, than to let them use a class which could be extended from another. Essentially I just tried to make the developer-experience as simple as possible, while letting logging providers customize pretty much everything that happens after a log message is generated.