Подробно объясните библиотеку основных средств ведения журналов Java.

Java

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

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

Давайте рассмотрим основные инструменты ведения журналов один за другим.

:notebook: Эта статья была заархивирована в: "blog"

структура регистрации

java.util.logging (JUL)

Начиная с JDK1.4, черезjava.util.loggingОбеспечить функцию журнала.

Он может удовлетворить основные потребности в ведении журналов, но он не такой мощный, как Log4j, и область его использования не такая обширная, как у Log4j.

Log4j

Log4j — это проект с открытым исходным кодом Apache, основатель Ceki Gulcu.

Следует сказать, что Log4j является старейшим и наиболее широко используемым инструментом ведения журналов в области Java. Он широко приветствуется в отрасли с момента его рождения.

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

В Log4j есть три основных компонента:

  • loggers- Отвечает за сбор информации о регистрации.
  • appenders- Отвечает за публикацию информации журнала в различные предпочтительные места назначения.
  • layouts- Отвечает за форматирование сообщений журнала в различных стилях.

Адрес официального сайта

Logback

Logback — еще один компонент ведения журнала с открытым исходным кодом, разработанный основателем log4j Чеки Гулку с целью заменить log4j.

logback в настоящее время разделен на три модуля:logback-core,logback-classicиlogback-access.

  • logback-core- является базовым модулем для двух других модулей.
  • logback-classic- это улучшенная версия log4j. такжеlogback-classicПолная реализация SLF4J API позволяет легко переключаться на другие системы ведения журналов, такие как log4j или JDK14 Logging.
  • logback-access- Модуль доступа интегрируется с контейнером сервлетов для предоставления функции доступа к журналу через Http.

Адрес официального сайта

Log4j2

Адрес официального сайта

Согласно официальному заявлению, Log4j2 является заменой Log4j и Logback.

Архитектура Log4j2:



Log4j vs Logback vs Log4j2

Согласно официальному заявлению,Log4j2 значительно превосходит Log4j и Logback.

Итак, какие преимущества у Log4j2 по сравнению с Log4j и Logback, которые вышли первыми?

  1. Log4j2 предназначен для использования в качестве среды ведения журнала аудита. И Log4j 1.x, и Logback теряют события при реконфигурации. Log4j 2 не будет. В Logback исключения в Appender никогда не видны приложению. В Log4j Appenders можно настроить так, чтобы исключения проникали в приложение.
  2. Log4j2 В многопоточном сценарииАсинхронные регистраторыВ 10 раз выше, чем определенный Logback Log4j 1.x и высокая, низкая задержка на несколько порядков.
  3. Log4j2 не содержит мусора для автономных приложений и с низким уровнем мусора для веб-приложений во время ведения журнала в стабильном состоянии. Это снижает нагрузку на сборщик мусора и может обеспечить лучшее время отклика.
  4. Log4j2 использует систему плагинов, которая позволяет очень легко расширять структуру без внесения каких-либо изменений в Log4j, добавляя новые Appenders, Filters, Layouts, Lookups и Pattern Converters.
  5. За счет плагина конфигурация системы упрощается. Записи в конфигурации не должны указывать имя класса.
  6. служба поддержкипользовательский уровень журнала.
  7. служба поддержкилямбда-выражение.
  8. служба поддержкиобъект сообщения.
  9. Макет Log4j и Logback возвращает строки, а Log4j2 возвращает двоичные массивы, что делает его пригодным для использования различными приложениями.
  10. Syslog Appender поддерживает TCP и UDP и поддерживает системный журнал BSD.
  11. Log4j2 использует функцию параллелизма Java5 для использования блокировков как можно маленькую, чтобы уменьшить накладные расходы блокировки.

бревенчатый фасад

Что такое бревенчатый фасад?

Фасад журнала — это инкапсуляция API, предоставляемая различными платформами журналов. Он может получить доступ к схеме реализации журнала без изменения какой-либо конфигурации во время развертывания.

common-logging

common-loging — это проект Apache с открытым исходным кодом. также называемыйJakarta Commons Logging, сокращенно JCL.

Функция common-logger состоит в том, чтобы предоставить API-интерфейс функции журнала, и она не обеспечивает конкретную реализацию самого журнала (конечно, внутри common-logging есть простая реализация Simple logger, но функция очень слабый, и прямо игнорируется), но вВремя выполненияДинамически связывайте компоненты реализации журнала для работы (например, log4j, java.util.loggin).

Адрес официального сайта

