log4j日志文件名?

时间:2020-03-05 18:59:01  来源:igfitidea点击:

我们有几个同时运行的作业,它们必须为log4j使用相同的配置信息。他们都使用相同的添加程序将日志转储到一个文件中。有没有一种方法可以让每个作业动态命名其日志文件,以使它们保持独立?

谢谢
汤姆

解决方案

回答

我们可以在初始化作业时以编程方式配置log4j。

我们还可以在运行时通过系统属性设置log4j.properties文件。从手册中:

Set the resource string variable to the value of the log4j.configuration system property. The preferred way to specify the default initialization file is through the log4j.configuration system property. In case the system property log4j.configuration is not defined, then set the string variable resource to its default value "log4j.properties".

假设我们从不同的Java命令运行作业,这将使它们能够使用不同的log4j.properties文件和每个文件使用不同的文件名。

没有关于工作如何运行的具体知识,很难说!

回答

我们可以为每个工作指定和添加汤姆。假设我们有2个作业,分别对应于两个不同的Java包com.tom.firstbatch和com.tom.secondbatch,在log4j.xml中将具有以下内容:

<category name="com.tom.firstbatch">
      <appender-ref ref="FIRST_APPENDER"/>
   </category>
   <category name="com.tom.secondtbatch">
      <appender-ref ref="SECOND_APPENDER"/>
   </category>

回答

如果提前知道作业名称,则可以在执行getLogger()调用时包括作业名称。然后,我们可以使用不同的文件名(或者其他目标)将不同的添加程序绑定到不同的记录器。

如果我们无法提前知道作业名称,则可以在运行时配置记录器,而不使用配置文件:

FileAppender appender = new FileAppender();
appender.setFileName(...);
appender.setLayout(...);
Logger logger = Logger.getLogger("com.company.job."+jobName);
logger.addAppender(appender);

回答

我们可以为每个作业传递Java系统属性吗?如果是这样,我们可以像这样进行参数化:

java -Dmy_var=somevalue my.job.Classname

然后在log4j.properties中:

log4j.appender.A.File=${my_var}/A.log

我们可以使用主机环境(例如)中的值填充Java系统属性,该值将唯一地标识作业实例。

回答

我们可以使用[File.createTempFile](http://java.sun.com/j2se/1.5.0/docs/api/java/io/File.html# createTempFile(java.lang.String,%20java.lang.String))方法。如果" FileAppender"类的编写正确,则应该能够扩展" RollingFileAppender"监视器,并覆盖" getFile"方法,以根据要添加的任何新属性返回我们选择的方法。

回答

我们可以为每个作业设置NDC或者MDC,然后编写一个根据NDC或者MDC值更改名称的添加程序。创建一个新的添加程序并不难。在log4j沙箱中可能还会有一个适合该帐单的添加程序。开始在http://svn.apache.org/viewvc/logging/log4j/trunk/contribs/中查找

回答

我们可以执行以下操作:

  • 一个ThreadLocal持有人,用于确定工作身份。
  • 扩展FileAppender,FileAppender必须为每个作业标识保留一个包含QuietWriter的Map。在方法subAppend中,我们可以从ThreadLocal获取作业的标识,然后查找(或者创建)QuietWriter并将其写入...

如果我们愿意,我可以通过邮件向我们发送一些代码...

回答

我们在系统中实现了类似的功能。我们将特定的记录器存储在HashMap中,并根据需要为每个记录器初始化添加程序。

这是一个例子:

public class JobLogger {
private static Hashtable<String, Logger> m_loggers = new Hashtable<String, Logger>();
private static String m_filename = "...";  // Root log directory

public static synchronized void logMessage(String jobName, String message)
{
    Logger l = getJobLogger(jobName);
    l.info(message);
}

public static synchronized void logException(String jobName, Exception e)
{
    Logger l = getJobLogger(partner);
    l.info(e.getMessage(), e);
}

private static synchronized Logger getJobLogger(String jobName)
{
    Logger logger = m_loggers.get(jobName);
    if (logger == null) {
        Layout layout = new PatternLayout("...");
        logger = Logger.getLogger(jobName);
        m_loggers.put(jobName, logger);
        logger.setLevel(Level.INFO);
        try {
            File file = new File(m_filename);
            file.mkdirs();
            file = new File(m_filename + jobName + ".log");
            FileAppender appender = new FileAppender(layout, file.getAbsolutePath(), false);
            logger.removeAllAppenders();
            logger.addAppender(appender);
    }
        catch (Exception e)
    { ... }
    }
    return logger;
}
}

然后,要在工作中使用它,我们只需要使用如下一行内容:

JobLogger.logMessage(jobName, logMessage);

这将为每个作业名称创建一个日志文件,并将其放入我们指定的目录中的该作业名称的文件中。

我们可以摆弄其他类型的添加程序,诸如此类,它将继续添加,直到重新启动JVM为止;如果我们在始终运行的服务器上运行相同的作业,则该JVM可能无法正常工作,但是这给出了一般的思路工作。