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

Java EE

Концепция фреймворка ведения журнала

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

уровень журнала

Прежде всего, вам нужно знать, для чего нужен уровень журнала.Когда вы запускаете различные способы, уровень журнала определяет, какая информация должна быть выведена в соответствии с тем, как вы работаете, и установленным вами уровнем печати журнала.
Положения: журнал будет печатать только установленный приоритет и контент с более высоким приоритетом, чем он сам.
Приоритет уровня журнала: OFF > FATAL > ERROR > WARN > INFO > DEBUG > TRACE > ALL

  • ВЫКЛЮЧЕННЫЙ:
  • ФАТАЛЬНО:
  • ОШИБКА:
  • ПРЕДУПРЕЖДАТЬ:
  • ИНФОРМАЦИЯ:
  • ОТЛАЖИВАТЬ:
  • СЛЕД:
  • ВСЕ:

Общие фреймворки ведения журналов

Jul: Java Util Logging

Платформа журналов Sun, собственная структура журналов, имеет то преимущество, что она очень проста в использовании и может использоваться непосредственно в JDK. Однако функция JDKLog слишком проста, не поддерживает отображение заполнителей и имеет плохую масштабируемость, поэтому сейчас ею мало кто пользуется. Пример:

import java.util.logging.Logger;
 
/****
 ** JDKLog Demo
 **/
public class JDKLog
{
    public static void main( String[] args )
    {
        Logger logger = Logger.getLogger("JDKLog");
        logger.info("Hello World.");
    }
}

Log4j

Инфраструктура ведения журнала Apache имеет несколько уровней ведения журнала (DEBUG/INFO/WARN/ERROR), которые могут записывать журналы разных уровней журналов отдельно, что значительно облегчает просмотр журналов.

  • импортировать пакет зависимостей
<dependency>
    <groupId>log4j</groupId>
    <artifactId>log4j</artifactId>
    <version>1.2.17</version>
</dependency>
  • log4j.properties
 ### 设置###
log4j.rootLogger = debug,stdout,D,E

### 输出信息到控制抬 ###
log4j.appender.stdout = org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target = System.out
log4j.appender.stdout.layout = org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern = [%-5p] %d{yyyy-MM-dd HH:mm:ss,SSS} method:%l%n%m%n

### 输出DEBUG 级别以上的日志到=E://logs/error.log ###
log4j.appender.D = org.apache.log4j.DailyRollingFileAppender
log4j.appender.D.File = E://logs/log.log
log4j.appender.D.Append = true
log4j.appender.D.Threshold = DEBUG 
log4j.appender.D.layout = org.apache.log4j.PatternLayout
log4j.appender.D.layout.ConversionPattern = %-d{yyyy-MM-dd HH:mm:ss}  [ %t:%r ] - [ %p ]  %m%n

### 输出ERROR 级别以上的日志到=E://logs/error.log ###
log4j.appender.E = org.apache.log4j.DailyRollingFileAppender
log4j.appender.E.File =E://logs/error.log 
log4j.appender.E.Append = true
log4j.appender.E.Threshold = ERROR 
log4j.appender.E.layout = org.apache.log4j.PatternLayout
log4j.appender.E.layout.ConversionPattern = %-d{yyyy-MM-dd HH:mm:ss}  [ %t:%r ] - [ %p ]  %m%n

Log4J2

Обновленная версия Log4j, версия 2.x претерпела некоторые апгрейды в архитектуре, также претерпели некоторые изменения конфигурационные файлы.

  • импортировать пакет зависимостей
<!-- Log4J -->
<dependency>
  <groupId>org.apache.logging.log4j</groupId>
  <artifactId>log4j-api</artifactId>
  <version>2.6.2</version>
</dependency>
<dependency>
  <groupId>org.apache.logging.log4j</groupId>
  <artifactId>log4j-core</artifactId>
  <version>2.6.2</version>
</dependency>

Примечание. Пути пакетов зависимостей для log4j и log4j2 различаются, что специально установлено разработчиком, чтобы различать log4j и log4j2.

  • Добавьте файл конфигурации log4j2.xml и поместите его в каталог ресурсов:
<?xml version="1.0" encoding="UTF-8"?>    
<configuration status="error">  
<!--     先定义所有的appender -->  
    <appenders>  
<!--         这个输出控制台的配置 -->  
        <Console name="Console" target="SYSTEM_OUT">  
