- PVSM.RU - https://www.pvsm.ru -

Java: свертывание многострочных логов в однострочный лог с помощью Spirng и логгера Logback или Log4j2

Logback и Log4j2 – одни из самых известных фреймворков логирования в JAVA. Фреймворк Logback используется только совместно с библиотекой SLF4J, которая представляет собой интерфейс для систем протоколирования событий. Log4j2 представляет собой вторую, улучшенную версию логгера Log4, библиотеку логирования, в которой интерфейс API и реализация выделены отдельно, что позволяет использовать API Log4j 2 совместно с реализацией другого логгера.

Spring Music является приложением для использования сервиса базы данных среды Cloud Foundry совместно со Spring Framework и Spring Boot. Оно создано для сохранения одних и тех же доменных объектов в одном из множества различных хранилищ – объектно-реляционном, документно-ориентированном или распределенном (key-value store).

Java: свертывание многострочных логов в однострочный лог с помощью Spirng и логгера Logback или Log4j2 - 1

Двумя наиболее распространенными логгерами, которые используются совместно со Spring / Spring Boot, являются Logback и Log4j2. Еще недавно разработчик имел большую свободу действий в отношении формата логов и самих файлов, используемых для ведения журнала. Однако в современном мире внедрения контейнеров и масштабирования логирование обычно предлагает корпоративные решения, требующие определенного уровня стандартизации.

Одна из самых больших проблем заключается в том, что исключения Java обычно приводят к большой многострочной трассировке стека в журналах. Из-за этого вместо одного события журнала, указывающего на исключение, или сообщение об ошибке, у вас возникает более 100 различных логов, по одному на каждую строку трассировки стека, перемежающихся другими событиями журнала, поступающими от других служб или экземпляров служб.

В этой статье рассказывается, как настроить приложение Spring Boot для свертывания исключений в одну строку как для логгера Logback, так и для Log4j2. Это позволяет рассматривать логирование исключения и трассировку стека как один лог событий.

Java: свертывание многострочных логов в однострочный лог с помощью Spirng и логгера Logback или Log4j2 - 2
Классы ошибок Error и исключений Exception в JAVA

Java: свертывание многострочных логов в однострочный лог с помощью Spirng и логгера Logback или Log4j2 - 3
Проверяемые Checked и непроверяемые Unchecked исключения Exception в JAVA

Приложение Spring Music

В этой статье для специализированного логирования используется кастомная версия приложения spring-music [1],  необходимая для работы логгеров Logback и Log4j2. Для начала нужно убедиться, что мы сможем воссоздать ее из источника. Проект требует наличия Java8, поэтому первым шагом является установка Java8 на ваш хост Ubuntu.

Java: свертывание многострочных логов в однострочный лог с помощью Spirng и логгера Logback или Log4j2 - 4

Затем мы берем исходный код проекта с github [1] и создаем сборку с использованием встроенных скриптов системы сборки Gradle:

Java: свертывание многострочных логов в однострочный лог с помощью Spirng и логгера Logback или Log4j2 - 5

Свертывание многострочных исключений с использованием Logback

Двинемся дальше и создадим Java-архив проекта jar с реализацией логгера Logback с помощью стандартной команды Gradle:

Java: свертывание многострочных логов в однострочный лог с помощью Spirng и логгера Logback или Log4j2 - 6

Файл “build/libs/spring-music.jar” является самоисполняемым и содержит встроенный Tomcat, который привязан к localhost:8080. Вызов jar-файла осуществляется с помощью команды:

Java: свертывание многострочных логов в однострочный лог с помощью Spirng и логгера Logback или Log4j2 - 7

Вызов http://localhost:8080 [2] в браузере покажет вам страницу со списком Альбомов, а в консоль будет выведена строка лога, выглядящая таким образом:

Java: свертывание многострочных логов в однострочный лог с помощью Spirng и логгера Logback или Log4j2 - 8

Этот синтаксис строки лога определен в “src/main/resources/logback-spring.xml [3]” с использованием пользовательского шаблона:

Java: свертывание многострочных логов в однострочный лог с помощью Spirng и логгера Logback или Log4j2 - 9

Переменные ${…} извлекаются из application.properties и system properties, которые можно просмотреть на странице по адресу http://localhost:8080/env [4]. Однако нужная нам часть кода находится сразу после сообщения (%m).

