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

时间:2013-05-30 20:27:45

标签: logging log4j aspectj

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

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

1 个答案:

答案 0 :(得分:0)

是。因为我没有Tomcat经验,所以我只是使用任意JAR文件(Apache Commons Compress 1.4.1)到read manifest data。您可以轻松调整示例代码以满足您的需求。

假设您有这样的应用程序:

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

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