<!--             控制台只输出level及以上级别的信息(onMatch),其他的直接拒绝(onMismatch) -->  
            <ThresholdFilter level="trace" onMatch="ACCEPT" onMismatch="DENY"/>  
<!--             这个都知道是输出日志的格式 -->  
            <PatternLayout pattern="%d{HH:mm:ss.SSS} %-5level %class{36} %L %M - %msg%xEx%n"/>  
        </Console>  

<!--         文件会打印出所有信息,这个log每次运行程序会自动清空,由append属性决定,这个也挺有用的,适合临时测试用 -->  
<!--         append为TRUE表示消息增加到指定文件中,false表示消息覆盖指定的文件内容,默认值是true -->  
        <File name="log" fileName="log/test.log" append="false">  
            <PatternLayout pattern="%d{HH:mm:ss.SSS} %-5level %class{36} %L %M - %msg%xEx%n"/>  
        </File>  

<!--          添加过滤器ThresholdFilter,可以有选择的输出某个级别以上的类别  onMatch="ACCEPT" onMismatch="DENY"意思是匹配就接受,否则直接拒绝  -->  
        <File name="ERROR" fileName="logs/error.log">  
            <ThresholdFilter level="error" onMatch="ACCEPT" onMismatch="DENY"/>  
            <PatternLayout pattern="%d{yyyy.MM.dd 'at' HH:mm:ss z} %-5level %class{36} %L %M - %msg%xEx%n"/>  
        </File>  

<!--         这个会打印出所有的信息,每次大小超过size,则这size大小的日志会自动存入按年份-月份建立的文件夹下面并进行压缩,作为存档 -->  
        <RollingFile name="RollingFile" fileName="logs/web.log"  
                     filePattern="logs/$${date:yyyy-MM}/web-%d{MM-dd-yyyy}-%i.log.gz">  
            <PatternLayout pattern="%d{yyyy-MM-dd 'at' HH:mm:ss z} %-5level %class{36} %L %M - %msg%xEx%n"/>  
            <SizeBasedTriggeringPolicy size="2MB"/>  
        </RollingFile>  
    </appenders>  

<!--     然后定义logger,只有定义了logger并引入的appender,appender才会生效 -->  
    <loggers>  
<!--         建立一个默认的root的logger -->  
        <root level="trace">  
            <appender-ref ref="RollingFile"/>  
            <appender-ref ref="Console"/>  
            <appender-ref ref="ERROR" />  
            <appender-ref ref="log"/>  
        </root> 
    </loggers>  
</configuration>  

Commons Logging

Фасад журнала поддерживает динамическую загрузку реализации компонентов журнала во время выполнения. То есть в коде приложения вам нужно только вызвать общий интерфейс ведения журнала, а базовой реализацией может быть log4j или Java Util Logging.

Slf4J

Лагерь, противоположный Commons Logging, это интерфейс, а реализация — Logback.

Logback

Реализация Slf4J.

Сравнение механизмов реализации Commons Logging и Slf4j

  • Механизм реализации ведения журнала Commons: ведение журнала Commons использует собственный ClassLoader для поиска и загрузки конкретных локальных реализаций с помощью механизма динамического поиска во время работы программы. Подробные политики см. в файле org.apache.commons.logging.impl.LogFactoryImpl.java в пакете commons-logging-*.jar. Поскольку разные подключаемые модули OSGi используют независимые загрузчики классов, этот механизм OSGI гарантирует, что подключаемые модули не зависят друг от друга, и его механизм ограничивает нормальное использование ведения журналов общих ресурсов в OSGi.
  • Механизм реализации Slf4j: Slf4j статически привязывает локальную библиотеку LOG во время компиляции, поэтому ее можно нормально использовать в OSGi. Это поиск org.slf4j.impl.StaticLoggerBinder в пути к классам, а затем в этом классе выполняется связывание.

Если в проекте выбран фреймворк логирования

  • Механизм реализации Slf4j определяет, что Slf4j имеет меньше ограничений и более широкий диапазон использования. Поскольку Slf4j статически связывает локальную библиотеку LOG во время компиляции, он более универсален, чем ведение журнала Commons.

  • Logback имеет лучшую производительность. Logback утверждает, что производительность некоторых ключевых операций, таких как определение того, следует ли регистрировать оператор журнала, была значительно улучшена. Эта операция занимает 3 наносекунды в Logback и 30 наносекунд в Log4J. LogBack также создает регистраторы быстрее: 13 мс по сравнению с 23 мс в Log4J. Более того, для извлечения существующего регистратора требуется всего 94 наносекунды по сравнению с 2234 наносекундами для Log4J, что сокращает время до 1/23. Улучшение производительности по сравнению с JUL также значительно.

  • Commons Logging имеет более высокие накладные расходы Чтобы уменьшить накладные расходы на сбор информации журнала при создании Commons Logging, обычная практика такова:

