基于呼叫者的不同记录器

时间:2015-03-25 14:08:16

标签: java log4j

我需要重新考虑一个主要项目的日志文件。目前,所有日志都转到同一个文件。该文件每天增长超过100MB。问题是每隔5分钟就会运行很多计划代码来填充日志文件。重新考虑因素的主要目标是由于计划而创建的所有日志都会分成不同的文件。

项目中的每个类都有以下内容:

final static Logger logger = LoggerFactory.getLogger(MyClass.class);

在运行计划的类中只更改它是很简单的:

final static Logger logger = LoggerFactory.getLogger("scheduledLogger");

问题是某些类是从调度类和非调度类调用的,日志记录必须转到相应的日志文件。

根本无法更改整个项目中的每个函数调用以发送相应的记录器。我想到的当前解决方案是创建一个object adapter,如下所示:

public class LoggerAdapter implements Logger {

private Logger defaultLogger;

private Logger scheduledLogger1 = LoggerFactory.getLogger("scheduledLogger1");

private Logger scheduledLogger2 = LoggerFactory.getLogger("scheduledLogger2");

//.. there are about 10 scheduled loggers

public LoggerWrapper(Class<?> Clazz) {
        defaultLogger = LoggerFactory.getLogger(Clazz);
}

//Implement each function like so
public void debug(String s) {
        Logger logger = findLoggerToUse();
        logger.debug(s);
}

public void trace(String s) {
    Logger logger = findLoggerToUse();
    logger.trace(s);
}

//See if logging has been called from a scheduled class
private Logger findLoggerToUse() {
        StackTraceElement[] stackTraceElements = Thread.currentThread().getStackTrace();
        for (StackTraceElement stackTraceElement : stackTraceElements) {
            String className = stackTraceElement.getClassName();
            if (fastStringCompare(className,SCHEDULED_CLASS_NAME_1)) {
                return scheduledLogger1;
            }
            if (fastStringCompare(className,SCHEDULED_CLASS_NAME_2)) {
                return scheduledLogger2;
            }
        }
        return defaultLogger;
    }

然后在整个项目的每个班级中我只需要改变:

private Logger logger = new LoggerAdapter(MyClass.class);

这个问题是trace(String s)将跟踪打印到LoggerAdapter而不是实际的调用者。我想知道是否有更好的方法来解决整个问题,或者是否有一个小的修复跟踪调用。

1 个答案:

答案 0 :(得分:0)

不要在任何地方更改代码,而是编写自定义appender。我建议您尝试使用slf4jlogback切换到log4j-2,因为两者都可以更加简单地编写自定义appender。 slf4j已替换旧的log4j API,log4j-2 has documentation how to migrate

现在你需要编写一个由线程局部变量控制的appender。 slf4j和旧的log4j称之为“MDC”,log4j-2将其称为“Thread Context”。

您可以在调度程序代码启动时设置此变量,并在调度程序代码结束时将其清除。在同一个线程中执行的所有操作最终都会通过appender,它可以检查变量并将消息路由到正确的文件。