Часто при использовании Log4j бывает нужно фильтровать сообщения по тому или иному критерию.
Для этих целей в Log4j предусмотрен механизм фильтров. Фильтр это класс унаследованный от org.apache.log4j.spi.Filter. Фильтр устанавливается для конкретного Appender-а, фильтры могу образовывать цепочку. Каждый фильтр получает объект типа LoggingEvent и должен вернуть результат фильтрации:- Filter.ACCEPT - сообщение можно писать в лог (следующие в цепочке фильры, не вызываются)
- Filter.NEUTRAL - сообщение следует передать дальше по цепочке (если фильтр последний, то сообщение пишется в лог)
- Filter.DENY - сообщение не следует писать в лог (следующие в цепочке фильры, не вызываются)
Если надо написать свой фильтр, то надо унаследовать его от базового класса и переопределить метод public int decide(LoggingEvent).
В состав библиотеки Log4j уже входит несколько стандартных фильтров, в частности есть фильты для фильтрации сообщений по уровню:- LevelMatchFilter - пишутся только сообщения указанного уровня
- LevelRangeFilter - пишутся только сообщения с уровнем попадающим в указанный диапазон
Рассмотрим на как организовать вывод в консоль только отладочных (DEBUG) сообщений:
Код | LevelMatchFilter matchFilter = new LevelMatchFilter(); matchFilter.setLevelToMatch("DEBUG"); ConsoleAppender errAppender = new ConsoleAppender(new PatternLayout("%d{dd-MM-yyyy HH:mm:ss.SSS} | %-5p | %m%n"), "System.err"); errAppender.addFilter(matchFilter); |
Еще один пример как организовать вывод отладочной информации в отдельный файл, с помощью конфигурационного файла:
Код | <?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
<log4j:configuration>
<appender name="Console" class="org.apache.log4j.ConsoleAppender"> <param name="Target" value="System.out"/> <layout class="org.apache.log4j.PatternLayout"> <param name="ConversionPattern" value="%-5p: %m%n"/> </layout> </appender>
<appender name="File" class="org.apache.log4j.FileAppender"> <param name="File" value="main.log"/> <param name="Append" value="false"/> <param name="BufferedIO" value="false"/> <layout class="org.apache.log4j.PatternLayout"> <param name="ConversionPattern" value="%d [%-5p] %m {at %c}%n"/> </layout> <filter class="org.apache.log4j.varia.LevelRangeFilter"> <param name="LevelMax" value="OFF"/> <param name="LevelMin" value="INFO"/> </filter> </appender>
<appender name="DebugFile" class="org.apache.log4j.FileAppender"> <param name="File" value="debug.log"/> <param name="Append" value="false"/> <param name="BufferedIO" value="false"/> <layout class="org.apache.log4j.PatternLayout"> <param name="ConversionPattern" value="%d [%-5p] %m {at %c}%n"/> </layout> <filter class="org.apache.log4j.varia.LevelRangeFilter"> <param name="LevelMax" value="DEBUG"/> <param name="LevelMin" value="ALL"/> </filter> </appender>
<root> <priority value ="ALL"/> <appender-ref ref="Console"/> <appender-ref ref="File"/> <appender-ref ref="DebugFile"/> </root>
</log4j:configuration> |
Создадим свой Filter, который будет фильтровать сообщения на основе регулярных выражений:
Код | public class RegexFilter extends Filter { private Pattern pattern;
public RegexFilter() { }
public String getPattern() { return pattern == null ? null : pattern.pattern(); }
public void setPattern(String pattern) { try { this.pattern = Pattern.compile(pattern); } catch(PatternSyntaxException ex) { this.pattern = null; throw ex; } }
public int decide(LoggingEvent event) { if(pattern == null) return Filter.NEUTRAL;
if(pattern.matcher(event.getMessage().toString()).matches()) return Filter.ACCEPT; else return Filter.DENY; } }
|
|