How to configure logback to append special prefix for each object?

11,867

I don't know how you currently instantiate your logger, but you can use your "string parameter which represents" your object to name this logger:

logger = LoggerFactory.getLogger("0999445454");

For example, if this string identifier is stored in an attribute id, you can do that:

Logger logger = null;

public MyClass(String id) {
    logger = org.slf4j.LoggerFactory.getLogger(id);
    // ...
}

public void doSomething()  {
    logger.info("Doing Something...");
    // Do something
}

You will then need to use the following Pattern in your Logback configuration file:

<appender name="..." class="...Appender">
    <encoder>
        <pattern>[%level] [%logger]: %msg%n</pattern>
    </encoder>
</appender>

Because %logger is the logger name, which is the parameter given to org.slf4j.LoggerFactory.getLogger()


If you want to avoid creating a Logger for each ID, you can also use Mapped Diagnostic Context (MDC):

logger = LoggerFactory.getLogger(MyClass.class);
org.slf4j.MDC.put("id", "your ID");
logger.info("Doing Something...");

You shall then add field %mdc in your Pattern (i.e. Logback configuration file):

<pattern>[%level] [%mdc{id}]: %msg%n</pattern>

So you shall call MDC.put() before a log each time you want to log with a different ID. What you could do in your case is something like:

public class MyClass {
    private Logger logger = LoggerFactory.getLogger(MyClass.class);
    private final String id;
    private static final Object MDC_MUTEX = new Object();

    public MyClass(String id) {
        this.id = id;
        // ...
    }

    public void doSomething()  {
        log("Doing Something...");
        // Do something...
    }

    private void log(String message) {
        synchronized(MDC_MUTEX) {
            MDC.put("id", id);
            logger.info(message);
        }
    }
}
Share:
11,867
Jman
Author by

Jman

I am a computer engineer student in Turkey .

Updated on June 11, 2022

Comments

  • Jman
    Jman almost 2 years

    I have a class that takes string parameter in its constructor which represents it.

    And i want to append this string as prefix at log messages. How can I do it in logback ?

    For example;

    MyClass classA = new MyClass("0999445454");
    
    MyClass classB = new MyClass("0999446464");
    
    classA.doSomething();
    classB.doSomething();
    

    The method of MyClass ;

    public void doSomething()  {
         logger.info("Doing Something...");
    
         //Do something
    }
    

    So i want to see log messages like that ;

    [INFO] [0999445454]: Doing Something...
    [INFO] [0999446464]: Doing Something...
    
  • Jman
    Jman over 9 years
    So at this situation, i must declare logger for each id. But at now, i have one logger. Can't i do it with one logger ?
  • xav
    xav over 9 years
    Using this solution, I don't think you can, because logger name used to instantiate it cannot be changed (yet, loggers are often instantiated for each class). If you want to avoid this, you can also use "Mapped Diagnostic Context" (MDC), I will update my answer in a few minutes to explain this
  • Jman
    Jman over 9 years
    Thanks for your replies.So at the last way, when i need to use logger object, i must always put id to MDC before logging, because to my knowledge the variables putted to MDC are stored in static map and id variable is same for all logger objects ?
  • xav
    xav over 9 years
    Yes, it's indeed a static map shared for all loggers. I meant "you shall call MDC.put() every time you want to log with a different id". I will clarify my answer for this point.
  • Jman
    Jman over 9 years
    Ok thanks :) but my class has lots of method and about 26 instance of my class will be run . I want to avoid adding "["+id+"]" to my log messages and the last way indeed looks same with that.
  • xav
    xav over 9 years
    You will not have to add "["+id+"]" to log messages, you will just put id in a map. I've completed my answer with a complete example.
  • Jman
    Jman over 9 years
    Is there any advantage using MDC.put in your log method according to using message = "["+id+"]" + message; And also, for logger.error,logger.warn i need different log methods. I think your response is acceptable because i think there is no any way.
  • xav
    xav over 9 years
    One advantage using MDC here is to avoid having one Logger for each ID (simply add static on logger attribute). Can be interesting if you have many instances of MyClass. As for other log levels: yes, you need one method for each log level.
  • Rafael Borja
    Rafael Borja about 6 years
    Very good. Any idea on how to work with multiple threads sharing the same logger?