Java: свертывание многострочных логов в однострочный лог с помощью Spirng и логгера Logback или Log4j2 - 10

Слово ‘MULTIEXCEPTION’ не имеет особого значения, это просто уникальный строковый маркер, который позволяет нам узнать, где заканчивается сообщение (%m) и начинается исключение. Если хотите, то можете оставить этот маркер.

Далее, вместо того, чтобы просто вставлять заполнитель %xException, который выводил бы большую трассировку стека с символами новой строки, мы преобразуем значение при помощи функции %replace и заменяем все символы новой строки на выражение “u2028”, которое является представлением разделителя строк Unicode [5].

Удаление символов "n" из трассировки стека означает, что теперь трассировка стека теперь будет отправляться в однострочном виде. Чтобы доказать это, перейдите по ссылке http://localhost:8080/errors/throw [6], где имеется Error Controller [7], который намеренно отбрасывает NullPointerException с помощью следующего кода:

Java: свертывание многострочных логов в однострочный лог с помощью Spirng и логгера Logback или Log4j2 - 11

Это создает в консоли строку лога, показанную ниже:

Java: свертывание многострочных логов в однострочный лог с помощью Spirng и логгера Logback или Log4j2 - 12

Здесь видно, что выражение «u2028» отделяет то, что раньше было переводом строки в трассировке стека. Теперь сообщение об исключении и трассировка стека будут отправлены как единое целое.

Java: свертывание многострочных логов в однострочный лог с помощью Spirng и логгера Logback или Log4j2 - 13

Свертывание многострочных исключений с использованием Log4j2

Чтобы переопределить сценарий сборки по умолчанию и использовать Log4j2 в качестве резервной реализации данного проекта, нужно использовать файл “build-log4j2.gradle”.

Java: свертывание многострочных логов в однострочный лог с помощью Spirng и логгера Logback или Log4j2 - 14

Файл “build/libs/spring-music.jar” является самоисполняемым и использует встроенный Tomcat, который привязан к localhost:8080. Как и в предыдущем примере, вызов jar-файла осуществляется с помощью команды:

Java: свертывание многострочных логов в однострочный лог с помощью Spirng и логгера Logback или Log4j2 - 15

Вызов http://localhost:8080 [2] с помощью браузера отобразит страницу со списком Альбомов с выводом на консоль строки лога, которая выглядит следующим образом:

Java: свертывание многострочных логов в однострочный лог с помощью Spirng и логгера Logback или Log4j2 - 16

Этот синтаксис строки журнала определен в “src/main/resources/log4j2.xml [8]” с использованием кастомного шаблона:

Java: свертывание многострочных логов в однострочный лог с помощью Spirng и логгера Logback или Log4j2 - 17

Переменные ${…} извлекаются из application.properties и system properties, которые можно просмотреть на странице по адресу http://localhost:8080/env [4]. Однако нужная нам часть кода находится сразу после сообщения (%m).

Java: свертывание многострочных логов в однострочный лог с помощью Spirng и логгера Logback или Log4j2 - 18

Слово ‘MULTIEXCEPTION’ не имеет специального значения, это просто уникальный строковый маркер по нашему выбору, который позволяет узнать, где заканчивается сообщение (%m) и начинается исключение. Если хотите, то можете его оставить.

Но после этого вместо того, чтобы просто вставлять заполнитель %xException, который выводил бы большую трассировку стека с символами новой строки, мы преобразуем значение при помощи функции %replace, которая заменяет все символы новой строки выражением “u2028”, которое является представлением разделителя строк Unicode [5].

Удаление символов "n" из трассировки стека означает, что теперь трассировка стека теперь будет отправляться в виде одной строки. Чтобы доказать это, перейдите по ссылке http://localhost:8080/errors/throw [6], где имеется Error Controller [7], который намеренно отбрасывает NullPointerException с помощью следующего кода:

Java: свертывание многострочных логов в однострочный лог с помощью Spirng и логгера Logback или Log4j2 - 19

Это создает в консоли строку лога, показанную ниже:

Java: свертывание многострочных логов в однострочный лог с помощью Spirng и логгера Logback или Log4j2 - 20

Как можно увидеть, здесь выражение «u2028» отделяет то, что раньше было переводом строки в трассировке стека. Теперь сообщение об исключении и трассировка стека будут отправляться как единое целое.

