Log4j - 更改特定记录器实例的记录器级别

时间:2014-09-22 10:13:21

标签: java logging log4j

我使用apache log4j进行应用程序日志记录。我的应用程序服务器启动时使用log4j.xml初始化记录器。对于每个类,我调用Loggers.getLogger(" loggername")来获取日志记录实例以记录该类的详细信息。

例如: 在log4j.xml中

<appender name="default" class="org.apache.log4j.RollingFileAppender">
                <param name="File" value="${log.dir}/logs/serverout.txt" />
                <param name ="Append" value="TRUE"/>
                <layout class="org.apache.log4j.PatternLayout">
                        <param name="ConversionPattern" value="%d{[HH:mm:ss:SSS]|[MM-dd-yyyy]}|[%c]|[%p]|[%L]: %m|%n"/>
                </layout>
                <param name="MaxFileSize" value="10MB"/>
                <param name="MaxBackupIndex" value="100"/>
</appender>
<logger name="com.mypackage" additivity="false">
                <level value="INFO"/>
                <appender-ref ref="default"/>
</logger>

我如何在每个班级中调用

private static Logger logger = Logger.getLogger(MPMyclass.class.getName());

我的要求:               基本上,我会在有许多用户会话时运行应用程序服务器。每个会话都有一个唯一的sessionId。每个会话都是几个类的实例。每个类都有自己的Logger实例。如果我想为特定类(MPMyclass)启用日志级别..我可以获取记录器名称(com.mypackage)并设置其级别,以便它更改整体级别。但我想以某种方式让我只能设置一个特定的会话而不是整体。               如果我有一个类名MPMyclass,有很多MPMyclass实例,我的要求是更改该类实例的记录器级别而不是所有实例。

可能的解决方案:            1.每个会话/实例都有一个唯一的sessionId。所以我可以获得/设定水平。但这太复杂了,因为设置/获取的课程很多很笨拙。            2.我可以使用Hashtable来存储每个类的实例以及它们的unqiue sessionid,但是也不推荐使用它,因为有太多的类和类的实例,它绝对不是一个好的解决方案。

我正在努力通过log4j或Java设计的帮助解决这个问题。如果我有什么可以处理的话,请建议我。

由于

2 个答案:

答案 0 :(得分:1)

我建议你编写一个自定义的RollingFileAppender(或任何其他Appender)来控制这个东西并将它与MDC和JMX结合起来。

看起来应该是这样的:

public class MyRollingFileAppender extends RollingFileAppender implements MyRollingFileAppenderMBean {

    private final Set<String> enabledSessions = new HashSet<>();

    @Override
    public synchronized void doAppend(LoggingEvent event) {
        if (enabledSessions.contains(event.getMDC("sessionId"))) {
            super.doAppend(event);
        }
    }

    @Override
    public synchronized void enable(String... sessionIds) throws JMException {
        for (String sessionId : sessionIds) {
            enabledSessions.add(sessionId);
        }
    }

    @Override
    public synchronized void disable(String... sessionIds) throws JMException {
        // do the opposite here...
    }

}

点击此链接了解有关MDC的信息:https://blog.oio.de/2010/11/09/logging-additional-information-like-sessionid-in-every-log4j-message/

答案 1 :(得分:0)

如果您的最终目标是轻松查找特定会话(或特定用户)的日志条目,您可以自动添加会话ID(或用户ID甚至自定义事务ID)每个日志条目。这可以使用Nested Diagnostic ContextMapped Diagnostic Context来完成。 Google可以为您提供许多使用示例。

如果您真的想要更改特定会话使用的特定类实例的日志级别,我认为这不是一个好主意。