如何使用AspectJ动态更改Log4j输出文件名



我在一个Tomcat中部署了同一个应用程序的多个版本。它们中的每一个都有相同的Log4j配置文件。因此,当所有这些应用程序写入日志时,它们最终会在同一个目录中。

我想知道是否有一种方法可以根据部署的应用程序的版本号动态更新日志的各自位置。

是。因为我没有Tomcat经验,所以我只是使用一个任意的JAR文件(Apache Commons Compress 1.4.1)来读取清单数据。您可以轻松地调整示例代码以满足您的需求。

假设您有这样一个应用程序:

package de.scrum_master.aop.java;
import java.util.Enumeration;
import org.apache.commons.compress.archivers.zip.ZipArchiveInputStream;
import org.apache.log4j.*;
public class Application {
    public static void main(String[] args) throws Exception {
        Logger logger = Logger.getLogger(ZipArchiveInputStream.class);
        logger.addAppender(new ConsoleAppender(new SimpleLayout()));
        logger.addAppender(new FileAppender(new SimpleLayout(), "my.log"));
        logger.info("Logger: " + logger.getName());
        logger.info("Appenders:");
        for (Enumeration<Appender> appenders = logger.getAllAppenders(); appenders.hasMoreElements();) {
            Appender appender = appenders.nextElement();
            if (appender instanceof FileAppender)
                logger.info("  " + appender + ": " + ((FileAppender) appender).getFile());
            else
                logger.info("  " + appender);
        }
    }
}

不包含AspectJ的输出如下:

INFO - Logger: org.apache.commons.compress.archivers.zip.ZipArchiveInputStream
INFO - Appenders:
INFO -   org.apache.log4j.ConsoleAppender@32c41a
INFO -   org.apache.log4j.FileAppender@e89b94: my.log

这并不奇怪。现在让我们假设我们想要在ZipArchiveInputStream的父JAR中添加一个从清单中读取的版本号。为了实现这一点,我们可以拦截对Log4J FileAppender的构造函数调用,并只操作第二个参数,该参数恰好总是文件名。为简单起见,我没有拦截默认构造函数或任何setter。

package de.scrum_master.aop.aspectj;
import org.apache.commons.compress.archivers.zip.ZipArchiveInputStream;
import org.apache.log4j.FileAppender;
public aspect LogFileChanger {
    pointcut fileAppenderCreation(String fileName) :
        call(public FileAppender.new(*, String, ..)) && args(*, fileName, ..);
    FileAppender around(String fileName) : fileAppenderCreation(fileName) {
        Class<?> clazz = ZipArchiveInputStream.class;
        Package pkg = clazz.getPackage();
        return proceed(fileName + "." + pkg.getSpecificationVersion());
    }
}

现在输出如下所示:

INFO - Logger: org.apache.commons.compress.archivers.zip.ZipArchiveInputStream
INFO - Appenders:
INFO -   org.apache.log4j.ConsoleAppender@12d03f9
INFO -   org.apache.log4j.FileAppender@5ffb18: my.log.1.4.1

宾果!我们已经动态地更改了日志文件名。:-)

最新更新