Выводы

Возможность свертывания многострочной трассировки стека Java в одну строку означает, что данный прием можно рассматривать как единое централизованное решение логирования.
Не существует никаких причин тратить вычислительные и человеческие ресурсы на восстановление трассировки стека на стороне назначения с помощью идентификаторов корреляции, больших размеров стека, высокой загрузки процессора и «умного» парсинга, если гораздо эффективнее выполнить это свертывание на стороне источника.

При этом символ Unicode всегда может быть заменен на стороне сбора логов (например, на стороне конвейера для сбора, фильтрации и нормализации логов Logstash) для восстановления сообщения в исходном формате.

Ссылочный материал

Немного рекламы :)

Спасибо, что остаётесь с нами. Вам нравятся наши статьи? Хотите видеть больше интересных материалов? Поддержите нас, оформив заказ или порекомендовав знакомым, облачные VPS для разработчиков от $4.99 [36], уникальный аналог entry-level серверов, который был придуман нами для Вас: Вся правда о VPS (KVM) E5-2697 v3 (6 Cores) 10GB DDR4 480GB SSD 1Gbps от $19 или как правильно делить сервер? [37] (доступны варианты с RAID1 и RAID10, до 24 ядер и до 40GB DDR4).

Dell R730xd в 2 раза дешевле в дата-центре Equinix Tier IV в Амстердаме? Только у нас 2 х Intel TetraDeca-Core Xeon 2x E5-2697v3 2.6GHz 14C 64GB DDR4 4x960GB SSD 1Gbps 100 ТВ от $199 [38] в Нидерландах! Dell R420 — 2x E5-2430 2.2Ghz 6C 128GB DDR3 2x960GB SSD 1Gbps 100TB — от $99! Читайте о том Как построить инфраструктуру корп. класса c применением серверов Dell R730xd Е5-2650 v4 стоимостью 9000 евро за копейки? [39]

Автор: ua-hosting.company

Источник [40]


Сайт-источник PVSM.RU: https://www.pvsm.ru

Путь до страницы источника: https://www.pvsm.ru/java/342095

Ссылки в тексте:

[1] spring-music: https://github.com/fabianlee/spring-music

[2] http://localhost:8080: http://localhost:8080

[3] src/main/resources/logback-spring.xml: https://github.com/fabianlee/spring-music/blob/master/src/main/resources/logback-spring.xml

[4] http://localhost:8080/env: http://localhost:8080/env

[5] представлением разделителя строк Unicode: https://en.wikipedia.org/wiki/Newline#Unicode

[6] http://localhost:8080/errors/throw: http://localhost:8080/errors/throw

[7] Error Controller: https://github.com/fabianlee/spring-music/blob/master/src/main/java/org/cloudfoundry/samples/music/web/ErrorController.java

[8] src/main/resources/log4j2.xml: https://github.com/fabianlee/spring-music/blob/master/src/main/resources/log4j2.xml

[9] https://docs.cloudfoundry.org/loggregator/architecture.html#metron: https://docs.cloudfoundry.org/loggregator/architecture.html#metron

[10] docs.pivotal.io/pivotalcf/2-0/devguide/deploy-apps/streaming-logs.html#format: http://docs.pivotal.io/pivotalcf/2-0/devguide/deploy-apps/streaming-logs.html#format

[11] https://docs.pivotal.io/tiledev/2-0/nozzle.html#examples: https://docs.pivotal.io/tiledev/2-0/nozzle.html#examples

[12] http://grokconstructor.appspot.com/do/construction: http://grokconstructor.appspot.com/do/construction

[13] https://github.com/cloudfoundry/dropsonde-protocol: https://github.com/cloudfoundry/dropsonde-protocol

[14] https://logback.qos.ch/manual/layouts.html: https://logback.qos.ch/manual/layouts.html

[15] https://www.elastic.co/guide/en/logstash/current/plugins-codecs-protobuf.html: https://www.elastic.co/guide/en/logstash/current/plugins-codecs-protobuf.html

[16] https://github.com/cloudfoundry-community/firehose-to-syslog: https://github.com/cloudfoundry-community/firehose-to-syslog

[17] http://schd.ws/hosted_files/cfsummit2016/f7/MonitoringCloudFoundry-LearningAboutTheFirehose.pdf: http://schd.ws/hosted_files/cfsummit2016/f7/MonitoringCloudFoundry-LearningAboutTheFirehose.pdf

