Вопрос

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

Спасибо
Том

Это было полезно?

Решение

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

java -Dmy_var=somevalue my.job.Classname

И затем в вашем log4j.properties:

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

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

Другие советы

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

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

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

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

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

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

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

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

Я использую его вместе с Метка времениФайлAppender так:

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

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

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

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

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

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

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

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

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

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

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

log4j.logger.com.foo.admin =, adminfileAppender log4j.logger.com.foo.report =, отчетфилиапендер

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top