Подтвердить что ты не робот

Конфигурация Log4j - разные журналы для разных файлов

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

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

# Root logger option
log4j.rootLogger=INFO, file, admin

# Direct log messages to a log file
log4j.appender.file=org.apache.log4j.RollingFileAppender
log4j.appender.file.File=/home/nick/logging/file.log
log4j.appender.file.MaxFileSize=1MB
log4j.appender.file.MaxBackupIndex=1
log4j.appender.file.layout=org.apache.log4j.PatternLayout
log4j.appender.file.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1} - %m%n

log4j.appender.admin=org.apache.log4j.RollingFileAppender
log4j.appender.admin.File=/home/nick/logging/admin.log
log4j.appender.admin.MaxFileSize=1MB
log4j.appender.admin.MaxBackupIndex=1
log4j.appender.admin.layout=org.apache.log4j.PatternLayout
log4j.appender.admin.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1} - %m%n

И вот мое (очень простое) приложение Java, используемое для проверки конфигурации:

public static void main(String[] args) throws Exception {

    Properties resource = new Properties();
    InputStream in = new FileInputStream("/home/nick/logging/log4j.properties");
    resource.load(in);
    PropertyConfigurator.configure(resource);

    Logger admin = Logger.getLogger("admin");
    Logger file = Logger.getLogger("file");

    admin.info("hello admin");
    file.info("hello file");
}

У меня есть 2 проблемы:

Одна проблема: я всегда получаю исключение в строке PropertyConfigurator.configure(resource);:

java.io.FileNotFoundException: /home/nick/logging (Is a directory)
 at java.io.FileOutputStream.open(Native Method)
 at java.io.FileOutputStream.<init>(FileOutputStream.java:212)
 at java.io.FileOutputStream.<init>(FileOutputStream.java:136)
 at org.apache.log4j.FileAppender.setFile(FileAppender.java:289)
 at org.apache.log4j.RollingFileAppender.setFile(RollingFileAppender.java:167)
 at org.apache.log4j.FileAppender.activateOptions(FileAppender.java:163)
 at org.apache.log4j.config.PropertySetter.activate(PropertySetter.java:256)

Вторая проблема заключается в том, что оба сообщения записываются в оба журнала. Вот результат фактический:

Администратор файла: журнал:

2014-04-27 11:55:30 INFO  admin - hello admin
2014-04-27 11:55:30 INFO  file - hello file

Файл file.log:

2014-04-27 11:55:30 INFO  admin - hello admin
2014-04-27 11:55:30 INFO  file - hello file

Вот результат требуемый:

Администратор файла: журнал:

2014-04-27 11:55:30 INFO  admin - hello admin

Файл file.log:

2014-04-27 11:55:30 INFO  file - hello file

Что вызывает исключение и как я могу достичь требуемого результата?

4b9b3361

Ответ 1

Log4J делает различие между регистраторами, которые отвечают за генерирование сообщений журнала, и приложениями, которые несут ответственность за отправку этих сообщений где-нибудь (файл, консоль, база данных и т.д.). Регистраторы формируют иерархию, корневой регистратор - это родительский журнал регистратора с именем admin, который является родительским элементом admin.component1 и т.д., И вы можете присоединять к любому регистратору в иерархии. По умолчанию регистратор отправляет сообщения всем приятелям, которые прикреплены непосредственно к нему, или любому из его предков в иерархии (поэтому регистраторы обычно называются как классы Java, например, вы можете управлять протоколированием для com.example.Class1 и com.example.subpkg.AnotherClass путем настройки регистратора com.example).

Регистраторы и приставки образуют отдельные пространства имен, и это является источником вашей путаницы - регистратор с именем admin, а appender с именем admin - это два отдельных объекта.

Конфигурация, заданная вами в вопросе, определяет один регистратор (корневой журнал), который отправляет все сообщения, которые он генерирует, в два отдельных приложения, по одному для каждого из двух файлов. Затем ваш код запрашивает два разных регистратора и генерирует одно сообщение журнала с каждым регистратором. Оба этих регистратора наследуют конфигурацию приложения от корневого регистратора, поэтому оба отправляют свои сообщения в оба настроенных приложения.

enter image description here

Вместо того, чтобы прикреплять два добавителя к корневому журналу, вы должны прикрепить file appender к регистратору file и приложению admin к регистратору admin:

log4j.rootLogger=INFO
log4j.logger.file=INFO, file
log4j.logger.admin=INFO, admin

Таким образом, регистратор file отправляет сообщения только на file.log, регистратор admin только на admin.log, и все сообщения от других регистраторов будут отброшены молча, так как нет добавлений, прикрепленных к корню.

enter image description here


Флаг аддитивности является исключением из этого правила - установка логической аддитивности на false существенно отключает стрелку от регистратора до его родителя, поэтому сообщения, сгенерированные этим регистратором (или втекающие в него от одного из его дочерних элементов), не будут идти дальше по дереву, они будут поступать только в приставки, прикрепленные непосредственно к указанному регистратору.

Ответ 2

Чтобы ответить на мой вопрос, это то, что мне нужно:

log4j.logger.file=DEBUG, fileAppender
log4j.logger.admin=DEBUG, adminAppender

log4j.additivity.file=false
log4j.additivity.admin=false

log4j.appender.fileAppender=org.apache.log4j.RollingFileAppender
log4j.appender.fileAppender.File=/home/nick/logging/file.log
log4j.appender.fileAppender.MaxFileSize=1MB
log4j.appender.fileAppender.MaxBackupIndex=1
log4j.appender.fileAppender.layout=org.apache.log4j.PatternLayout
log4j.appender.fileAppender.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1} - %m%n

log4j.appender.adminAppender=org.apache.log4j.RollingFileAppender
log4j.appender.adminAppender.File=/home/nick/logging/admin.log
log4j.appender.adminAppender.MaxFileSize=1MB
log4j.appender.adminAppender.MaxBackupIndex=1
log4j.appender.adminAppender.layout=org.apache.log4j.PatternLayout
log4j.appender.adminAppender.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1} - %m%n

Ответ 3

Вам не нужно загружать файл свойств. Просто поместите его в папку src, которая будет автоматически добавлена ​​в путь класса.

Пример кода:

public static void main(String[] args) throws Exception {

   Logger admin = Logger.getLogger("admin");
   Logger file = Logger.getLogger("file");

   admin.info("hello admin");
   file.info("hello file");
}

Ответ 4

Во-первых: log4j рекомендует использовать файл формата XML для свойств.

Во-вторых: лучше загрузить файл свойств в загрузчик классов.

В-третьих: есть наследование в журнале, но вы можете разрезать его с помощью свойства аддитивности, см. файл log4j.properties - несколько журналов в том же классе