How to configure logback to append special prefix for each object?
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);
}
}
}
Comments
-
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 over 9 yearsSo 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 over 9 yearsUsing 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 over 9 yearsThanks 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 over 9 yearsYes, 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 differentid
". I will clarify my answer for this point. -
Jman over 9 yearsOk 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 over 9 yearsYou 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 over 9 yearsIs 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 over 9 yearsOne advantage using MDC here is to avoid having one Logger for each ID (simply add
static
onlogger
attribute). Can be interesting if you have many instances ofMyClass
. As for other log levels: yes, you need one method for each log level. -
Rafael Borja about 6 yearsVery good. Any idea on how to work with multiple threads sharing the same logger?