slf4j

Полное название — Simple Logging Facade for Java, который представляет собой простой фасад ведения журналов java.

Что, автор снова Чеки Гулджу! Этот великий бог написал Log4j, Logback и slf4j, и уже пятьсот лет занимается разработкой лог-компонентов, и всегда мог превзойти самого себя.

Подобно Common-Logging, slf4j представляет собой инкапсуляцию API, предоставляемую различными платформами ведения журналов.Он может получить доступ к схеме реализации ведения журнала без изменения какой-либо конфигурации во время развертывания. Однако slf4j ввремя компиляцииСтатически привязать реальную библиотеку журналов. При использовании SLF4J, если вам нужно использовать определенную реализацию ведения журнала, вы должны выбрать правильный набор jar-пакетов SLF4J (различные пакеты мостов).

Адрес официального сайта



common-logging vs slf4j

Библиотека slf4j похожа на Apache Common-Logging. Однако он статически привязывает настоящую библиотеку протоколирования во время компиляции. Это кажется очень хлопотным, но на самом деле это просто импорт пакета jar bridging.

Одним из основных преимуществ slf4j является то, что он обеспечивает более удобный способ ведения журнала:

Не нужно использоватьlogger.isDebugEnabled()Чтобы решить проблемы с производительностью журнала, вызванные сплайсингом символов. Способ slf4j заключается в использовании{}Как заменитель строки в виде:

logger.debug("id: {}, name: {} ", id, name);

Суммировать

Таким образом, использование slf4j + Logback в настоящее время является наиболее идеальным решением для ведения журнала.

Далее, как это реализовать в проекте.

Реализовать решение для ведения журнала

Использование решения журнала можно разделить на три этапа:

  1. импортный пакет jar
  2. настроить
  3. Используйте API

Шаги 2 и 3 общих решений для ведения журналов в основном одинаковы, а разница в реализации в основном заключается в шаге 1, который заключается в использовании разных библиотек.

импортный пакет jar

Комбинация slf4j + logback здесь предпочтительнее.

Если вы привыкли к обычному логированию, вы можете выбрать common-logging+log4j.

Настоятельно не рекомендуется использовать компоненты реализации лога (logback, log4j, java.util.logging) напрямую по причинам, упомянутым ранее, то есть библиотеку лога нельзя гибко заменить.

Бывает и другая ситуация: ваш старый проект использует common-loging, либо напрямую использует логирование для реализации компонентов. Если старый код изменен, рабочая нагрузка слишком велика и требуется обработка совместимости. Ниже вы увидите различные способы борьбы.

Примечание. Насколько мне известно, в настоящее время нет способа связать slf4j с общим протоколированием. Если я не в курсе, пожалуйста, дайте мне знать.

slf4j напрямую связывает компонент журнала

slf4j + logback

Просто добавьте зависимости в pom.xml.

logback-classic-1.0.13.jarбудет автоматическиslf4j-api-1.7.21.jarиlogback-core-1.0.13.jarТакже добавьте в свой проект.

<dependency>
  <groupId>ch.qos.logback</groupId>
  <artifactId>logback-classic</artifactId>
  <version>1.0.13</version>
</dependency>

slf4j + log4j

Просто добавьте зависимости в pom.xml.

slf4j-log4j12-1.7.21.jarбудет автоматическиslf4j-api-1.7.21.jarиlog4j-1.2.17.jarТакже добавьте в свой проект.

<dependency>
  <groupId>org.slf4j</groupId>
  <artifactId>slf4j-log4j12</artifactId>
  <version>1.7.21</version>
</dependency>

slf4j + java.util.logging

Просто добавьте зависимости в pom.xml.

slf4j-jdk14-1.7.21.jarбудет автоматическиslf4j-api-1.7.21.jarТакже добавьте в свой проект.

<dependency>
  <groupId>org.slf4j</groupId>
  <artifactId>slf4j-jdk14</artifactId>
  <version>1.7.21</version>
</dependency>

Совместимые с slf4j компоненты ведения журнала, отличные от slf4j

Прежде чем представить решение, сначала упомяните понятие - соединение

Что такое мост

Если в компонентах, вызываемых разрабатываемым вами приложением, используется common-loging, то вам потребуется jcl-over-slf4j.jar, чтобы перенаправить вывод информации журнала в slf4j-api, а затем slf4j-api вызовет фактические зависимости slf4j. компонент журнала. Этот процесс называется мостовидным. На следующем рисунке показана официальная диаграмма стратегии моста slf4j:



