10

I use log4j2 and I would like to add a prefix to all my messages. This prefix is passed to the constructor parameter and it depends on the instance of the class. So we're at the object level (not class or thread).

For example, I have an A class instantiated like new A(152), so when I use log.error("message") on this class, 152: is written just before the message. For new A(155), 155: will be displayed instead.

Thanks for your help

Joanis
  • 1,669
  • 3
  • 20
  • 32
Lucie
  • 125
  • 1
  • 1
  • 7

5 Answers5

7

Use MDC to achive this

In your constructor put

 MDC.put("prefix", yourvalue);

and in your XML use it like this in pattern

      %X{prefix}
NullPointerException
  • 3,732
  • 5
  • 28
  • 62
  • 1
    Different threads can put different values for the same key. The map is threadlocal so every thread has a separate copy. – Remko Popma May 24 '13 at 16:19
5

Based on Bill Clars answer:

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

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

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

Then you set as instance variable in your class

public class MyClass {
    private LogWrapper log;

    public MyClass(int prefix) {
        log = new LogWrapper(Logger.getLogger(this.getClass()), String.valueOf(prefix));

        // then log away
        log.error("Test");
    }
}
DairyLea
  • 802
  • 1
  • 8
  • 16
  • Or you could extend `Logger` and override the logging methods – DairyLea May 23 '13 at 20:26
  • 1
    I tried this before... It will always print the exact same `file:line` as the log message origin. It will always be `LogWrapper:26` because you log4j logger call is at line (e.g.) 26 in your `LogWrapper` class. You'd need to extend the log4j logger, but that's still not trivial (at least, it wasn't on log4j 1.2). – Joanis May 24 '13 at 15:46
  • As I understood it the question asked to simply prefix a number before all messages... – DairyLea May 24 '13 at 17:50
  • 1
    I'm just pointing out that, although answering the question, it's not very practical since you are losing valuable information. Unless you don't care where your logs come from, in which case I'd wonder why you're logging using a logging framework and not simply printing the desired information to a file. – Joanis May 25 '13 at 02:05
3

Here is one simple workaround solution: you can wrap the string with a method that adds the prefix to it and returns concatenated string to the error method.

public class A {
    private static final Logger LOG = LogManager.getLogger();

    final int index;

    public A(int index) {
        this.index = index;
    }

    public static void f(String message) {
        return String.valueOf(index) + ": ";
    }

    public void method() {

        // ...

        LOG.error(f("message"));

    }

}

Advantages:

  • Simple
  • You can log messages with and also without the prefix in one class/method
  • You don't have to permanently add something like %X{prefix} to the log4j2 configuration

Disadvantages:

  • You always have to use the wrapper method if you want to add the prefix
jjurm
  • 501
  • 6
  • 11
  • And if you want to use this wrapper method in each class you create, you can use static import instead of declaring the method in each class – jjurm Aug 25 '14 at 19:02
0

One solution is a wrapper class.

public class YourLogger
{
    private Logger log;

    public void error(int value, String msg)
    {
        log.error(String.valueOf(value) + ": " + msg);
    }
}
Bill Clar
  • 139
  • 1
  • 9
0

try this

public void writeError(String msg,int intValue) {
logger.error(intValue+" "+msg);
}
KhAn SaAb
  • 5,248
  • 5
  • 31
  • 52