【问题标题】:log4j for threads with different output files/configslog4j 用于具有不同输出文件/配置的线程
【发布时间】:2015-01-30 22:30:20
【问题描述】:

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

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

在 main 我从文件中加载属性

 PropertyConfigurator.configure("log4j.properties");

并写入输出

 logger.debug("Hello World!");

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

现在我想重写一个将生成不同线程的应用程序(它们将被调度作业并且可能并行执行)。 据我了解,每个线程都必须创建自己的记录器。像这样的:

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

现在(在“做线程”方法中)我想为这个记录器设置属性。

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 文件(具有不同的输出文件)? IE。我想这样做

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 好像对所有线程都是全局的?

【问题讨论】:

    标签: java multithreading logging log4j


    【解决方案1】:

    您不需要为每个线程创建一个配置文件,但您可以通过编程方式添加附加程序。例如:

    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

    【讨论】:

    • 谢谢,但这不是我所需要的。当我开始 2 份或更多相同班级的工作时,我的文件一团糟。附加程序已合并 :) 在第一个文件中,我从每个线程收到消息:2015-02-02/23:39:00.027/MSK INFO TestJob:57 - 从 SBScheduler_Worker-1 开始 TestJob: BackupGroup.testJob1 2015-02-02 /23:39:00.048/MSK INFO TestJob:57 - 从 SBScheduler_Worker-2 开始 TestJob: BackupGroup.testJob2 2015-02-02/23:39:02.049/MSK INFO TestJob:59 - 完成 TestJob: BackupGroup.testJob2 从 SBScheduler_Worker- 2 在 ...
    • 我想我通过重命名 appender 解决了这个问题:见下文
    • 我认为我的解决方案可以为您提供一些构建自己的解决方案的想法。你看到e.g.了吗?
    【解决方案2】:

    这是我的工作(我希望)更新 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);
    }
    

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

    【讨论】:

      猜你喜欢
      • 2019-05-25
      • 1970-01-01
      • 2014-06-12
      • 2015-06-16
      • 2021-01-04
      • 1970-01-01
      • 2013-12-31
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多