Из рисунка видно, что независимо от того, используете ли вы common-loging в своем старом проекте или напрямую используете log4j или java.util.logging, вы можете использовать соответствующий jar-пакет моста для решения проблем совместимости.

slf4j совместим с общим протоколированием

<dependency>
  <groupId>org.slf4j</groupId>
  <artifactId>jcl-over-slf4j</artifactId>
  <version>1.7.12</version>
</dependency>

slf4j совместим с log4j

<dependency>
    <groupId>org.slf4j</groupId>
    <artifactId>log4j-over-slf4j</artifactId>
    <version>1.7.12</version>
</dependency>

slf4j совместим с java.util.logging

<dependency>
    <groupId>org.slf4j</groupId>
    <artifactId>jul-to-slf4j</artifactId>
    <version>1.7.12</version>
</dependency>

пружинная интеграция slf4j

Выполнение веб-разработки на Java в основном неотделимо от среды Spring. К сожалению, решение для ведения журнала, используемое spring, — это common-logging + log4j.

Итак, вам понадобится перемычка:logback-ext-spring.

<dependency>
  <groupId>ch.qos.logback</groupId>
  <artifactId>logback-classic</artifactId>
  <version>1.1.3</version>
</dependency>
<dependency>
  <groupId>org.logback-extensions</groupId>
  <artifactId>logback-ext-spring</artifactId>
  <version>0.1.2</version>
</dependency>
<dependency>
  <groupId>org.slf4j</groupId>
  <artifactId>jcl-over-slf4j</artifactId>
  <version>1.7.12</version>
</dependency>

компонент журнала привязки common-loging

common-logging + log4j

Просто добавьте зависимости в pom.xml.

<dependency>
  <groupId>commons-logging</groupId>
  <artifactId>commons-logging</artifactId>
  <version>1.2</version>
</dependency>
<dependency>
  <groupId>log4j</groupId>
  <artifactId>log4j</artifactId>
  <version>1.2.17</version>
</dependency>

Используйте API

использование slf4j

Использовать API slf4j просто. использоватьLoggerFactoryинициализироватьLoggerinstance, а затем вызовите соответствующую функцию уровня печати Logger.

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class App {
    private static final Logger log = LoggerFactory.getLogger(App.class);
    public static void main(String[] args) {
        String msg = "print log, current level: {}";
        log.trace(msg, "trace");
        log.debug(msg, "debug");
        log.info(msg, "info");
        log.warn(msg, "warn");
        log.error(msg, "error");
    }
}

использование общего журнала

Использование общего журнала почти такое же, как slf4j, но поддерживаемый уровень печати имеет более высокий уровень:fatal.

Кроме того, common-loging не поддерживает{}Чтобы заменить параметры, вы можете выбрать только конкатенацию строк.

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

public class JclTest {
    private static final Log log = LogFactory.getLog(JclTest.class);

    public static void main(String[] args) {
        String msg = "print log, current level: ";
        log.trace(msg + "trace");
        log.debug(msg + "debug");
        log.info(msg + "info");
        log.warn(msg + "warn");
        log.error(msg + "error");
        log.fatal(msg + "fatal");
    }
}

конфигурация log4j2

Базовая конфигурация log4j2 выглядит следующим образом:

<?xml version="1.0" encoding="UTF-8"?>;
<Configuration>
  <Properties>
    <Property name="name1">value</property>
    <Property name="name2" value="value2"/>
  </Properties>
  <Filter type="type" ... />
  <Appenders>
    <Appender type="type" name="name">
      <Filter type="type" ... />
    </Appender>
    ...
  </Appenders>
  <Loggers>
    <Logger name="name1">
      <Filter type="type" ... />
    </Logger>
    ...
    <Root level="level">
      <AppenderRef ref="name"/>
    </Root>
  </Loggers>
</Configuration>

Пример конфигурации:

