Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/logging/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java log4j日志文件名?_Java_Logging_Log4j - Fatal编程技术网

Java log4j日志文件名?

Java log4j日志文件名?,java,logging,log4j,Java,Logging,Log4j,我们有几个并发运行的作业,它们必须为log4j使用相同的配置信息。它们都使用相同的appender将日志转储到一个文件中。有没有办法让每个作业动态命名其日志文件,以便它们保持分离 谢谢 Tom初始化作业时,可以通过编程方式配置log4j 还可以在运行时通过系统属性设置log4j.properties文件。从: 将资源字符串变量设置为log4j.configuration系统属性的值。指定默认初始化文件的首选方法是通过log4j.configuration系统属性。如果未定义系统属性log4j.c

我们有几个并发运行的作业,它们必须为log4j使用相同的配置信息。它们都使用相同的appender将日志转储到一个文件中。有没有办法让每个作业动态命名其日志文件,以便它们保持分离

谢谢

Tom

初始化作业时,可以通过编程方式配置log4j

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

将资源字符串变量设置为log4j.configuration系统属性的值。指定默认初始化文件的首选方法是通过log4j.configuration系统属性。如果未定义系统属性log4j.configuration,则将字符串变量资源设置为其默认值“log4j.properties”

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


如果不知道你的工作是如何运行的,很难说

您可以为每个作业指定和附加程序。假设您有两个作业对应于两个不同的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
JobLogger.logMessage(jobName, logMessage);
log4j.appender.LOGFILE.File=${sun.java.command}.log
log4j.appender.LOGFILE=TimestampFileAppender
log4j.appender.LOGFILE.TimestampPattern=yyyy_MM_dd__HH_mm
log4j.appender.LOGFILE.File=${sun.java.command}_{timestamp}.log
然后在log4j.properties中:

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

您可以使用来自主机环境(例如)的值来填充Java system属性,该值将唯一标识作业实例。

您可以编写自己的appender,以构成自己的文件名,可能使用[File.createTempFile](方法。如果
FileAppender
类编写正确,您应该能够扩展它或
RollingFileAppender
,并重写
getFile
方法,以返回一个根据您希望添加的任何新属性选择的方法。

您可以将每个作业设置为NDC或MDC,然后编写一个根据NDC或MDC值更改名称。创建一个新的appender并不困难。可能还有一个appender可以在log4j沙箱中满足账单要求。开始查看您可以实现以下功能:

  • 您的工作身份的本地持有者
  • 扩展FileAppender,您的FileAppender必须为每个作业标识保留一个包含QuietWriter的映射。在方法subAppend中,您从ThreadLocal获取作业标识,您可以查找(或创建)QuietWriter并写入它

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

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

下面是一个例子:

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;
}
}
这将为每个作业名创建一个日志文件,并将其放入自己的文件中,该作业名位于您指定的目录中


您可以摆弄其他类型的追加器,如编写的,它将继续追加,直到JVM重新启动。如果您在始终处于运行状态的服务器上运行同一个作业,这可能不起作用,但这给出了它如何工作的一般概念。

log4j.logger.com.foo.admin=,AdminFileAppender= log4j.logger.com.foo.report=,ReportFileAppender

这是执行此任务的另一种方法。.这里com.foo.admin是完整的包名

基于的答案。如果可以通过启动哪个类的主方法来标识每个作业,则可以使用系统属性
sun.java.command
,该属性包含已启动类的完整名称。例如:

java -Dmy_var=somevalue my.job.Classname
JobLogger.logMessage(jobName, logMessage);
log4j.appender.LOGFILE.File=${sun.java.command}.log
log4j.appender.LOGFILE=TimestampFileAppender
log4j.appender.LOGFILE.TimestampPattern=yyyy_MM_dd__HH_mm
log4j.appender.LOGFILE.File=${sun.java.command}_{timestamp}.log
我把它和一个类似的

java -Dmy_var=somevalue my.job.Classname
JobLogger.logMessage(jobName, logMessage);
log4j.appender.LOGFILE.File=${sun.java.command}.log
log4j.appender.LOGFILE=TimestampFileAppender
log4j.appender.LOGFILE.TimestampPattern=yyyy_MM_dd__HH_mm
log4j.appender.LOGFILE.File=${sun.java.command}_{timestamp}.log
这样,当我在Eclipse中开发时,我会为我运行的每个新进程获得一个新的日志文件,由类的类名和主方法及其启动时间标识