Log4j имена файлов журнала?
У нас есть несколько заданий, которые запускаются одновременно, которые должны использовать одну и ту же конфигурационную информацию для log4j. Все они записывают журналы в один файл, используя один и тот же файл. Есть ли способ, чтобы каждая работа динамически называла свой файл журнала, чтобы они оставались отдельно?
Спасибо
Том
Ответы
Ответ 1
Можете ли вы передать системное свойство Java для каждой работы? Если это так, вы можете параметризовать следующее:
java -Dmy_var=somevalue my.job.Classname
И затем в вашем log4j.properties:
log4j.appender.A.File=${my_var}/A.log
Вы можете заполнить свойство системы Java значением из среды хоста (например), которое однозначно идентифицирует экземпляр задания.
Ответ 2
Если имена заданий известны заранее, вы можете включить имя задания при вызове getLogger(). Затем вы можете привязывать разные приложения к различным регистраторам с отдельными именами файлов (или другими адресами).
Если вы не можете узнать имя задания раньше времени, вы можете настроить логгер во время выполнения, вместо использования файла конфигурации:
FileAppender appender = new FileAppender();
appender.setFileName(...);
appender.setLayout(...);
Logger logger = Logger.getLogger("com.company.job."+jobName);
logger.addAppender(appender);
Ответ 3
В нашей системе реализовано нечто подобное. Мы храним конкретные регистраторы в 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 не будет перезапущен, что может не сработать, если вы выполняете ту же работу на сервере, который всегда вверх, но это дает общее представление о как это может работать.
Ответ 4
У вас может быть задано задание NDC или MDC, а затем написать приложение, которое меняет имя на основе значения NDC или MDC. Создание нового приложения не слишком сложно. Также может быть приложение, которое будет соответствовать счету в песочнице log4j. Начать поиск http://svn.apache.org/viewvc/logging/log4j/trunk/contribs/
Ответ 5
Вы можете написать свой собственный 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
был написан правильно, вы должны иметь возможность расширять его, или RollingFileAppender
— и переопределить метод getFile
, чтобы вернуть тот, который вы выбираете, на основе любых новых свойств, которые вы хотели бы добавить.
Ответ 6
На основе 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, я получаю новый файл журнала для каждого нового процесса, который я запускаю, идентифицируется классом класса с основным методом и временем его запуска.
Ответ 7
Вы можете программно настроить log4j при инициализации задания.
Вы также можете установить файл log4j.properties во время выполнения через системное свойство. Из manual:
Задайте переменную строки ресурса значению свойства системы log4j.configuration. Предпочтительный способ указать файл инициализации по умолчанию - это свойство системы log4j.configuration. Если системное свойство log4j.configuration не определено, установите для ресурса строковой переменной значение по умолчанию "log4j.properties".
Предполагая, что вы выполняете задания из разных java-команд, это позволит им использовать разные файлы log4j.properties и разные имена файлов для каждого из них.
Без особых знаний о том, как работают ваши задания, трудно сказать!
Ответ 8
Том, который вы укажете и добавляет для каждой работы. Пусть у вас есть 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>
Ответ 9
вы можете реализовать следующее:
- Держатель ThreadLocal для идентификации вашей работы.
- Расширьте FileAppender, ваш FileAppender должен хранить карту с QuietWriter для каждого идентификатора задания. В методе subAppend вы получаете личность своей работы из ThreadLocal, вы ищете (или создаете) QuietWriter и записываете в нее...
Я могу отправить вам код по почте, если вы хотите...
Ответ 10
= log4j.logger.com.foo.admin, AdminFileAppender
log4j.logger.com.foo.report =, ReportFileAppender
Это другой способ выполнить эту задачу.. здесь com.foo.admin - это полное имя пакета