Структурированный журнал приложений для Azure Spring Apps
Примечание.
Планы "Базовый", "Стандартный" и "Корпоративный" будут устарели начиная с середины марта 2025 г. с 3-летнего периода выхода на пенсию. Рекомендуется перейти в приложения контейнеров Azure. Дополнительные сведения см. в объявлении о выходе на пенсию в Azure Spring Apps.
Стандартный план потребления и выделенного плана будет устарел с 30 сентября 2024 г. с полным завершением работы после шести месяцев. Рекомендуется перейти в приложения контейнеров Azure. Дополнительные сведения см. в статье "Миграция потребления Azure Spring Apps Standard" и выделенного плана в приложения контейнеров Azure.
Эта статья относится к: ✔️ Basic/Standard ✔️ Enterprise
Из этой статьи вы узнаете, как создавать и собирать структурированные данные журнала приложений в Azure Spring Apps. Если правильно настроить Azure Spring Apps, вы сможете запрашивать журнал приложений и выполнять анализ посредством Log Analytics.
Требования к схеме журнала
Для должной работы журнал приложений должен быть в формате JSON и соответствовать заданной схеме. Azure Spring Apps использует эту схему, чтобы анализировать приложение и передавать данные в Log Analytics.
Примечание.
Включение формата журнала JSON затрудняет чтение потоковой передачи журналов из консоли. Чтобы получить результат в понятном для человека формате, добавьте аргумент --format-json
в команду CLI az spring app logs
. См. статью Форматирование структурированных журналов JSON.
Требования к схеме JSON:
Ключ JSON | Тип значения JSON | Обязательное поле | Столбец в Log Analytics | Description |
---|---|---|---|---|
TIMESTAMP | строка | Да | AppTimestamp | Метка времени в формате UTC |
logger | строка | Нет | Ведение журнала | logger |
level | строка | Нет | CustomLevel | log level |
среды | строка | Нет | Дискуссия | среды |
message | строка | Нет | Сообщение | Сообщение журнала |
stackTrace | строка | Нет | StackTrace | Трассировка стека исключений |
exceptionClass | строка | Нет | ExceptionClass | Название класса исключений |
mdc | Вложенный массив JSON | No | Сопоставленный контекст диагностики | |
mdc.traceId | строка | Нет | TraceId | Идентификатор трассировки для распределенной трассировки |
mdc.spanId | строка | Нет | SpanId | Идентификатор диапазона для распределенной трассировки |
- Поле timestamp является обязательным и должно быть в формате UTC, все остальные поля необязательны.
- traceId и spanId в поле mdc используются в целях трассировки.
- Каждую запись JSON необходимо вносить отдельной строкой.
Пример записи журнала
{"timestamp":"2021-01-08T09:23:51.280Z","logger":"com.example.demo.HelloController","level":"ERROR","thread":"http-nio-1456-exec-4","mdc":{"traceId":"c84f8a897041f634","spanId":"c84f8a897041f634"},"stackTrace":"java.lang.RuntimeException: get an exception\r\n\tat com.example.demo.HelloController.throwEx(HelloController.java:54)\r\n\","message":"Got an exception","exceptionClass":"RuntimeException"}
Ограничения
Каждая строка журналов JSON имеет не более 16 байт. Если выходные данные JSON одной записи журнала превышают это ограничение, он разбивается на несколько строк, и каждая необработанную строку собирается в Log
столбец без анализа структурно.
Как правило, эта ситуация возникает при ведении журнала исключений с глубоким стеком, особенно если агент AppInsights in-Process включен. Примените параметры ограничения к результату трассировки стека (см. приведенные ниже примеры конфигурации), чтобы гарантировать его надлежащий анализ.
Создание журнала JSON в соответствии со схемой
Для приложений Spring можно создать ожидаемый формат журнала JSON с помощью общих платформ ведения журнала, таких как Logback и Log4j2.
Ведение журнала с помощью logback
При использовании начальных средств Spring Boot по умолчанию используется logback. Для приложений Logback используйте кодировщик logstash-encoder для создания форматированного журнала JSON. Этот метод поддерживается в Spring Boot версии 2.1 или более поздней.
Процедура:
Добавьте зависимость logstash в файл
pom.xml
.<dependency> <groupId>net.logstash.logback</groupId> <artifactId>logstash-logback-encoder</artifactId> <version>6.5</version> </dependency>
Переведите файл конфигурации
logback-spring.xml
в формат JSON.<configuration> <appender name="stdout" class="ch.qos.logback.core.ConsoleAppender"> <encoder class="net.logstash.logback.encoder.LoggingEventCompositeJsonEncoder"> <providers> <timestamp> <fieldName>timestamp</fieldName> <timeZone>UTC</timeZone> </timestamp> <loggerName> <fieldName>logger</fieldName> </loggerName> <logLevel> <fieldName>level</fieldName> </logLevel> <threadName> <fieldName>thread</fieldName> </threadName> <nestedField> <fieldName>mdc</fieldName> <providers> <mdc /> </providers> </nestedField> <stackTrace> <fieldName>stackTrace</fieldName> <!-- maxLength - limit the length of the stack trace --> <throwableConverter class="net.logstash.logback.stacktrace.ShortenedThrowableConverter"> <maxDepthPerThrowable>200</maxDepthPerThrowable> <maxLength>14000</maxLength> <rootCauseFirst>true</rootCauseFirst> </throwableConverter> </stackTrace> <message /> <throwableClassName> <fieldName>exceptionClass</fieldName> </throwableClassName> </providers> </encoder> </appender> <root level="info"> <appender-ref ref="stdout" /> </root> </configuration>
При использовании файла конфигурации ведения журнала с суффиксом
-spring
, напримерlogback-spring.xml
, можно задать конфигурацию ведения журнала на основе активного профиля Spring.<configuration> <springProfile name="dev"> <!-- JSON appender definitions for local development, in human readable format --> <include resource="org/springframework/boot/logging/logback/defaults.xml" /> <include resource="org/springframework/boot/logging/logback/console-appender.xml" /> <root level="info"> <appender-ref ref="CONSOLE" /> </root> </springProfile> <springProfile name="!dev"> <!-- JSON appender configuration from previous step, used for staging / production --> ... </springProfile> </configuration>
При локальной разработке запустите приложение Spring с аргументом виртуальной машины Java
-Dspring.profiles.active=dev
, после чего появятся журналы в понятном для человека формате, а не строки в формате JSON.
Ведение журнала с помощью log4j2
Если речь идет о приложениях log4j2, создать журнал в формате JSON можно с помощью json-template-layout. Этот метод поддерживается в Spring Boot 2.1 и более поздних версиях.
Процедура:
Исключите
spring-boot-starter-logging
изspring-boot-starter
, добавьте зависимостиspring-boot-starter-log4j2
,log4j-layout-template-json
в файлpom.xml
.<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> <exclusions> <exclusion> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-logging</artifactId> </exclusion> </exclusions> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-log4j2</artifactId> </dependency> <dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-layout-template-json</artifactId> <version>2.14.0</version> </dependency>
Подготовьте файл шаблона макета JSON
jsonTemplate.json
в пути к классу.{ "mdc": { "$resolver": "mdc" }, "exceptionClass": { "$resolver": "exception", "field": "className" }, "stackTrace": { "$resolver": "exception", "field": "stackTrace", "stringified": true }, "message": { "$resolver": "message", "stringified": true }, "thread": { "$resolver": "thread", "field": "name" }, "timestamp": { "$resolver": "timestamp", "pattern": { "format": "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", "timeZone": "UTC" } }, "level": { "$resolver": "level", "field": "name" }, "logger": { "$resolver": "logger", "field": "name" } }
Используйте этот шаблон макета JSON в своем файле конфигурации
log4j2-spring.xml
.<configuration> <appenders> <console name="Console" target="SYSTEM_OUT"> <!-- maxStringLength - limit the length of the stack trace --> <JsonTemplateLayout eventTemplateUri="classpath:jsonTemplate.json" maxStringLength="14000" /> </console> </appenders> <loggers> <root level="info"> <appender-ref ref="Console" /> </root> </loggers> </configuration>
Анализ журналов в Log Analytics
После правильной настройки приложения журнал консоли приложения передается в Log Analytics. Такая структура обеспечивает эффективную обработку запросов в Log Analytics.
Проверка структуры журнала в Log Analytics
Это можно сделать следующим образом:
Перейдите на страницу обзора своего экземпляра службы.
Щелкните Журналы в разделе Мониторинг.
Выполните этот запрос.
AppPlatformLogsforSpring | where TimeGenerated > ago(1h) | project AppTimestamp, Logger, CustomLevel, Thread, Message, ExceptionClass, StackTrace, TraceId, SpanId
Вы получите журналы приложений, как на этом изображении:
Отобразите записи журнала, содержащие ошибки.
Чтобы проверить записи журнала с ошибкой, выполните следующий запрос:
AppPlatformLogsforSpring
| where TimeGenerated > ago(1h) and CustomLevel == "ERROR"
| project AppTimestamp, Logger, ExceptionClass, StackTrace, Message, AppName
| sort by AppTimestamp
Этот запрос позволяет искать ошибки или менять условия запроса таким образом, чтобы находить конкретные классы исключения или коды ошибки.
Отображение записей журнала по определенному идентификатору трассировки
Чтобы изучить записи журнала по конкретному идентификатору трассировки trace_id, выполните следующий запрос:
AppPlatformLogsforSpring
| where TimeGenerated > ago(1h)
| where TraceId == "trace_id"
| project AppTimestamp, Logger, TraceId, SpanId, StackTrace, Message, AppName
| sort by AppTimestamp
Следующие шаги
- Подробнее о запросах к журналу см. в статье Начало работы с запросами к журналу в Azure Monitor.