Blee
Blee

Reputation: 87

log4j add prefix to all messages from one abstract class

I am trying to use log4j to add prefix to all log commands.

Previously I have been using @Slf4j in front of all classes, but now I need to add certain prefix to all messages, so this is no longer possible.

My class structure is as follows:

abstract class MyAbstractClass {
    protected final MyLogger log;
    MyAbstractClass(String foodType) {
        this.log = new MyLogger(Logger.getLogger(this.getClass(), foodType));
    }
}

class MyClass1 extends MyAbstractClass {
    MyClass1(String foodType) { super(foodType); }   
    public static void myMethod1() {
        log.info("hehe");
    } 
}

class MyClass2 extends MyAbstractClass {
    MyClass2(String foodType) { super(foodType); }   
    public static void myMethod2() {
        log.info("hohohoho");
    } 
}

/* MyLogger.java */

@Slf4j
public class MyLogger  {
    private final Logger LOGGER;
    private String PREFIX;
    public MyLogger(Logger logger, String foodType) {
        LOGGER = logger;
        PREFIX = foodType + ": ";
    }

    public void info(final String str) {
        log.info(PREFIX + str);
    }

    public void warn(final String str) {
        log.warn(PREFIX + str);
    }

    public void debug(final String str) { log.debug(PREFIX + str); }

    public void error(final String str) {
        log.error(PREFIX + str);
    }

    public void error(final String str, Exception e) {
        log.error(PREFIX + str, e);
    }
    ...

    // i know.. it's so inconvenient because I have to override all the methods that I want to use from log4j Logger. I wish there is an alternative.

}

If I were to do something like this,

public static void main() {
    MyClass1 c1 = new MyClass1("burger");
    MyClass2 c2 = new MyClass2("pizza");
    c1.myMethod1();
    c2.myMethod2();
}

I would get something like this.

/* console */
[INFO] MyLogger#info - burger: hehe
[INFO] MyLogger#info - pizza: hohoho

BUT, i would like to get something like this to be able to trace where exactly it came from (original Log4j does this).

/* console */
[INFO] MyClass1#MyMethod1 - burger: hehe
[INFO] MyClass2#MyMethod2 - pizza: hohoho

Is there way for me to accomplish this?

Thanks!

Upvotes: 1

Views: 6193

Answers (2)

Blee
Blee

Reputation: 87

I solved this by using the MDC Pattern. I no longer need MyLogger class. I can just use the Log4j 's Logger class.

You can do something like

abstract class MyAbstractClass {
    protected final Logger log;
    MyAbstractClass(String foodType) {
        MDC.put("myfood", foodType);
        this.log = LoggerFactory.getLogger(getClass()));
    }
}

and in the pattern, you can add on %X{myfood} to access the variables you set :)

More on MDC here: http://logback.qos.ch/manual/mdc.html

Upvotes: 2

Pradeep Pati
Pradeep Pati

Reputation: 5919

If you are using PatternLayout (and you should) you can do this by defining the pattern to be

%C{1}:%M - %m%n

Upvotes: 1

Related Questions