nberlijn
nberlijn

Reputation: 313

Java public Logger

Is it allowed to make a single static class for your log?

public final class Log {

    public static final Logger LOGGER = Logger.getLogger(Log.class.getName());

}

And call it whenever it's needed?

Log.LOGGER.info("Let's log something!");

Rather than add this single line of code on every class?

private static final Logger LOGGER = Logger.getLogger(Log.class.getName());

I read information that you should initializes the Logger in every single class.

public static final Logger LOGGER = Logger.getLogger(ClassName.class.getName());

Or what's the way to go? I prefer some static approuch rather than initializes the logger in every single class...

I tried it out, and the result is as follow.

Preview:

Log

public class Log {

    public static final Logger LOGGER = Logger.getLogger(Log.class.getName());

}

App

final class App() {

    public static void main(String[] args) {
        start();
    }

    private static void start() {
        Log.LOGGER.info("Starting the application.");
    }

}

Kernel

public final class Kernel() {

    public static void preload() {
        Log.LOGGER.info("Preload kernel modules.");
    }

}

Output:

Aug 26, 2015 2:17:34 PM nl.nberlijn.powercontrol.App start
INFO: Starting the application.
Aug 26, 2015 2:17:34 PM nl.nberlijn.powercontrol.kernel.Kernel preload
INFO: Preload kernel modules.

Upvotes: 3

Views: 781

Answers (3)

Nathan Hughes
Nathan Hughes

Reputation: 96394

It's allowed, but there's a reason people don't do this.

With the usual approach of having a separate logger for each class, you can filter your logging based on which packages and classes you want to see, at what level. That way you don't have to worry too much about whether to insert a call to the logger, you can keep it in even if you don't need it all the time, because you can filter it out. When there's a problem you can increase the log level for just those classes you're interested in. But with the single Log class approach you can't do that at all.

Upvotes: 1

Ian2thedv
Ian2thedv

Reputation: 2701

You can probably do something like this:

public static final class Logger {
    public static Logger get() {
        return Logger.getLogger(Thread.currentThread().getStackTrace()[1].getClassName());
    }
}

Which can be used like this:

Logger.get().log("Hello World!");

This will allow you preserve information such as the name of the logging class and won't require you to actually pass the calling class name as a parameter. I am not sure of the performance of getting the stacktrace on every call though, so this might not be efficient.

Upvotes: 0

aleroot
aleroot

Reputation: 72636

If you want to follow a similar approach I would suggest to use static methods for logging instead like in the following example :

 public final class Log {

    private static final Logger LOGGER = Logger.getLogger(Log.class.getName());
    public void logError(String someText) {
       LOGGER.error(someText);
    }
    public static LogInfo(String someText) {
       LOGGER.info(someText);
    }
}

and then call it in your client classes simply with :

    private static void start() {
        LogInfo("Starting the application.");
    }

Of course before you need a static import :

import static com.yourpackage.Log.*

It is an approach that could be followed, but I would prefer to inject the logger inside the components of your application that needs to log something, leaving things more decoupled ...

Upvotes: 1

Related Questions