简体   繁体   中英

Log4j2 custom wrapper

I made a wrapper for log4j2 logger based on this topic: How do I add a prefix to log4j messages (at the object level)

here is that i have:

import org.apache.log4j.Logger;

public class LogWrapper
{
    private Logger log;
    private String prefix;

    public LogWrapper(Logger log, String prefix) {
        this.log = log;
        this.prefix = prefix;
    }

    public void info(String msg)
    {
        log.error(prefix + "| " + msg);
    }
    public void error(String msg)
    {
        log.error(prefix + "| " + msg);
    }
}

usage:

public class MyClass {
    private final LogWrapper logger;
    public MyClass(String username) {
        logger = new LogWrapper(Logger.getLogger(MyClass.class.getName()), username);
    }
}

Problem:

As the output i have a links to LogWrapper class

2016-07-12 21:15:17,543 ERROR [pool-3-thread-1] global.LogWrapper (LogWrapper.java:17) - blab bla bla

'LogWrapper.java:17' it doesn't point on the line in MyClass where the logger was called.

How to solve it?

The built-in mechanism provided by Log4j to put prefixes in your log output is the ThreadContext map. How to do this:

Code:

// usually at some entry point from where these values won't change 
ThreadContext.put("user.ip", ipAdr);
ThreadContext.put("user.account", userAccount);

Configuration:

<PatternLayout pattern="%d %p %c{1.} [%t] %X{user.ip} %X{user.account} %m%n"/>

Now any logging after values have been put into the ThreadContext will show with the desired prefixes.

A custom logger wrapper can be used to achieve something similar but is quite a lot more work.

Log4j remembers the fully qualified class name (FQCN) of the logger and uses this to walk the stack trace for every log event when configured to print location. (Be aware that logging with location is slow and may impact the performance of your application.)

The problem with the custom logger wrapper is that it has a different FQCN than the actual logger, so Log4j can't find the place where your custom logger was called.

The solution is to provide the correct FQCN. The easiest way to do this is to let Log4j generate the logger wrapper for you. Log4j comes with a Logger wrapper generator tool. This tool was originally meant to support custom log levels and is documented here: https://logging.apache.org/log4j/2.x/manual/customloglevels.html#CustomLoggers

The generated logger code will take care of the FQCN and you can use it as a base for the further enhancements you have in mind.

Actually, the problem is that the Location information isn't what you want it to be. That happens when you create a wrapper as you have done. To fix it, Log4j needs the fully qualified class name (FQCN) of the Logger class. It isn't that hard to manually create a class that does that, but the easy way is to follow the instructions in the Log4j manual at http://logging.apache.org/log4j/2.x/manual/customloglevels.html#CustomLoggers

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM