Предыдущая версия справа и слева
Предыдущая версия
Следующая версия
|
Предыдущая версия
|
develop:java:logging [2023/05/03 16:13] admin |
develop:java:logging [2024/03/02 11:40] (текущий) admin |
| |
===== Сведения ===== | ===== Сведения ===== |
| |
<details> | <details> |
<summary>:!: Logback</summary> | <summary>:!: Logback</summary> |
(ch.qos.logback.classic.Logger)LoggerFactory.getLogger("com.baeldung.logback"); | (ch.qos.logback.classic.Logger)LoggerFactory.getLogger("com.baeldung.logback"); |
logger.debug("Hi there!"); | logger.debug("Hi there!"); |
| |
</code> | </code> |
| </details> |
| |
| |
| <details> |
| <summary>:!: Уровни</summary> |
| * TRACE — самый низкий уровень информации, в основном используемый для очень глубокой отладки кода, обычно не включаемый в производственные журналы. |
| * DEBUG — информация низкого уровня, используемая для целей отладки, обычно не включаемая в производственные журналы. |
| * INFO — серьезность журнала, содержащая информацию, например, о начавшейся или завершенной операции. |
| * WARN – уровень журнала, информирующий о событии, которое может потребовать нашего внимания, но не является критическим и может быть ожидаемым. |
| * ОШИБКА — уровень журнала, сообщающий об ошибке, ожидаемой или неожиданной, обычно означающей, что часть системы работает неправильно. |
| |
| Библиотека "logback-core" содержит следующие классы:\\ |
| * ConsoleAppender — добавляет события журнала в System.out или System.err. |
| * OutputStreamAppender — добавляет события журнала в java.io.Outputstream, предоставляя базовые услуги для других приложений. |
| * FileAppender — добавляет события журнала в файл. |
| * RollingFileAppender — добавляет события журнала в файл с возможностью автоматического переключения файлов. |
| |
| "Logback-classic" расширяет перечень:\\ |
| * SocketAppender — добавляет события журнала в сокет |
| * SSLSocketAppender — добавляет события журнала в сокет, используя безопасное соединение. |
| * SMTPAppender — накапливает данные в пакетах и отправляет содержимое пакета на указанный пользователем адрес электронной почты после наступления указанного пользователем события. |
| * DBAppender — добавляет данные в таблицы базы данных |
| * SyslogAppender — добавляет данные в место назначения, совместимое с Syslog. |
| * SiftingAppender — приложение, которое может разделять ведение журнала в соответствии с заданным атрибутом времени выполнения. |
| * AsyncAppender — асинхронно добавляет события журнала. |
| |
| |
| |
| |
</details> | </details> |
| |
<details> | <details> |
<summary>:!: Приемы/детали</summary> | <summary>:!: Приемы/детали</summary> |
| **Отдельный класс**\\ |
| Для того чтобы перенаправить определенные сообщение в какой либо файл, создаем ему отдельный логгер, указав любое имя, создаем ему аппендер, с нужной конфигурацией, и в логере указываем **additivity="false"** чтобы сообщение не передавалось дальше\\ |
| |
| |
<code java> | <code java> |
* %msg%n — сообщения журнала, за которыми следует символ-разделитель строк, зависящий от платформы. | * %msg%n — сообщения журнала, за которыми следует символ-разделитель строк, зависящий от платформы. |
[[https://logback.qos.ch/manual/layouts.html#conversionWord|Перечень]]\\ | [[https://logback.qos.ch/manual/layouts.html#conversionWord|Перечень]]\\ |
| </details> |
| |
| |
| <details> |
| <summary>:!: Итого</summary> |
| root-логер является корневым, перехватывает все, с заданным уровнем\\ |
| В апендерах можно настроить фильтрацию, в основном по уровню, но как то особо не развернешься с одними только ими\\ |
| |
| Есть вариант создавать свои логеры, но там нужно указывать класс, с которого идет обращения сообщения, из приложения, тобишь в приложении нужно создавать объект логера с таким же (или базовым) классом.\\ |
| Вроде вариант, но базовый логер эти сообщения тоже перехватывает\\ |
| |
| Пример с разделением на три файла, общий, ошибки и спец файл, в него пишется из отдельного класса, правда в общие файлы эти сообщения тоже попадают т.к. там корневой логер\\ |
<code java> | <code java> |
| <?xml version="1.0" encoding="UTF-8"?> |
| <configuration> |
| |
| <property name="LOGS" value="./logs" /> |
| |
| <appender name="Console" class="ch.qos.logback.core.ConsoleAppender"> |
| <encoder> |
| <pattern> |
| %d{dd-MM-yyyy HH:mm:ss.SSS} %magenta([%thread]) %highlight(%-5level) %logger{36}.%M - %msg%n |
| </pattern> |
| </encoder> |
| </appender> |
| |
| <appender name="SystemLog" class="ch.qos.logback.core.rolling.RollingFileAppender"> |
| <file>${LOGS}/system.log</file> |
| <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder"> |
| <Pattern>%d{dd-MM-yyyy HH:mm:ss.SSS} [%thread] %-5level %logger{36}.%M - %msg%n</Pattern> |
| </encoder> |
| <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> |
| <!-- rollover daily and when the file reaches 10 MegaBytes --> |
| <fileNamePattern>${LOGS}/archived/system_%d{yyyy-MM-dd}_%i.log.zip |
| </fileNamePattern> |
| <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP"> |
| <maxFileSize>50MB</maxFileSize> |
| </timeBasedFileNamingAndTriggeringPolicy> |
| </rollingPolicy> |
| <filter class="ch.qos.logback.classic.filter.ThresholdFilter"> |
| <level>INFO</level> |
| </filter> |
| </appender> |
| |
| <appender name="ErrorLog" class="ch.qos.logback.core.rolling.RollingFileAppender"> |
| <file>${LOGS}/error.log</file> |
| <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder"> |
| <Pattern>%d{dd-MM-yyyy HH:mm:ss.SSS} [%thread] %-5level %logger{36}.%M - %msg%n</Pattern> |
| </encoder> |
| <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> |
| <!-- rollover daily and when the file reaches 10 MegaBytes --> |
| <fileNamePattern>${LOGS}/archived/error_%d{yyyy-MM-dd}_%i.log.zip |
| </fileNamePattern> |
| <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP"> |
| <maxFileSize>50MB</maxFileSize> |
| </timeBasedFileNamingAndTriggeringPolicy> |
| </rollingPolicy> |
| <filter class="ch.qos.logback.classic.filter.ThresholdFilter"> |
| <level>ERROR</level> |
| </filter> |
| </appender> |
| |
| <appender name="WebappLog" class="ch.qos.logback.core.rolling.RollingFileAppender"> |
| <file>${LOGS}/webapp.log</file> |
| <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder"> |
| <Pattern>%d{dd-MM-yyyy HH:mm:ss.SSS} [%thread] %-5level %logger{36}.%M - %msg%n</Pattern> |
| </encoder> |
| <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> |
| <!-- rollover daily and when the file reaches 10 MegaBytes --> |
| <fileNamePattern>${LOGS}/archived/webapp_%d{yyyy-MM-dd}_%i.log.zip |
| </fileNamePattern> |
| <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP"> |
| <maxFileSize>50MB</maxFileSize> |
| </timeBasedFileNamingAndTriggeringPolicy> |
| </rollingPolicy> |
| <filter class="ch.qos.logback.classic.filter.ThresholdFilter"> |
| <level>ERROR</level> |
| </filter> |
| </appender> |
| |
| <logger name="com.baeldung.logback" level="INFO"> |
| <appender-ref ref="webapp" /> |
| </logger> |
| |
| <root level="info"> |
| <appender-ref ref="SystemLog" /> |
| <appender-ref ref="Console" /> |
| <appender-ref ref="ErrorLog"/> |
| </root> |
| </configuration> |
| </code> |
| |
| <code java> |
| private final Logger logger = LoggerFactory.getLogger(this.getClass()); |
| private final Logger waLogger = LoggerFactory.getLogger("com.baeldung.logback"); |
| |
| logger.info("Запись в лог"); |
| waLogger.info("(WA) Запись в лог"); |
</code> | </code> |
</details> | </details> |
| |
| |
| <details> |
| <summary>:!: Еще пример</summary> |
| <code xml> |
| <appender name="Commands" class="ch.qos.logback.core.rolling.RollingFileAppender"> |
| <file>./logs/commands/commands.log</file> |
| <append>true</append> |
| <encoder> |
| <pattern>%d{yyyy-MM-dd} %d{HH:mm:ss.SSS} %-5level - %msg%n</pattern> |
| </encoder> |
| <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> |
| <!-- daily rollover --> |
| <fileNamePattern>./logs/commands/commands-%d{yyyy-MM-dd}.log.zip</fileNamePattern> |
| <maxHistory>50</maxHistory> |
| </rollingPolicy> |
| </appender> |
| (...) |
| <logger name="com.gmware.lib.commands" level="INFO" additivity="false"> |
| <appender-ref ref="Commands"/> |
| </logger> |
| </code> |
| </details> |
| |
| |
| <details> |
| <summary>:!: Рабочий пример, есть Json</summary> |
| <code xml> |
| <?xml version="1.0" encoding="UTF-8" ?> |
| <configuration scan="false" scanPeriod="1 seconds" debug="false"> |
| |
| <appender name="ConsoleAppender" class="ch.qos.logback.core.ConsoleAppender"> |
| <target>System.out</target> |
| <encoder> |
| <pattern>%d{yyyy-MM-dd} %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n |
| </pattern> |
| </encoder> |
| </appender> |
| |
| <appender name="FileMultiplicatorDefaultAppender" |
| class="ch.qos.logback.core.rolling.RollingFileAppender"> |
| <file>./log/FileMultiplicator.log</file> |
| <append>true</append> |
| <encoder> |
| <pattern>%d{yyyy-MM-dd} %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n |
| </pattern> |
| </encoder> |
| <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy"> |
| <!-- rollover daily --> |
| <fileNamePattern>log/FileMultiplicator-%d{yyyy-MM-dd}.%i.zip</fileNamePattern> |
| <!-- each file should be at most 100MB, keep 7 days worth of history, but at most 20GB --> |
| <maxFileSize>100MB</maxFileSize> |
| <maxHistory>7</maxHistory> |
| <totalSizeCap>20GB</totalSizeCap> |
| </rollingPolicy> |
| </appender> |
| |
| <appender name="FileMultiplicatorJsonAppender" class="ch.qos.logback.core.rolling.RollingFileAppender"> |
| <file>log/json/FileMultiplicator.log</file> |
| <append>true</append> |
| <encoder class="net.logstash.logback.encoder.LoggingEventCompositeJsonEncoder"> |
| <providers> |
| <pattern> |
| <!-- the pattern that defines what to include --> |
| <pattern> |
| { |
| "timestamp": "%date{yyyy-MM-dd'T'HH:mm:ss}", |
| "logger": "%logger{36}", |
| "message": "%message", |
| "level": "%level" |
| } |
| </pattern> |
| </pattern> |
| <arguments/> |
| <logstashMarkers/> |
| <stackTrace> |
| <throwableConverter class="net.logstash.logback.stacktrace.ShortenedThrowableConverter"> |
| <maxDepthPerThrowable>30</maxDepthPerThrowable> |
| <maxLength>2048</maxLength> |
| <shortenedClassNameLength>20</shortenedClassNameLength> |
| <exclude>^sun\.reflect\..*\.invoke</exclude> |
| <exclude>^net\.sf\.cglib\.proxy\.MethodProxy\.invoke</exclude> |
| <rootCauseFirst>true</rootCauseFirst> |
| </throwableConverter> |
| </stackTrace> |
| </providers> |
| </encoder> |
| <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy"> |
| <!-- rollover daily --> |
| <fileNamePattern>log/json/FileMultiplicator-%d{yyyy-MM-dd}.%i.zip</fileNamePattern> |
| <!-- each file should be at most 100MB, keep 60 days worth of history, but at most 20GB --> |
| <maxFileSize>100MB</maxFileSize> |
| <maxHistory>7</maxHistory> |
| <totalSizeCap>20GB</totalSizeCap> |
| </rollingPolicy> |
| <filter class="ch.qos.logback.classic.filter.ThresholdFilter"> |
| <level>INFO</level> |
| </filter> |
| </appender> |
| |
| |
| <appender name="Commands" class="ch.qos.logback.core.rolling.RollingFileAppender"> |
| <file>./log/commands/commands.log</file> |
| <append>true</append> |
| <encoder> |
| <pattern>%d{yyyy-MM-dd} %d{HH:mm:ss.SSS} %-5level - %msg%n</pattern> |
| </encoder> |
| <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> |
| <!-- daily rollover --> |
| <fileNamePattern>./log/commands/commands-%d{yyyy-MM-dd}.log.zip</fileNamePattern> |
| <maxHistory>50</maxHistory> |
| </rollingPolicy> |
| </appender> |
| |
| <root level="INFO"> |
| <!-- <appender-ref ref="ConsoleAppender"/>--> |
| <appender-ref ref="FileMultiplicatorDefaultAppender"/> |
| <appender-ref ref="FileMultiplicatorJsonAppender"/> |
| </root> |
| |
| <logger name="com.gmware.lib.commands" level="INFO" additivity="false"> |
| <appender-ref ref="Commands"/> |
| </logger> |
| </configuration> |
| </code> |
| </details> |
| |
| |
| |
| |
| ===== Ротирование логов ===== |
| Аппендер класса **"RollingFileAppender"** расширяет класс **"FileAppender"**, добавляя возможность ротирования файлов\\ |
| |
| Два важных подкомпонента: **RollingPolicy** ("что делать") и **TriggeringPolicy** ("когда это делать")\\ |
| Первый может реализовать интерфейс для второго, тогда достаточно указать только его\\ |
| |
| |
| ==== RollingPolicy ==== |
| Внутри аппендера создается xml компонент политики, имеются разные классы, определяющие поведение\\ |
| |
| <details> |
| <summary>:!: Примеры классов для RollingPolicy</summary> |
| |
| **TimeBasedRollingPolicy** - На основе времени, один обязательный аргумент "fileNamePattern", так же есть "MaxHistory"\\ |
| Шаблон имени должен сдержать спецификатор "%d", тот может содержать шаблон даты/времени, по умолчанию "гггг-ММ-дд". **Период ротирования выводится из значения в fileNamePattern**\\ |
| т.е. в данном случае в полночь, если время не указано\\ |
| |
| **Сжатие** - для этого нужно добавить расширение "gz/zip" к имени файла\\ |
| |
| **SizeAndTimeBaseRollingPolicy** - собсна по дате и размеру. Здесь добавляется еще один обязательный токен именования - "%i", обозначающий порядковый номер\\ |
| |
| Пример конфигурации |
| <code xml> |
| <configuration> |
| <appender name="ROLLING" class="ch.qos.logback.core.rolling.RollingFileAppender"> |
| <file>mylog.txt</file> |
| <append>true</append> |
| |
| <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy"> |
| <!-- rollover daily --> |
| <fileNamePattern>mylog-%d{yyyy-MM-dd}.%i.txt</fileNamePattern> |
| <maxFileSize>100MB</maxFileSize> |
| <maxHistory>60</maxHistory> |
| <totalSizeCap>20GB</totalSizeCap> |
| </rollingPolicy> |
| |
| <encoder> |
| <pattern>%d{yyyy-MM-dd} %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n |
| </pattern> |
| </encoder> |
| </appender> |
| |
| |
| <root level="DEBUG"> |
| <appender-ref ref="ROLLING" /> |
| </root> |
| |
| </configuration> |
| </code> |
| |
| </details> |
| |
| |
| |
| |