Введение
logbackЭто самый популярный на данный момент инструмент для записи логов, обладающий высокой производительностью, полным функционалом и полной документацией.log4jРазработчик серии,
Эта статья изlogbackВводятся часто используемые компоненты и функциональные точки, а также приводится простой справочный пример.logbackОфициальный сайт
javaкак пользоватьсяlogback
существует
pom.xmlВнедрить два ключевых пакета в
<!-- https://mvnrepository.com/artifact/ch.qos.logback/logback-core -->
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-core</artifactId>
<version>1.2.3</version>
</dependency>
<!-- https://mvnrepository.com/artifact/ch.qos.logback/logback-classic -->
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.2.3</version>
<scope>test</scope>
</dependency>
Затем создайте logback.xml в каталоге ресурсов, см.Полный набор доступных профилейэта глава
уровень журнала
Рекомендуются следующие, ранжированные от высокого к низкому
| Level | описывать |
|---|---|
ERROR |
События ошибок могут по-прежнему позволять приложению продолжать работу. |
WARN |
Обозначьте потенциально опасные ситуации |
INFO |
Указывает сообщение, которое может выделять информацию о работе приложения на грубом уровне. |
DEBUG |
Указание детальных информационных событий наиболее полезно для отладки приложений. |
| *** | |
| ## Уровень добавления |
Appender class dependency
ConsoleAppender(вывод журнала в консоль)
вывести информацию журнала на консоль
| настроить | тип | описывать |
|---|---|---|
encoder |
Encoder | формат вывода журнала |
target |
String | Место назначения вывода журнала, которое может быть System.out или System.err, по умолчанию — System.out. |
withJansi |
boolean | Значение по умолчанию - false, которое нельзя использовать.Похоже, что вывод ANSI будет иметь цвет после его включения.Подробности см. во введении на официальном сайте. |
sample:
<configuration>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<!-- encoders are assigned the type
ch.qos.logback.classic.encoder.PatternLayoutEncoder by default -->
<encoder>
<pattern>%-4relative [%thread] %-5level %logger{35} - %msg %n</pattern>
</encoder>
</appender>
<root level="DEBUG">
<appender-ref ref="STDOUT" />
</root>
</configuration>
FileAppender(вывод журнала в файл)
FileAppender OutputStreamAppenderПодкласс , который выводит журнал в указанный файл. Если файл уже существует, добавьте или заново создайте файл в конце в соответствии со свойством конфигурации.
| настроить | тип | описывать |
|---|---|---|
append |
boolean | По умолчанию true, журнал будет добавлен в конец существующего файла. |
encoder |
Encoder | формат вывода журнала |
file |
String | Имя файла, может иметь путь, если файл или каталог не существует, он будет создан, например:logs/info.log, это свойство не имеет значения по умолчанию |
immediateFlush |
boolean | Как только журнал сгенерирован, он будет немедленно сброшен в файл, и для повышения производительности для него следует установить значение false, поскольку буфер будет сбрасываться часто; |
sample:
<configuration>
<!-- 使用时间戳作为文件名 -->
<timestamp key="bySecond" datePattern="yyyyMMdd'T'HHmmss"/>
<appender name="FILE" class="ch.qos.logback.core.FileAppender">
<file>testFile-${bySecond}.log</file>
<append>true</append>
<!-- set immediateFlush to false for much higher logging throughput -->
<immediateFlush>true</immediateFlush>
<!-- encoders are assigned the type
ch.qos.logback.classic.encoder.PatternLayoutEncoder by default -->
<encoder>
<pattern>%-4relative [%thread] %-5level %logger{35} - %msg%n</pattern>
</encoder>
</appender>
<root level="DEBUG">
<appender-ref ref="FILE" />
</root>
</configuration>
RollingFileAppender(прокатный выход)
RollingFileAppenderУнаследованный от FileAppender, он генерирует скользящие файлы в соответствии с некоторыми специфическими политиками. Например, когда он работает в паре с политикой TimeBasedRollingPolicy, когда файл достигает указанного времени, новый файл будет создан заново. Политика будет подробно описана в следующие главы.
| настроить | тип | описывать |
|---|---|---|
append |
boolean | См. конфигурацию FileAppender |
encoder |
Encoder | См. конфигурацию FileAppender |
file |
String | См. конфигурацию FileAppender |
rollingPolicy |
RollingPolicy | Политика обновления журнала: при настройке этого параметра файл журнала будет обновляться в соответствии с указанной политикой. |
triggeringPolicy |
TriggeringPolicy | Политика прокрутки триггера: обычно используется с RollingPolicy для установки условий запуска прокрутки. |
sample:
<appender name="errorAppender" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>logs/error.log</file>
<!-- 设置滚动策略 TimeBasedRollingPolicy 按日期滚动 -->
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!--设置日志命名模式-->
<fileNamePattern>errorFile.%d{yyyy-MM-dd}.log</fileNamePattern>
<!--最多保留30天log-->
<maxHistory>30</maxHistory>
</rollingPolicy>
<!-- 超过150MB时,立即触发滚动策略,生成新的文件 -->
<triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
<maxFileSize>150</maxFileSize>
</triggeringPolicy>
<encoder>
<pattern>%d [%p] %-5level %logger - %msg%newline</pattern>
</encoder>
</appender>
Политика файла журнала *Политика (обычно используется)
TimeBasedRollingPolicy(скользящая стратегия по дате)
TimeBasedRollingPolicyЭто может быть самая популярная стратегия логбэка. Прокрутка на основе времени может составлять один день или один месяц. Это чаще используется. Обычно мы можем установить день для создания нового файла, который легко суммировать и подсчитывать.
| настроить | тип | описывать |
|---|---|---|
fileNamePattern |
String | Правила именования файлов журнала обычно используют %d для вывода по дням или месяцам, например, errorFile.%d{гггг-ММ-дд}.log, сгенерированный файл похож на errorFile.2018-10-09.log, с дата, файлы, создаваемые каждый день, не будут иметь повторяющихся имен. Это также поддерживает выбор часового пояса, например %d{yyyy-MM-dd,UTC} |
maxHistory |
int | Количество дней для хранения журнала. Исторические файлы журнала, которые превышают это количество дней, будут удалены асинхронно путем возврата журнала. |
totalSizeCap |
int | Общий размер заархивированных файлов и политика maxHistory применяются в первую очередь. |
cleanHistoryOnStart |
boolean | Значение по умолчанию — false, что запускает действие по немедленному удалению файла архива. |
Прокрутка вывода поддерживает автоматическое сжатиеИмя файла начинается с
.gzили.zipконец, например:/wombat/foo.%d.gz
sample:
<configuration>
<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>logFile.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- daily rollover -->
<fileNamePattern>logFile.%d{yyyy-MM-dd}.log</fileNamePattern>
<!-- keep 30 days' worth of history capped at 3GB total size -->
<maxHistory>30</maxHistory>
<totalSizeCap>3GB</totalSizeCap>
</rollingPolicy>
<encoder>
<pattern>%-4relative [%thread] %-5level %logger{35} - %msg%n</pattern>
</encoder>
</appender>
<root level="DEBUG">
<appender-ref ref="FILE" />
</root>
</configuration>
SizeAndTimeBasedRollingPolicy(Скользящая стратегия по размеру и времени)
Это должно быть наиболее часто используемым, прокручивая журнал в соответствии с политикой указания времени и размера файла. Без дальнейших церемоний, посмотрите на следующий пример
<configuration>
<appender name="ROLLING" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>mylog.txt</file>
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<!-- rollover daily -->
<fileNamePattern>mylog-%d{yyyy-MM-dd}.%i.txt</fileNamePattern>
<!-- each file should be at most 100MB, keep 60 days worth of history, but at most 20GB -->
<maxFileSize>100MB</maxFileSize>
<maxHistory>60</maxHistory>
<totalSizeCap>20GB</totalSizeCap>
</rollingPolicy>
<encoder>
<pattern>%msg%n</pattern>
</encoder>
</appender>
<root level="DEBUG">
<appender-ref ref="ROLLING" />
</root>
</configuration>
Обратите внимание, что кроме
“%d”за пределами“%i”Тег конверсии.%iи%dТокены обязательны. Всякий раз, когда текущий файл журнала достигает maxFileSize до конца текущего периода, он будет архивироваться с возрастающим индексом, начиная с 0.
FixedWindowRollingPolicy(Создание скользящих файлов с фиксированной стратегией алгоритма обычно не используется)
Эта стратегия обычно не используется, поэтому давайте не будем использовать больше bbs. Атрибуты такие же, как и у других стратегий прокрутки. Обычно соглашение об именах файлов выглядит следующим образом:
tests.%i.log, файл будет сгенерирован, когда будет достигнуто условие для запуска прокруткиtest1.log,test2.log,test3.log...
SizeBasedTriggeringPolicy(стратегия, запускающая прокрутку в зависимости от размера)
Конфигурация в этом теге используется для запуска времени прокрутки, например, когда размер файла достигает указанного значения, запускается прокрутка.
sample:
<configuration>
<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>test.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy">
<fileNamePattern>test.%i.log.zip</fileNamePattern>
<minIndex>1</minIndex>
<maxIndex>3</maxIndex>
</rollingPolicy>
<triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
<maxFileSize>5MB</maxFileSize>
</triggeringPolicy>
<encoder>
<pattern>%-4relative [%thread] %-5level %logger{35} - %msg%n</pattern>
</encoder>
</appender>
<root level="DEBUG">
<appender-ref ref="FILE" />
</root>
</configuration>
fileNamePattenнекоторые правила для (например, прокатка по годам, месяцам, дням, дням, часам, минутам, секундам)
| пример | описывать |
|---|---|
/wombat/foo.%d |
Ролл по дням, формат год-месяц-день, все создается в одной папке |
/wombat/%d{yyyy/MM}/foo.txt |
Прокручивайте по месяцам, создавайте одинаковый файл каждый месяц в другой папке месяца, например, сначала: /wombat/2018/09/foo.txt, затем: /wombat/2018/10/foo.txt |
/wombat/foo.%d{yyyy-ww}.log |
Генерировать раз в неделю, регенерируя с первого дня недели |
/wombat/foo%d{yyyy-MM-dd_HH}.log |
Генерируется каждый час |
/wombat/foo%d{yyyy-MM-dd_HH-mm}.log |
Генерируется каждую минуту |
/wombat/foo%d{yyyy-MM-dd_HH-mm, UTC}.log |
Генерируется каждую минуту в указанном часовом поясе |
/foo/%d{yyyy-MM,aux}/%d.log |
Генерируется один раз в день с разбивкой по годам и месяцам, например, в /foo/2018-09/ есть журнал за месяц, а имя журнала — это дата каждого дня |
patternКонфигурация (форматирование вывода журнала)
пример
Некоторые общие правила конфигурации описаны ниже.
<encoder>
<pattern>%-4relative [%thread] %-5level %logger{35} - %msg%n</pattern>
</encoder>
-
%-4relative: время выходной записи журнала выравнивается по левому краю, а ширина равна 4. -
%thread: номер потока, в котором будет выводиться журнал. -
%-5level: Вывод 5 уровней журнала, выровненных по левому краю. -
%logger{35}: записи журнала выводаloggerИмя обычно является именем класса и имеет длину 35. -
%msg%n: Печать информации, предоставленной приложением, с переносом строки.
Уведомление: при использовании должны быть включены все ключевые слова.%, как указано выше,-Как его логотип
patternлист
| ключевые слова | описывать | ||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|
| c{length} lo{length} |
Категория, к которой принадлежит выходной логгер, обычно полное имя класса, к которому он принадлежит.Параметром является зарезервированная длина имени логгера, а полное имя по умолчанию не заполняется.
|
||||||||||
| C{length} class{length} |
Аналогично приведенному выше использованию, выводится полное имя вызывающего абонента, что имеет низкую производительность и не рекомендуется настраивать. | ||||||||||
| contextName cn| |
имя выходного контекста | ||||||||||
| d{pattern} date{pattern} |
Время печати выходного журнала, похожее на формат даты в java.
|
||||||||||
| caller{depth} | Вывод информации о глубине стека вызовов вызывающего абонента, чем больше значение, тем больше информации о стеке выводится.
|
||||||||||
| L line |
Выведите, где произошло событие журнала, включая название категории, поток, в котором оно произошло, и количество строк в коде. Если вопросы производительности не рассматриваются, вы можете использовать | ||||||||||
| m msg message |
Информация, предоставленная приложением | ||||||||||
| M method |
Производительность имени метода для вывода журнала выполнения низкая. Если проблемы с производительностью не учитываются, вы можете использовать | ||||||||||
| n | Вывод возврата каретки и перевода строки, "/r/n" для платформ Windows и "/n" для платформ Unix. | ||||||||||
| p le level |
Уровень выходного журнала, т. е. DEBUG, INFO, WARN, ERROR, FATAL | ||||||||||
| t thread |
Имя потока для вывода журнала печати | ||||||||||
| replace(msg){r,t} | msg — это содержимое журнала, а r — регулярное выражение.Замените содержимое r в msg на t. Например: %replace(%msg){'\s',""} |
||||||||||
| r relative |
Количество миллисекунд, которое потребовалось для вывода информации журнала с момента запуска приложения. |
Конфигурация:
<configuration>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<!-- 日期 [线程] [class类]-[日志级别] log内容 回车符号 -->
<pattern>%d{yyyy-MM-dd HH:mm:ss,SSS} [%t] [%c]-[%p] %m%n</pattern>
</encoder>
</appender>
<!-- 输出INFO及以上的日志 -->
<root level="INFO">
<!-- 让自定义的appender生效 -->
<appender-ref ref="STDOUT"/>
</root>
</configuration>
Вывод консоли:
2018-10-09 14:27:55 [main] [org.springframework.web.servlet.handler.SimpleUrlHandlerMapping]-[INFO] Mapped URL path [/**] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
2018-10-09 14:27:55 [main] [org.springframework.jmx.export.annotation.AnnotationMBeanExporter]-[INFO] Registering beans for JMX exposure on startup
2018-10-09 14:27:55 [main] [org.apache.coyote.http11.Http11NioProtocol]-[INFO] Starting ProtocolHandler ["http-nio-6677"]
2018-10-09 14:27:55 [main] [org.apache.tomcat.util.net.NioSelectorPool]-[INFO] Using a shared selector for servlet write/read
2018-10-09 14:27:55 [main] [org.springframework.boot.web.embedded.tomcat.TomcatWebServer]-[INFO] Tomcat started on port(s): 6677 (http) with context path ''
2018-10-09 14:27:55 [main] [com.xj.plugins.Springboot2AnalyzeApplication]-[INFO] Started Springboot2AnalyzeApplication in 2.014 seconds (JVM running for 3.949)
Цвет конфигурации журнала вывода консоли
| Формат | описывать |
|---|---|
| %black | чернить |
| %red | красный |
| %green | зеленый |
| %yellow | желтый |
| %blue | синий |
| %magenta | пурпурный |
| %cyan | синий |
| %white | белый |
| %gray | серый |
| %highlight | Цвет выделения |
| %bold | Более яркие цвета, усиливающие все вышеперечисленные цвета, такие как %boldRed, %boldBlack |
пример:
<configuration>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<!-- 日期 [线程] [class类]-[日志级别] log内容 回车符号 -->
<pattern>%blue(%d{yyyy-MM-dd HH:mm:ss,SSS}) [%cyan(%t)] [%yellow(%c)]-[%highlight(%p)] %m%n</pattern>
</encoder>
</appender>
<!-- 输出INFO及以上的日志 -->
<root level="INFO">
<!-- 让自定义的appender生效 -->
<appender-ref ref="STDOUT"/>
</root>
</configuration>
Вывод в консоль после настройки
лог-направленный вывод
В logback.xml, как вывести определенный журнал в файл, можно использовать фильтр, аналогичный следующему примеру.
фильтр конфигурации xml, например вывод журнала ошибок в error.log
<appender name="ERROR" class="ch.qos.logback.core.rolling.RollingFileAppender">
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%t] [%c]-[%p] %m%n</pattern>
</encoder>
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<!-- rollover daily -->
<fileNamePattern>${LOG_HOME}/error-%d{yyyy-MM-dd}.%i.txt</fileNamePattern>
<!-- 文件最大30MB,保留60天,总大小20GB -->
<maxFileSize>30MB</maxFileSize>
<maxHistory>60</maxHistory>
<totalSizeCap>20GB</totalSizeCap>
</rollingPolicy>
<!-- 过滤器,只写入error级别log -->
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>ERROR</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
</appender>
Метод Filter можно переписать, если есть необходимость в специальных логах, требующих направленного вывода
public class MyLogFilter extends Filter<ILoggingEvent> {
@Override
public FilterReply decide(ILoggingEvent event) {
if(event.getMessage() != null
&& (event.getMessage().startsWith("test")
|| event.getMessage().startsWith("demo"))) {
return FilterReply.ACCEPT;
} else {
return FilterReply.DENY;
}
}
}
Затем добавьте фильтр в приложение
<!-- 过滤器,写入test和demo开头的日志 -->
<filter class="xx.xxx.xxxx.MyLogFilter" />
Отключить вывод журнала на уровне класса
Добавьте следующую конфигурацию в logback.xml.
OFF означает, что все закрыто, вы можете настроить указанный уровень, например INFO, DEBUG...
<logger name="xx.xx.class" level="OFF" />
logback.xmlчитать переменные окружения
logback.xmlПоддержка двух методов чтения: чтение из системной среды, чтение из файла конфигурации spring.
Чтение переменных системной среды и получение их с помощью ${envName}
<!-- 从系统环境变量读取日志输出目录 -->
<property name="LOG_HOME" value="${log.dir}"/>
Как читать файлы конфигурации Spring
<!-- 从context中读取所以不需要使用${}获取 -->
<springProperty scope="context" name="LOG_HOME" source="logback.dir"/>
Настройки значения по умолчанию
Если вы не получите его в переменной окружения
LOG_HOMEзначение, сделаетlogsпо умолчанию иShellСинтаксис установки значений по умолчанию аналогичен
<file>${LOG_HOME:-logs}/test/test-info.log</file>
-
Полный набор доступных профилей
Следующая конфигурация будет генерировать три файла журнала. Конкретная стратегия такова: новый файл будет создаваться каждый день. Когда файл журнала достигает указанного размера в день, он будет автоматически сжат, и будет создан новый файл для записи.
-
main.log(только записьinfoвыход журнала уровня и выше) -
warn.log(только записьwarnуровень вывода журнала) -
error.log(только записьerrorуровень вывода журнала)
<?xml version="1.0" encoding="UTF-8"?>
<configuration debug="false">
<!-- 从spring中获取配置,如获取不到会使用默认值 -->
<springProperty scope="context" name="LOG_HOME" source="logging.path"/>
<springProperty scope="context" name="LOG_LEVEL" source="logging.output.level"/>
<springProperty scope="context" name="LOG_MAX_SIZE" source="logging.file.max-size"/>
<springProperty scope="context" name="LOG_TOTAL_SIZE_CAP" source="logging.file.total-size-cap"/>
<springProperty scope="context" name="LOG_MAX_HISTORY" source="logging.file.max-history"/>
<!-- 输出样式 -->
<property name="pattern" value="%d{yyyy-MM-dd HH:mm:ss.SSS} [%t] [%logger{10}]-[%p] %m%n"/>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<pattern>%blue(%d{yyyy-MM-dd HH:mm:ss.SSS}) [%cyan(%t)] [%yellow(%logger{10})]-[%highlight(%p)] %m%n</pattern>
</encoder>
</appender>
<appender name="Main-Log" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${LOG_HOME:-logs}/logback/main.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<FileNamePattern>${LOG_HOME:-logs}/logback/main-%d{yyyy-MM-dd}_%i.log.zip</FileNamePattern>
<MaxHistory>${LOG_MAX_HISTORY:-30}</MaxHistory>
<MaxFileSize>${LOG_MAX_SIZE:-10MB}</MaxFileSize>
<totalSizeCap>${LOG_TOTAL_SIZE_CAP:-10GB}</totalSizeCap>
</rollingPolicy>
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<pattern>${pattern}</pattern>
</encoder>
</appender>
<appender name="Error-Log" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${LOG_HOME:-logs}/logback/error.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<FileNamePattern>${LOG_HOME:-logs}/logback/error-%d{yyyy-MM-dd}_%i.log.zip</FileNamePattern>
<MaxHistory>${LOG_MAX_HISTORY:-30}</MaxHistory>
<MaxFileSize>${LOG_MAX_SIZE:-10MB}</MaxFileSize>
<totalSizeCap>${LOG_TOTAL_SIZE_CAP:-10GB}</totalSizeCap>
</rollingPolicy>
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<pattern>${pattern}</pattern>
</encoder>
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>ERROR</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
</appender>
<appender name="Warn-Log" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${LOG_HOME:-logs}/logback/warn.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<FileNamePattern>${LOG_HOME:-logs}/logback/warn-%d{yyyy-MM-dd}_%i.log.zip</FileNamePattern>
<MaxHistory>${LOG_MAX_HISTORY:-30}</MaxHistory>
<MaxFileSize>${LOG_MAX_SIZE:-10MB}</MaxFileSize>
<totalSizeCap>${LOG_TOTAL_SIZE_CAP:-10GB}</totalSizeCap>
</rollingPolicy>
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<pattern>${pattern}</pattern>
</encoder>
<!-- log filter -->
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>WARN</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
</appender>
<!-- 关闭类中某个级别的输出 OFF全部关闭 , INFO,DEBUG ...
<logger name="x.x.Constants">
<level value="OFF"/>
</logger>
-->
<!-- log output level -->
<root level="${LOG_LEVEL:-INFO}">
<appender-ref ref="STDOUT"/>
<appender-ref ref="Main-Log"/>
<appender-ref ref="Warn-Log"/>
<appender-ref ref="Error-Log"/>
</root>
</configuration>