【发布时间】:2014-07-07 22:52:17
【问题描述】:
我正在使用带有 log4j 2.0 或 logback 的 slf4j 作为实现。例如,我的 servlet 有一个级别为 ERROR 的记录器,而我的服务器产生了 100 个 servlet 线程。我会在运行时得到一个特殊用户的列表。当我检测到一些特殊用户连接时。我想将这些特殊用户/线程的日志级别更改为调试,而其他线程的日志级别不受影响(仍然是错误)。
我知道 logback 中的 TurboFilter 和 log4j 2.0 中的 DynamicThresholdFilter,但由于我只会在运行时获取特殊用户列表,因此无法使用它们。
这是我的申请:
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");
}
}
}
这是我在 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>
如果我调用以下方法:
App myApp = new App();
// assume the below 4 methods are called concurrently
myApp.writeToLogFile("user1");
myApp.writeToLogFile("user2");
myApp.writeToLogFile("user3");
myApp.writeToLogFile("user4");
预期的输出应该是:
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
【问题讨论】:
-
我不确定,我知道 ThreadContext 可以用于区分日志消息和线程,但我不知道它是否可以用于更改单个线程的日志级别。
-
你是如何创建你的记录器的?如果您想为每个线程配置设置,那么大概您在运行前不知道该线程是什么(即您没有在某些属性文件或其他东西中进行配置)。你不能只为你正在使用的对象的每个实例配置它吗?或者也许让它成为线程本地的,这样对它的更改只影响当前线程?
-
其实这个类是用来服务客户端的,所以我可以从当前线程中知道客户端信息,所以对于一两个特定的客户端,我希望能够为他们动态更改日志级别,如果它们连接到我的 servlet,不会影响其他人。
-
我之前的评论应该有效。
标签: java multithreading logging logback log4j2