log4j用于具有不同输出文件/配置的线程

时间:2015-01-30 22:30:21

标签: java multithreading logging log4j

我有一个应用程序可以完成一些工作并生成日志。 我使用org.apache.log4j.Logger 在我的课上,我写道:

static final Logger logger = Logger.getLogger(App.class);

在main I中加载文件

中的属性
 PropertyConfigurator.configure("log4j.properties");

并写输出

 logger.debug("Hello World!");

一切正常(log4j.properties的内容见下文)

现在我想重写一个生成不同线程的应用程序(它们将被预定作业并可以并行执行)。 据我所知,每个线程必须创建自己的记录器。像这样:

public class TestJob implements Job {
    private Logger thread_logger = null;
    //...
}

现在(在" do thread"方法中)我想设置此记录器的属性。

thread_logger = Logger.getLogger(TestJob.class); 
//and assign the configuration, but how?
PropertyConfigurator.configure("mythreadname.log4j.properties"); //?

原始记录器有一个log4j.properies文件(这里声明了输出文件):

# Root logger option
log4j.rootLogger=DEBUG, file, stdout

# Direct log messages to a log file
log4j.appender.file=org.apache.log4j.RollingFileAppender
log4j.appender.file.append=false
log4j.appender.file.File=.\\streambackup.execution.log
log4j.appender.file.MaxFileSize=100MB
log4j.appender.file.MaxBackupIndex=10
log4j.appender.file.layout=org.apache.log4j.PatternLayout
log4j.appender.file.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n

# Duplicate log messages to stdout
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target=System.out
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n

是否可以(以及如何操作) - 为每个线程(使用不同的输出文件)链接一个.property文件? 即我想这样做

main thread writes log to log\logmain.txt 
thread1 writes log to log\trh1\log1.txt 
thread2 writes log to log\trh2\log2.txt 
...
threadN writes log to log\trhN\logN.txt 
//I don't now the count of treads...

看来PropertyConfigurator是所有线程的全局?

2 个答案:

答案 0 :(得分:3)

您不需要为每个线程创建一个配置文件,但可以通过编程方式添加appender。 e.g:

public static class TestJob implements Job {

    private Logger logger;
    private RollingFileAppender appender;

    private void init() {
        logger = Logger.getLogger(TestJob.class);
        appender = new RollingFileAppender();
        appender.setLayout(new PatternLayout("%d %-5p %c{1}:%L - %m%n"));
        appender.setFile("logs/trh1/log1.txt");
        appender.setAppend(false);
        appender.setMaxFileSize("100MB");
        appender.setMaxBackupIndex(10);
        appender.activateOptions();
        logger.setAdditivity(false);
        logger.addAppender(appender);
    }

    private void destroy() {
        logger.removeAppender(appender);
    }

    public void execute(JobExecutionContext context) throws JobExecutionException {
        init();

        for (int i = 0; i < 10; i++) {
            if (logger.isInfoEnabled()) {
                logger.info("This is " + i);
            }
        }

        destroy();
    }

}

您可能希望看到Short introduction to log4j: Ceki Gülcü, March 2002

答案 1 :(得分:1)

这是我工作(我希望)Paul Vargas的代码更新 首先,我重写init函数调用。我根据工作身份命名:

public void execute(JobExecutionContext jExeCtx) throws JobExecutionException {
        JobKey jobKey = jExeCtx.getJobDetail().getKey();
        String OutputForLog = jExeCtx.getJobDetail().getJobDataMap().getString(PR_LOGFILNAME); //<--Here I pass the name of the log file from main thread to scheduller job
        init("Thread" + jobKey.toString().replaceAll("\\.", ""), OutputForLog);   //<-- Here I pass the name for appender and the path for log file name

init函数现在看起来像:

private Logger logger = null;
private RollingFileAppender appender = null;

private void init(String NameForAppender, String Name4LogFile) {
    logger = Logger.getLogger(NameForAppender); //NOT DEFAULT BY "logger = Logger.getLogger(TestJob.class);"

    appender = new RollingFileAppender();
    appender.setName(NameForAppender); //<-- I think this helps in pair of the Logger.getLogger(NameForAppender) above
    appender.setLayout(new PatternLayout("%d{yyyy-MM-dd/HH:mm:ss.SSS/zzz} %-5p %c{1}:%L - %m%n"));
    appender.setFile(Name4LogFile);
    appender.setAppend(true);
    appender.setImmediateFlush(true);
    appender.setMaxFileSize("100MB");
    appender.setMaxBackupIndex(10);
    appender.activateOptions();

    logger.setAdditivity(false);    //<--do not use default root logger
    logger.addAppender(appender);
}

至少使用此代码,我无法在文件中生成日志合并。 (我同时基于同一个类开始几个作业(线程))