根据记录器名称记录到不同的文件

时间:2014-03-26 17:59:37

标签: java logging log4j

我有以下问题。我正在开发一个应用程序,它为所有记录器使用文件appender(log4j版本1.2)。一切正常,但现在我需要根据一些运行时参数登录到不同的文件。

作为限制,我还需要限制log4j.xml配置信息的数量,因为我事先不知道这个参数会占用多少个值,因此我无法配置不同的appender(FileAppenders)指向log4j配置文件中的不同文件。我还需要限制添加的新代码量,例如,可以将运行时参数作为记录器名称的一部分传递(LoggerFactory.getLogger(runtimeParameter + getClass)等),但我不想创建一个新的FileAppender按代码,然后将新的Appender添加到最近创建的记录器中(作为一个附带问题,这个替代方案会起作用吗?)。

我认为也许创建一个基于他提供的名称(基于运行时参数)打开不同文件的新appender会起作用,但我不知道该怎么做,我不知道它会怎样并发执行时的行为(因为它将是所有记录器的单个追加器)。

谢谢你,原谅我的英语!

1 个答案:

答案 0 :(得分:0)

在您的情况下,听起来最简单的解决方法是以编程方式实时配置和创建记录器对象。

是的,它有效。幸运的是,我刚刚解决了这个问题,并提供了示例代码。这是针对log4j2的。我相信它在1.2

中更容易和直接
/**
 * Dynamically creates an instance of a Logger.
 * 
 * @param appenderName
 *            most often will be the name of the class this logger will
 *            belong to.
 * @param logFileName
 *            the file name to save the logs to
 * @return
 */
public static org.apache.logging.log4j.Logger createInstanceLogger(String appenderName,
        String logFileName) {
    //call getLogger() which will create and load a logger with a default configuration
    org.apache.logging.log4j.Logger logger = org.apache.logging.log4j.LogManager
            .getLogger(String.format("DynamicLogger%s",
                    String.valueOf(DynamicLogManager.loggerCount++)));
    org.apache.logging.log4j.core.Logger coreLogger = (org.apache.logging.log4j.core.Logger) logger; // cast logger to core logger to access protected methods
    org.apache.logging.log4j.core.LoggerContext context = coreLogger.getContext();
    org.apache.logging.log4j.core.config.BaseConfiguration configuration = (org.apache.logging.log4j.core.config.BaseConfiguration) context
            .getConfiguration();

    TriggeringPolicy compositePolicy = CompositeTriggeringPolicy.createPolicy(
            SizeBasedTriggeringPolicy.createPolicy("5mb"),
            TimeBasedTriggeringPolicy.createPolicy("1", "true"));

    String fileName = String.format("%1$s/%2$s", appenderName, logFileName);
    String filePattern = String.format("%1$s/%2$s.%%d{yyyy-MM-dd}",
            appenderName, logFileName);

    Layout<String> layout = PatternLayout.createLayout(DynamicLogManager._conversionPattern,
            configuration, RegexReplacement.createRegexReplacement("a^", "."), //empty regex replacement
            "utf-8", "false");

    Filter f = ThresholdFilter.createFilter("trace", "accept", "accept");

    Appender a = RollingFileAppender.createAppender(fileName, //fileName
            filePattern, //filePattern
            "true", //append
            appenderName, //appender name
            "true", //bufferred io
            "true", //immediate flush
            compositePolicy, //policy
            null, //strategy default
            layout, //layout
            f, //filter none
            "true", //ignore exceptions
            "false", //advertise
            "null", //advertise uri
            configuration //configuration
            );

    a.start();

    coreLogger.addAppender(a);

    //this is where we would figure out how to configure the logger to listen on a configuration file
    coreLogger.setLevel(Level.ALL); //set the log level of the logger that we are returning to Level.ALL

    return coreLogger; //cast logger back to Logger interface