I'm using slf4j with either log4j 2.0 or logback as the implementation. For example, my servlet has a logger with level ERROR, and my server spawns 100 threads of the servlet. I will get a list of special users at runtime. When I detect some of the special users connected in. I want to change the log level for those special users/threads to DEBUG, and leave other threads' log level unaffected (still ERROR).
I know the TurboFilter in logback and DynamicThresholdFilter in log4j 2.0, but since I will only get the special users list at runtime, I cannot use them.
Here is my application:
package com.example.logging;
import java.util.HashMap;
import java.util.Map;
import javax.servlet.http.HttpServlet;
import org.slf4j.*;
public class App extends HttpServlet {
private final Logger Logger = LoggerFactory.getLogger(App.class);
Map<String, String> map = new HashMap<String, String>();
public App() {
map.put("user1", "DEBUG");
map.put("user2", "DEBUG");
map.put("user3", "ERROR");
}
public void writeToLogFile(String userName) {
if (map.containsKey(userName)) {
// do something so that I can change the logger to the corresponding log level
}
Logger.error(userName + " error message");
// the logger is of level ERROR, so by default, this log event will not happen
// but I want it to happen for special users
if (Logger.isDebugEnabled()) {
Logger.debug(userName + " debug message");
}
}
}
Here is my log configuration in log4j2.xml
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="ERROR">
<Appenders>
<Console name="Console" target="SYSTEM_OUT">
<PatternLayout pattern="%-5level %class{36} %M %msg%xEx%n" />
</Console>
</Appenders>
<Loggers>
<Logger name="com.example.logging.App" level="ERROR" additivity="false">
<AppenderRef ref="Console" />
</Logger>
<Root level="DEBUG">
<AppenderRef ref="Console" />
</Root>
</Loggers>
</Configuration>
If I call the methods below:
App myApp = new App();
// assume the below 4 methods are called concurrently
myApp.writeToLogFile("user1");
myApp.writeToLogFile("user2");
myApp.writeToLogFile("user3");
myApp.writeToLogFile("user4");
The expected output should be:
ERROR com.example.logging.App writeToLogFile - user1 error message
DEBUG com.example.logging.App writeToLogFile - user1 debug message
ERROR com.example.logging.App writeToLogFile - user2 error message
DEBUG com.example.logging.App writeToLogFile - user2 debug message
ERROR com.example.logging.App writeToLogFile - user3 error message
ERROR com.example.logging.App writeToLogFile - user4 error message