log4j имена файлов журнала? - PullRequest
       7

log4j имена файлов журнала?

13 голосов
/ 17 сентября 2008

У нас есть несколько заданий, которые выполняются одновременно и должны использовать одну и ту же информацию конфигурации для log4j. Все они выгружают журналы в один файл с помощью одного и того же приложения. Есть ли способ, чтобы каждое задание динамически называло свой файл журнала, чтобы они оставались отдельными?

Спасибо
Том

Ответы [ 10 ]

21 голосов
/ 17 сентября 2008

Можете ли вы передать системное свойство Java для каждого задания? Если это так, вы можете параметризовать так:

java -Dmy_var=somevalue my.job.Classname

А потом в вашем log4j.properties:

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

Вы можете заполнить системное свойство Java значением из среды хоста (например), которое однозначно идентифицирует экземпляр задания.

3 голосов
/ 17 сентября 2008

В нашей системе реализовано нечто подобное. Мы храним определенные регистраторы в 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, что может не сработать, если вы выполняете одно и то же задание на работающем сервере, но это дает общее представление как это может работать.

3 голосов
/ 17 сентября 2008

Если имена заданий известны заранее, вы можете включить их в вызов getLogger (). Затем вы можете привязать разные приложения к различным регистраторам с разными именами файлов (или другими адресатами).

Если вы не можете знать имя задания заранее, вы можете настроить регистратор во время выполнения вместо использования файла конфигурации:

FileAppender appender = new FileAppender();
appender.setFileName(...);
appender.setLayout(...);
Logger logger = Logger.getLogger("com.company.job."+jobName);
logger.addAppender(appender);
2 голосов
/ 17 сентября 2008

Для каждого задания можно задать NDC или MDC, а затем написать приложение, которое меняет имя в зависимости от значения NDC или MDC. Создать нового appender не так уж сложно. В песочнице log4j также может быть приложение, которое будет отвечать всем требованиям. Начни смотреть в http://svn.apache.org/viewvc/logging/log4j/trunk/contribs/

1 голос
/ 30 ноября 2012

Опираясь на ответ shadit . Если каждое задание может быть идентифицировано тем, какой метод класса был запущен, вы можете использовать системное свойство sun.java.command, которое содержит полное имя запущенного класса. Например, как это:

log4j.appender.LOGFILE.File=${sun.java.command}.log

Я использую его вместе с TimestampFileAppender следующим образом:

log4j.appender.LOGFILE=TimestampFileAppender
log4j.appender.LOGFILE.TimestampPattern=yyyy_MM_dd__HH_mm
log4j.appender.LOGFILE.File=${sun.java.command}_{timestamp}.log

Таким образом, когда я занимаюсь разработкой в ​​Eclipse, я получаю новый файл журнала для каждого запускаемого мной нового процесса, идентифицируемый именем класса класса с основным методом и временем его запуска.

1 голос
/ 17 сентября 2008

Вы можете написать свой собственный appender, который создает свое собственное имя файла, возможно, используя метод [File.createTempFile] (http://java.sun.com/j2se/1.5.0/docs/api/java/io/File.html#createTempFile(java.lang.String,%20java.lang.String)). Если класс FileAppender написан правильно, вы сможете расширить его & mdash ; или RollingFileAppender & mdash; и переопределите метод getFile, чтобы он возвращал метод, выбранный вами, на основе новых свойств, которые вы хотели бы добавить.

0 голосов
/ 29 сентября 2012

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

Это еще один способ выполнить эту задачу .. здесь com.foo.admin - полное имя пакета

0 голосов
/ 17 сентября 2008

Вы можете реализовать следующее:

  • Держатель ThreadLocal для идентификации вашей работы.
  • Расширяя FileAppender, ваш FileAppender должен сохранять Карту, содержащую QuietWriter, для каждой вакансии. В методе subAppend вы получаете идентификатор своей работы из ThreadLocal, ищите (или создаете) QuietWriter и пишете в него ...

Я могу прислать вам код по почте, если вы хотите ...

0 голосов
/ 17 сентября 2008

Том, которого вы можете указать и добавьте для каждой работы. Допустим, у вас есть 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>
0 голосов
/ 17 сентября 2008

Вы можете программно настроить log4j при инициализации задания.

Вы также можете установить файл log4j.properties во время выполнения через системное свойство. Из руководства :

Задайте для строковой переменной ресурса значение системного свойства log4j.configuration . Предпочтительный способ указать файл инициализации по умолчанию - через системное свойство log4j.configuration. Если системное свойство log4j.configuration не определено, задайте для ресурса строковой переменной значение по умолчанию "log4j.properties".

Если вы выполняете задания из разных команд Java, это позволит им использовать разные файлы log4j.properties и разные имена файлов для каждого из них.

Без особых знаний о том, как выполняются ваши задания, трудно сказать!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...