[18] https://github.com/cloudfoundry-community/logsearch-for-cloudfoundry: https://github.com/cloudfoundry-community/logsearch-for-cloudfoundry

[19] https://discuss.pivotal.io/hc/en-us/articles/223207207-Why-Loggregator-may-lose-logs : https://discuss.pivotal.io/hc/en-us/articles/223207207-Why-Loggregator-may-lose-logs

[20] http://scottfrederick.cfapps.io/blog/2014/02/20/cloud-foundry-and-logstash: http://scottfrederick.cfapps.io/blog/2014/02/20/cloud-foundry-and-logstash

[21] https://logz.io/blog/cloud-foundry-elk-stack/: https://logz.io/blog/cloud-foundry-elk-stack/

[22] https://docs.cloudfoundry.org/loggregator/cli-plugin.html: https://docs.cloudfoundry.org/loggregator/cli-plugin.html

[23] https://github.com/cloudfoundry/loggregator-release/blob/develop/docs/java-multi-line-work-around.md: https://github.com/cloudfoundry/loggregator-release/blob/develop/docs/java-multi-line-work-around.md

[24] https://stackoverflow.com/questions/23096129/make-logback-include-the-t-between-date-and-time-in-its-date-format-for-str: https://stackoverflow.com/questions/23096129/make-logback-include-the-t-between-date-and-time-in-its-date-format-for-str

[25] http://cloud.rohitkelapure.com/2016/06/multi-line-java-stack-traces-out-of.html: http://cloud.rohitkelapure.com/2016/06/multi-line-java-stack-traces-out-of.html

[26] https://discuss.elastic.co/t/match-and-replace-unicode-characters/56656: https://discuss.elastic.co/t/match-and-replace-unicode-characters/56656

[27] https://www.diycode.cc/projects/cloudfoundry/loggregator: https://www.diycode.cc/projects/cloudfoundry/loggregator

[28] https://www.elastic.co/guide/en/logstash/5.0/breaking-changes.html: https://www.elastic.co/guide/en/logstash/5.0/breaking-changes.html

[29] https://medium.com/@martatatiana/aws-lambda-in-java-8-log4j2-and-scattered-stacktrace-in-cloudwatch-a4aea2e7bf2a: https://medium.com/@martatatiana/aws-lambda-in-java-8-log4j2-and-scattered-stacktrace-in-cloudwatch-a4aea2e7bf2a

[30] https://springframework.guru/using-log4j-2-spring-boot/: https://springframework.guru/using-log4j-2-spring-boot/

[31] https://www.quickprogrammingtips.com/spring-boot/using-log4j2-with-spring-boot.html: https://www.quickprogrammingtips.com/spring-boot/using-log4j2-with-spring-boot.html

[32] https://logging.apache.org/log4j/2.x/manual/layouts.html: https://logging.apache.org/log4j/2.x/manual/layouts.html

[33] http://www.codepreference.com/2016/04/configurable-thread-context-tags-log4j2.html: http://www.codepreference.com/2016/04/configurable-thread-context-tags-log4j2.html

[34] https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-external-config.html: https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-external-config.html

[35] http://logging.apache.org/log4j/2.x/manual/configuration.html#PropertySubstitution: http://logging.apache.org/log4j/2.x/manual/configuration.html#PropertySubstitution

[36] облачные VPS для разработчиков от $4.99: https://ua-hosting.company/cloudvps/nl

[37] Вся правда о VPS (KVM) E5-2697 v3 (6 Cores) 10GB DDR4 480GB SSD 1Gbps от $19 или как правильно делить сервер?: https://habr.com/company/ua-hosting/blog/347386/

[38] 2 х Intel TetraDeca-Core Xeon 2x E5-2697v3 2.6GHz 14C 64GB DDR4 4x960GB SSD 1Gbps 100 ТВ от $199: https://ua-hosting.company/serversnl

[39] Как построить инфраструктуру корп. класса c применением серверов Dell R730xd Е5-2650 v4 стоимостью 9000 евро за копейки?: https://habr.com/company/ua-hosting/blog/329618/

[40] Источник: https://habr.com/ru/post/482804/?utm_source=habrahabr&utm_medium=rss&utm_campaign=482804