<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="debug" strict="true" name="XMLConfigTest"
               packages="org.apache.logging.log4j.test">
  <Properties>
    <Property name="filename">target/test.log</Property>
  </Properties>
  <Filter type="ThresholdFilter" level="trace"/>

  <Appenders>
    <Appender type="Console" name="STDOUT">
      <Layout type="PatternLayout" pattern="%m MDC%X%n"/>
      <Filters>
        <Filter type="MarkerFilter" marker="FLOW" onMatch="DENY" onMismatch="NEUTRAL"/>
        <Filter type="MarkerFilter" marker="EXCEPTION" onMatch="DENY" onMismatch="ACCEPT"/>
      </Filters>
    </Appender>
    <Appender type="Console" name="FLOW">
      <Layout type="PatternLayout" pattern="%C{1}.%M %m %ex%n"/><!-- class and line number -->
      <Filters>
        <Filter type="MarkerFilter" marker="FLOW" onMatch="ACCEPT" onMismatch="NEUTRAL"/>
        <Filter type="MarkerFilter" marker="EXCEPTION" onMatch="ACCEPT" onMismatch="DENY"/>
      </Filters>
    </Appender>
    <Appender type="File" name="File" fileName="${filename}">
      <Layout type="PatternLayout">
        <Pattern>%d %p %C{1.} [%t] %m%n</Pattern>
      </Layout>
    </Appender>
  </Appenders>

  <Loggers>
    <Logger name="org.apache.logging.log4j.test1" level="debug" additivity="false">
      <Filter type="ThreadContextMapFilter">
        <KeyValuePair key="test" value="123"/>
      </Filter>
      <AppenderRef ref="STDOUT"/>
    </Logger>

    <Logger name="org.apache.logging.log4j.test2" level="debug" additivity="false">
      <AppenderRef ref="File"/>
    </Logger>

    <Root level="trace">
      <AppenderRef ref="STDOUT"/>
    </Root>
  </Loggers>

</Configuration>

конфигурация журнала

<configuration>

  • эффект:<configuration>является корневым элементом файла конфигурации журнала.
  • суть
    • она имеет<appender>,<logger>,<root>Три дочерних элемента.



<appender>

  • Роль: делегируйте задачу ведения журнала компоненту с именем appender.
  • суть
    • Можно настроить ноль или более.
    • она имеет<file>,<filter>,<layout>,<encoder>Четыре дочерних элемента.
  • Атрибуты
    • имя: Установите имя приложения.
    • class: Установите конкретный класс экземпляра.

<file>

  • Роль: Задайте путь к файлу журнала.

<filter>

  • Роль: установить фильтр.
  • суть
    • Можно настроить ноль или более.

<layout>

  • Роль: Установить приложение.
  • суть
    • Можно настроить ноль или единицу.
  • Атрибуты
    • class: Установите конкретный класс экземпляра.

<encoder>

  • Функция: Установить кодировку.
  • суть
    • Можно настроить ноль или более.
  • Атрибуты
    • class: Установите конкретный класс экземпляра.



<logger>

  • Функция: Установить регистратор.
  • суть
    • Можно настроить ноль или более.
  • Атрибуты
    • name
    • уровень: Установите уровень журнала. нечувствительный к регистру. Дополнительные значения: TRACE, DEBUG, INFO, WARN, ERROR, ALL, OFF.
    • аддитивность: необязательные значения: истина или ложь.

<appender-ref>

  • Роль: добавление ссылки.
  • суть
    • Можно настроить ноль или более.

<root>

  • Функция: Установить корневой регистратор.
  • суть
    • Можно настроить только один.
    • Никакие атрибуты не поддерживаются, кроме уровня. атрибут уровня и<logger>то же в .
    • имеет дочерний элемент<appender-ref><logger>то же в .

Полный справочный пример logback.xml

В файле конфигурации ниже я установил пять уровней для кода моего проекта (корневой каталог: org.zp.notes.spring):

TRACE, DEBUG, INFO, WARN, ERROR, приоритет от низкого к высокому.

Поскольку я обращаю внимание на некоторую информацию о самой структуре Spring, я добавил журнал, в котором специально печатаются сообщения Spring WARN и выше.

<?xml version="1.0" encoding="UTF-8" ?>

