Пользовательские поля Log4J
Введение:
Я пытаюсь получить дополнительные поля для входа в log4j и его работу, но только тогда, когда я создаю приложение в коде, а не в log4j.properties
Прогресс:
Проблема:
используя файл свойств, который будет запущен, но не будет использовать AppServerPatternLayout, чтобы пользовательские поля не отображались.
customlog.properties
log4j.rootLogger=FATAL
log4j.logger.some.log=INFO,stdout
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=logging.AppServerPatternLayout
log4j.appender.stdout.layout.ConversionPattern=-----------------using log file------------------------%nTime: %d%nHost: %h%nServer: %s%nComponent: %b%nVersion: %v%nPriority: %p%nThread Id: %t%nContext: %x%nMessage: %m%n
Запись в Main.java без файла свойств log4j
AppServerLoggerFactory factory;
factory = new AppServerLoggerFactory("MyServer", "MyComponent", "1.0");
AppServerLogger.setFactory(factory);
Logger logger = AppServerLogger.getLogger("some.log");
PatternLayout layout = new AppServerPatternLayout( formatString );
logger.addAppender( new ConsoleAppender(layout) );
logger.info("Hello");
Запись в Main.java с файлом свойств log4j
PropertyConfigurator.configure("customlog.properties");
AppServerLoggerFactory factory;
factory = new AppServerLoggerFactory("MyServer", "MyComponent", "1.0");
AppServerLogger.setFactory(factory);
Logger logger = AppServerLogger.getLogger("some.log");
logger.info("Hello");
Ожидаемый результат
----------------using in code appender----------------------
Time: 2009-11-06 12:55:05,785
Host: M1330
Server: MyServer
Component: MyComponent
Version: 1.0
Priority: INFO
Thread Id: main
Context:
Message: logging config from code
Фактический выход
-----------------using log file------------------------
Time: 2009-11-06 12:56:17,983
Host:
Server:
Component:
Version:
Priority: INFO
Thread Id: main
Context:
Message: logging config from customlog.properties
Решение
Используя MDC, вы можете добавить настраиваемые поля, например
MDC.put("Version", versionName);
Logger log = LogManager.getLogger("some.log");
log.info("Hello");
и вытащите его в файле log4j.properties с ВЕРХНИЙ случай X
log4j.appender.stdout.layout.ConversionPattern=%X{Version}
Ответы
Ответ 1
Из приведенного вами примера я могу только догадываться, что AppServerPatternLayout
не находится в пакете logging
. Все остальное выглядит находкой. Добавить
log4j.DEBUG=true
в файл свойств. log4j затем сбрасывает то, что он делает, читая свойства. Возможно, это дает вам представление о том, что неправильно.
Если это не помогает, рассмотрите Вложенные диагностические контексты.
Ответ 2
Может ли быть, что при загрузке через свойства создается AppServerPatternLayout
до создания AppServerLoggerFactory
? Если вы выбираете значения своих настраиваемых полей при создании, а не вначале, это может быть объяснением.
Ответ 3
Я не уверен, что вы достигнете этого с настройкой свойств, но я думаю, вы можете сделать это с помощью XML, что дает вам множество настроек:
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
<log4j:configuration
xmlns:log4j="http://jakarta.apache.org/log4j/"
debug="true"
reset="true"
>
<appender name="stdout" class="org.apache.log4j.ConsoleAppender">
<param name="Target" value="System.out"/>
<layout class="your.package.AppServerPatternLayout">
<param name="ConversionPattern" value="YOUR CONVERSION PATTERN"/>
</layout>
</appender>
<root>
<level value="info"/>
<appender-ref ref="stdout" />
</root>
<loggerFactory class="your.package.AppServerLoggerFactory">
<param name="server" value="MyServer"/>
<param name="component" value="MyComponent"/>
<param name="version" value="1.0r"/>
</loggerFactory>
</log4j:configuration>
Вам нужно будет определить сеттеры на AppServerLoggerFactory
для сервера, компонента и версии. Кроме того, прочитайте log4j.dtd
в общем макете файла конфигурации xml.
Сохраните этот файл как log4j.xml и определите -Dlog4j.configuration =/path/to/log4j.xml в своем старте script или замените log4j.properties на log4j.xml в своем веб-приложении.
Я раньше не пробовал пользовательский LoggerFactory, но может быть, потому что он установлен конфигуратором, вы можете использовать стандартные вызовы getLogger
factory, например.
//Logger logger = AppServerLogger.getLogger("some.log");
Logger logger = Logger.getLogger("some.log");