if(log.isDebugEnabled()){
    log.debug("User name: " +
    user.getName() + " buy goods id :" + good.getId());
}

В лагере Slf4j вы просто делаете:

log.debug("User name:{} ,buy goods id :{}", user.getName(),good.getId());

Другими словами, slf4j помещает накладные расходы на журнал сборки после того, как подтвердит необходимость отображения этого журнала, уменьшает накладные расходы памяти и чашки, использует заполнители, а код становится более кратким.

  • Документация по журналу бесплатна. Вся документация Logback полностью предоставляется бесплатно, в отличие от Log4J, который предоставляет только часть бесплатной документации и требует от пользователей покупки платной документации.

Как использовать Slf4J в своем проекте

Мост между Slf4J и другими журналами

имя пакета jar иллюстрировать
slf4j-log4j12-1.7.13.jar Для версии моста log4j1.2 вам необходимо добавить log4j.jar в путь к классам.
slf4j-jdk14-1.7.13.jar Мост к java.util.logging, собственной среде ведения журналов JDK.
slf4j-nop-1.7.13.jar Мост NOP, молча отбрасывающий все журналы.
slf4j-simple-1.7.13.jar Мост с простой реализацией, который выводит все события в System.err, печатаются только сообщения INFO и выше, что может быть полезно в небольших приложениях.
slf4j-jcl-1.7.13.jar Мост для ведения журналов Jakarta Commons Этот мост делегирует все журналы SLF4j в JCL.
logback-classic-1.0.13.jar(requires logback-core-1.0.13.jar) Нативная реализация slf4j, logback напрямую реализует интерфейс slf4j, поэтому использование slf4j в сочетании с logback также означает меньшие затраты памяти и вычислительных ресурсов.

Конкретный метод доступа выглядит следующим образом:

image

Как соединить устаревшие API

При использовании разных фреймворков фреймворки, интегрированные другими, могут отличаться. Например, Spring Framework интегрирует ведение журнала Commons, а XSocket полагается на ведение журнала Java Util. Теперь нам нужно решить проблему, заключающуюся в том, что разные компоненты логов в разных фреймворках объединяются в Slf4J. SLF4J передаст журнал конкретному инструменту реализации журнала в соответствии с связующим. Slf4J поставляется с несколькими модулями моста, которые могут перенаправлять log4j, JCL и API в java.util.logging на Slf4J.

Устаревшая схема сопряжения API

имя пакета jar эффект
log4j-over-slf4j-version.jar перенаправить log4j на slf4j
jcl-over-slf4j-version.jar Перенаправить Simple Logger в журнал общих ресурсов на slf4j
jul-to-slf4j-version.jar Перенаправить ведение журнала Java Util на slf4j

См. следующий рисунок для мостового метода:

image

Вопросы, требующие внимания при использовании моста slf4j

При использовании моста slf4j обратите внимание на то, чтобы избежать образования бесконечного цикла.В пакете jar, от которого зависит проект, не должно быть следующих ситуаций:

Условия для нескольких пакетов журналов для формирования бесконечного цикла причина
И log4j-over-slf4j.jar, и slf4j-log4j12.jar существуют. Все вызовы журналирования делегируются log4j из-за наличия slf4j-log4j12.jar. Однако из-за одновременного существования log4j-over-slf4j.jar все вызовы log4j API будут делегированы соответствующему эквивалентному slf4j, поэтому существование log4j-over-slf4j.jar и slf4j-log4j12.jar при этом будет образовываться бесконечный цикл
И jul-to-slf4j.jar, и slf4j-jdk14.jar существуют Из-за существования файла slf4j-jdk14.jar все вызовы журнала будут делегированы журналу jdk. Однако из-за одновременного существования jul-to-slf4j.jar все вызовы jul API будут делегированы соответствующему эквиваленту slf4j, поэтому сосуществование jul-to-slf4j.jar и slf4j-jdk14. jar образует бесконечный цикл.