<!-- logback中一共有5种有效级别,分别是TRACE、DEBUG、INFO、WARN、ERROR,优先级依次从低到高 -->
<configuration scan="true" scanPeriod="60 seconds" debug="false">

  <property name="DIR_NAME" value="spring-helloworld"/>

  <!-- 将记录日志打印到控制台 -->
  <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
    <encoder>
      <pattern>%d{HH:mm:ss.SSS} [%thread] [%-5p] %c{36}.%M - %m%n</pattern>
    </encoder>
  </appender>

  <!-- RollingFileAppender begin -->
  <appender name="ALL" class="ch.qos.logback.core.rolling.RollingFileAppender">
    <!-- 根据时间来制定滚动策略 -->
    <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
      <fileNamePattern>${user.dir}/logs/${DIR_NAME}/all.%d{yyyy-MM-dd}.log</fileNamePattern>
      <maxHistory>30</maxHistory>
    </rollingPolicy>

    <!-- 根据文件大小来制定滚动策略 -->
    <triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
      <maxFileSize>30MB</maxFileSize>
    </triggeringPolicy>

    <encoder>
      <pattern>%d{HH:mm:ss.SSS} [%thread] [%-5p] %c{36}.%M - %m%n</pattern>
    </encoder>
  </appender>

  <appender name="ERROR" class="ch.qos.logback.core.rolling.RollingFileAppender">
    <!-- 根据时间来制定滚动策略 -->
    <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
      <fileNamePattern>${user.dir}/logs/${DIR_NAME}/error.%d{yyyy-MM-dd}.log</fileNamePattern>
      <maxHistory>30</maxHistory>
    </rollingPolicy>

    <!-- 根据文件大小来制定滚动策略 -->
    <triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
      <maxFileSize>10MB</maxFileSize>
    </triggeringPolicy>

    <filter class="ch.qos.logback.classic.filter.LevelFilter">
      <level>ERROR</level>
      <onMatch>ACCEPT</onMatch>
      <onMismatch>DENY</onMismatch>
    </filter>

    <encoder>
      <pattern>%d{HH:mm:ss.SSS} [%thread] [%-5p] %c{36}.%M - %m%n</pattern>
    </encoder>
  </appender>

  <appender name="WARN" class="ch.qos.logback.core.rolling.RollingFileAppender">
    <!-- 根据时间来制定滚动策略 -->
    <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
      <fileNamePattern>${user.dir}/logs/${DIR_NAME}/warn.%d{yyyy-MM-dd}.log</fileNamePattern>
      <maxHistory>30</maxHistory>
    </rollingPolicy>

    <!-- 根据文件大小来制定滚动策略 -->
    <triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
      <maxFileSize>10MB</maxFileSize>
    </triggeringPolicy>

    <filter class="ch.qos.logback.classic.filter.LevelFilter">
      <level>WARN</level>
      <onMatch>ACCEPT</onMatch>
      <onMismatch>DENY</onMismatch>
    </filter>

    <encoder>
      <pattern>%d{HH:mm:ss.SSS} [%thread] [%-5p] %c{36}.%M - %m%n</pattern>
    </encoder>
  </appender>

  <appender name="INFO" class="ch.qos.logback.core.rolling.RollingFileAppender">
    <!-- 根据时间来制定滚动策略 -->
    <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
      <fileNamePattern>${user.dir}/logs/${DIR_NAME}/info.%d{yyyy-MM-dd}.log</fileNamePattern>
      <maxHistory>30</maxHistory>
    </rollingPolicy>

    <!-- 根据文件大小来制定滚动策略 -->
    <triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
      <maxFileSize>10MB</maxFileSize>
    </triggeringPolicy>

    <filter class="ch.qos.logback.classic.filter.LevelFilter">
      <level>INFO</level>
      <onMatch>ACCEPT</onMatch>
      <onMismatch>DENY</onMismatch>
    </filter>

    <encoder>
      <pattern>%d{HH:mm:ss.SSS} [%thread] [%-5p] %c{36}.%M - %m%n</pattern>
    </encoder>
  </appender>

  <appender name="DEBUG" class="ch.qos.logback.core.rolling.RollingFileAppender">
    <!-- 根据时间来制定滚动策略 -->
    <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
      <fileNamePattern>${user.dir}/logs/${DIR_NAME}/debug.%d{yyyy-MM-dd}.log</fileNamePattern>
      <maxHistory>30</maxHistory>
    </rollingPolicy>

    <!-- 根据文件大小来制定滚动策略 -->
    <triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
      <maxFileSize>10MB</maxFileSize>
    </triggeringPolicy>

    <filter class="ch.qos.logback.classic.filter.LevelFilter">
      <level>DEBUG</level>
      <onMatch>ACCEPT</onMatch>
      <onMismatch>DENY</onMismatch>
    </filter>

    <encoder>
      <pattern>%d{HH:mm:ss.SSS} [%thread] [%-5p] %c{36}.%M - %m%n</pattern>
    </encoder>
  </appender>

  <appender name="TRACE" class="ch.qos.logback.core.rolling.RollingFileAppender">
    <!-- 根据时间来制定滚动策略 -->
    <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
      <fileNamePattern>${user.dir}/logs/${DIR_NAME}/trace.%d{yyyy-MM-dd}.log</fileNamePattern>
      <maxHistory>30</maxHistory>
    </rollingPolicy>

    <!-- 根据文件大小来制定滚动策略 -->
    <triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
      <maxFileSize>10MB</maxFileSize>
    </triggeringPolicy>

    <filter class="ch.qos.logback.classic.filter.LevelFilter">
      <level>TRACE</level>
      <onMatch>ACCEPT</onMatch>
      <onMismatch>DENY</onMismatch>
    </filter>

    <encoder>
      <pattern>%d{HH:mm:ss.SSS} [%thread] [%-5p] %c{36}.%M - %m%n</pattern>
    </encoder>
  </appender>

  <appender name="SPRING" class="ch.qos.logback.core.rolling.RollingFileAppender">
    <!-- 根据时间来制定滚动策略 -->
    <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
      <fileNamePattern>${user.dir}/logs/${DIR_NAME}/springframework.%d{yyyy-MM-dd}.log
      </fileNamePattern>
      <maxHistory>30</maxHistory>
    </rollingPolicy>

    <!-- 根据文件大小来制定滚动策略 -->
    <triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
      <maxFileSize>10MB</maxFileSize>
    </triggeringPolicy>

    <encoder>
      <pattern>%d{HH:mm:ss.SSS} [%thread] [%-5p] %c{36}.%M - %m%n</pattern>
    </encoder>
  </appender>
  <!-- RollingFileAppender end -->

  <!-- logger begin -->
  <!-- 本项目的日志记录,分级打印 -->
  <logger name="org.zp.notes.spring" level="TRACE" additivity="false">
    <appender-ref ref="STDOUT"/>
    <appender-ref ref="ERROR"/>
    <appender-ref ref="WARN"/>
    <appender-ref ref="INFO"/>
    <appender-ref ref="DEBUG"/>
    <appender-ref ref="TRACE"/>
  </logger>

  <!-- SPRING框架日志 -->
  <logger name="org.springframework" level="WARN" additivity="false">
    <appender-ref ref="SPRING"/>
  </logger>

  <root level="TRACE">
    <appender-ref ref="ALL"/>
  </root>
  <!-- logger end -->

