I'm trying to recieve the logger for my class:
public static final java.util.logging.Logger log = java.util.logging.Logger.getLogger(this);
But using "this" there causes "Cannot use this in a static context" error.
Anyone know how to fix this?
EDIT: I must be able to access the logger from all classes in my program, so it must be public.
Notice I changed modifier from public to private:
public class FooBar {
private static final Logger log = Logger.getLogger(FooBar.class);
//or (if you are using java.util.logging):
private static final Logger log = Logger.getLogger(FooBar.class.getName());
}
For org.appache.log4j:
private static final Logger LOG = Logger.getLogger(MyClass.class);
For java.util.Logging
private static final Logger LOG = Logger.getLogger(MyClass.class.getName());
Related
I want to decorate logger like below:
public class CustomLogger implements org.slf4j.Logger {
private final Logger logger;
public CustomLogger(Class clazz) {
logger = getLoggerInLogback(clazz);
}
...
}
When I call org.slf4j.LoggerFactory.getLogger(clazz), I want this method to return a instance of CustomLogger. In this way, I can add additional behavior to logger without changing code.
But how can I make the method to return a instance of CustomLogger?
I am using final Logger LOGGER = LoggerFactory.getLogger(clazz); to get the LOGGER object of org.slf4j. I am facing difficulty in overriding any default implemented method of this class.
I am trying to override non-static method of the conrete class. Lets say, Class MyLogger { Logger LOGGER = LoggerFactory.getLogger(clazz); LOGGER.debug("Some message"); } Now debug method is the non-static method declared in the LOGGER class for which some concrete implementation has been provided. The problem here is I am seeing lots of implementation classes when I try to search for the references. So in order to override debug method what should I do
Updated the original class like this:
public class MyLogger implements Logger {
private static final Logger LOGGER = LoggerFactory.getLogger(MyLogger.class);
public static org.slf4j.Logger init(Class clazz) {
final Logger loggerOut = LoggerFactory.getLogger(clazz);
setContainerId();
LOGGER.debug("Logger is initialized for [{}].", clazz.getName());
return loggerOut;
}
public void debug(String msg, Object arg1)
{
LOGGER.debug("My message",arg1);
}
}
Still not able to get result. Please suggest what am I missing here?
Static methods cannot be overriden. If you see here the functions of LoggerFactory in documentation
I was taking over an old java projcet. And the original designer has gone.
In this project, it uses Log4j in a static way, like this:
public class LogUtil {
private static final String FQCN = LogUtil.class.getName();
private static final Logger logger1 = Logger.getLogger("INFO");
private static final Logger logger2 = Logger.getLogger("ERROR");
public static void info(Object message) {
if (logger1.isInfoEnabled()) {
forcedLog(logger1, Level.INFO, message);
}
}
public static void error(Object message) {
forcedLog(logger2, Level.ERROR, message);
}
private static void forcedLog(Logger logger, Level level, Object message) {
logger.callAppenders(new LoggingEvent(FQCN, logger, level, message, null));
}
}
Then other class can easily write logs with LogUtil.error("") and LogUtil.info("") .
And the INFO logger and ERROR logger were configured to write in separate files.
But in Log4j2, the class LoggingEvent can not be found.
So the question is, if I want to use Log4j2, how should I modify this class?
(maybe use Log4j 1.x bridge provided in log4j2 packages?)
Is using logger in this way reasonable? It seems that it is easier than creating loggers per class. Is there any problems like performance or others?
So the question is, if I want to use Log4j2, how should I modify this class? (maybe use Log4j 1.x bridge provided in log4j2 packages?)
You could rewrite it to use the public API instead of relying on underlying implementation details. So, something like this:
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
public class LogUtil {
private static final Logger TRACE_LOGGER = LogManager.getLogger("TRACE");
private static final Logger DEBUG_LOGGER = LogManager.getLogger("DEBUG");
private static final Logger INFO_LOGGER = LogManager.getLogger("INFO");
private static final Logger WARN_LOGGER = LogManager.getLogger("WARN");
private static final Logger ERROR_LOGGER = LogManager.getLogger("ERROR");
private static final Logger FATAL_LOGGER = LogManager.getLogger("FATAL");
public static void trace(Object msg){
TRACE_LOGGER.trace(msg);
}
public static void debug(Object msg){
DEBUG_LOGGER.debug(msg);
}
public static void info(Object msg) {
INFO_LOGGER.info(msg);
}
public static void warn(Object msg){
WARN_LOGGER.warn(msg);
}
public static void error(Object msg) {
ERROR_LOGGER.error(msg);
}
public static void fatal(Object msg){
FATAL_LOGGER.fatal(msg);
}
...
}
Is using logger in this way reasonable? It seems that it is easier than creating loggers per class. Is there any problems like performance or others?
I don't see how adding 3 lines to a class is anything other than easy. All it takes to create a logger (in log4j2) is this:
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
...
private static final Logger logger = LogManager.getLogger();
As for potential problems, with this implementation you give up a lot of the functionality of log4j.
You can't change the log level on a package or class basis because all of the classes share the same loggers. Perhaps you want to turn on TRACE logging for a new class you're working on, but you don't want any TRACE logs from other classes as it clutters the log file - you would not be able to make this kind of change easily.
You can't change the appenders on a package or class basis because once again all classes share the same loggers. Perhaps you want to send all of the logs from a new package that you're working on to a separate file so that you can more easily see what your new code is doing without having to filter the logs manually. Maybe you want to see all logs from a particular class or package in a single file during development so that you can follow the execution more easily without having to jump around to different files.
I'm new to util.logging so this might seem a trivial question to some but anyway here goes..I'm using Java's Util.logger to log messages. I'm trying to declare a logger in a single class and accessing it from other classes for logging messages.
Logger class
package util;
import java.util.logging.*;
public class Logger {
public Logger LOGGER = Logger.getLogger(Logger.GLOBAL_LOGGER_NAME);
}
I'm trying to access this logger in other class as follows..
package mycode;
import util.Logger;
public class MYcode{
private void test(){
LOGGER.fine("Sample message");
}
}
Compilation Error message..
error: cannot find symbol
[javac]LOGGER.fine("Sample message");
When I'm declaring logger in Mycode class then I'm not getting any error but when declaring it another class I'm getting an error. Any idea where I'm going wrong??
Just keep using in all classes needing the logger the same line:
public Logger LOGGER = Logger.getLogger(Logger.GLOBAL_LOGGER_NAME);
This way you are creating many references to one instance of logger identified by the global name.
The problem is your 'LOGGER' is NOT static, so you are NOT able to access.
Logger class:
package util;
import java.util.logging.*;
public class Logger {
public static final Logger LOGGER = Logger.getLogger(Logger.GLOBAL_LOGGER_NAME);
}
Accessing logger in other class:
package mycode;
import util.Logger;
public class MYcode{
public void test(){
LOGGER.fine("Sample message");
}
}
I'm using an enum singleton, but implementing logging is troublesome. This:
public enum Foo {
INSTANCE;
private final Logger log = Logger.getLogger(Foo.class.getName());
...
}
The logger is instantiated in the way that I would instantiate a logger for a normal Java class, but of course I get the following error:
Foo.java: illegal reference to static field from initializer
Is there an equivalent way to log in enum singletons?
In answer to your question, just make the logger static...
BTW, I think its standard practice to use a static logger even for object instances. In other words, the logger is on the class; all objects use the static logger references.
See
http://logging.apache.org/log4j/1.2/manual.html
Most of the examples of using a logger in there have the logger as a static property...
Log dynamically:
Logger.getLogger(Foo.class.getName()).info("log info");
A bit shorter: use a method: logger().debug(...)
private static Logger logger()
{
if(logger == null)
{
logger = Logger.getLogger(AnEnum.class);
}
return logger;
}
/** Logger **/
private static Logger logger;