</configuration>

конфигурация log4j

Полный справочный пример log4j.xml

Файл конфигурации log4j обычно имеет формат xml или формат свойств. Для того, чтобы провести сравнение с logback.xml, здесь свойства не вводятся, но особой разницы нет.

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">

<log4j:configuration xmlns:log4j='http://jakarta.apache.org/log4j/'>

  <appender name="STDOUT" class="org.apache.log4j.ConsoleAppender">
    <layout class="org.apache.log4j.PatternLayout">
      <param name="ConversionPattern"
             value="%d{yyyy-MM-dd HH:mm:ss,SSS\} [%-5p] [%t] %c{36\}.%M - %m%n"/>
    </layout>

    <!--过滤器设置输出的级别-->
    <filter class="org.apache.log4j.varia.LevelRangeFilter">
      <param name="levelMin" value="debug"/>
      <param name="levelMax" value="fatal"/>
      <param name="AcceptOnMatch" value="true"/>
    </filter>
  </appender>


  <appender name="ALL" class="org.apache.log4j.DailyRollingFileAppender">
    <param name="File" value="${user.dir}/logs/spring-common/jcl/all"/>
    <param name="Append" value="true"/>
    <!-- 每天重新生成日志文件 -->
    <param name="DatePattern" value="'-'yyyy-MM-dd'.log'"/>
    <!-- 每小时重新生成日志文件 -->
    <!--<param name="DatePattern" value="'-'yyyy-MM-dd-HH'.log'"/>-->
    <layout class="org.apache.log4j.PatternLayout">
      <param name="ConversionPattern"
             value="%d{yyyy-MM-dd HH:mm:ss,SSS\} [%-5p] [%t] %c{36\}.%M - %m%n"/>
    </layout>
  </appender>

  <!-- 指定logger的设置,additivity指示是否遵循缺省的继承机制-->
  <logger name="org.zp.notes.spring" additivity="false">
    <level value="error"/>
    <appender-ref ref="STDOUT"/>
    <appender-ref ref="ALL"/>
  </logger>

  <!-- 根logger的设置-->
  <root>
    <level value="warn"/>
    <appender-ref ref="STDOUT"/>
  </root>
</log4j:configuration>

Ссылаться на