Как включить несколько полей JSON при использовании ведения журнала JSON с SLF4J?
Я работаю с Dropwizard 1.3.2, который делает запись с использованием SLF4J поверх Logback. Я пишу логи для приема в ElasticSearch, поэтому я подумал, что я буду использовать JSON logging и создаю несколько инструментальных панелей Kibana. Но мне действительно нужно более одного элемента JSON на каждое сообщение журнала - если я записываю обновление статуса с десятью полями, в идеале я хотел бы зарегистрировать объект и сделать так, чтобы поля JSON отображались как записи верхнего уровня в журнале JSON. Я получил работу MDC, но это очень неуклюже и не выравнивает объекты.
Это оказалось сложно! Как я могу это сделать? У меня есть вход в JSON, но я не могу приятно войти несколько полей JSON!
Вещи, которые я сделал:
Моя конфигурация Dropwizard имеет этот appender:
appenders:
- type: console
target: stdout
layout:
type: json
timestampFormat: "ISO_INSTANT"
prettyPrint: false
appendLineSeparator: true
additionalFields:
keyOne: "value one"
keyTwo: "value two"
flattenMdc: true
Дополнительные поля отображаются, но эти значения, кажется, зафиксированы в файле конфигурации и не изменяются. Существует "customFieldNames", но нет документации о том, как его использовать, и независимо от того, что я туда вставил, я получаю сообщение об ошибке "нет конструктора аргумента строки / метод фабрики для десериализации из значения строки". (Документы имеют примерное значение "@timestamp", но без объяснения, и даже это порождает ошибку. У них также есть примеры, такие как "(requestTime:request_time, userAgent:user_agent)", но опять же, без документов, и я ничего не могу сделать аналогичная работа, все, что я пробовал, выдает ошибку выше.
Я заставил MDC работать, но кажется глупым подключать каждый элемент к MDC, а затем очищать его.
И я могу десериализовать объект и зарегистрировать его как вложенный JSON, но это также кажется странным.
Все ответы, которые я видел по этому вопросу, старые - есть ли у кого-нибудь совет, как сделать это в Dropwizard?
0 ответов
Вы можете явно использовать логбэк в Dropwizard, используя фабрику настраиваемого логгера, а затем настроить его с помощью logstash-logback-encoder и настроить его для записи в приложение JSON.
Кодировщик JSON может выглядеть так:
<included>
<encoder class="net.logstash.logback.encoder.LoggingEventCompositeJsonEncoder">
<providers>
<pattern>
<pattern>
{
"id": "%uniqueId",
"relative_ns": "#asLong{%nanoTime}",
"tse_ms": "#asLong{%tse}",
"start_ms": "#asLong{%startTime}",
"cpu": "%cpu",
"mem": "%mem",
"load": "%loadavg"
}
</pattern>
</pattern>
<timestamp>
<!-- UTC is the best server consistent timezone -->
<timeZone>${encoders.json.timeZone}</timeZone>
<pattern>${encoders.json.timestampPattern}</pattern>
</timestamp>
<version/>
<message/>
<loggerName/>
<threadName/>
<logLevel/>
<logLevelValue/><!-- numeric value is useful for filtering >= -->
<stackHash/>
<mdc/>
<logstashMarkers/>
<arguments/>
<provider class="com.tersesystems.logback.exceptionmapping.json.ExceptionArgumentsProvider">
<fieldName>exception</fieldName>
</provider>
<stackTrace>
<!--
https://github.com/logstash/logstash-logback-encoder#customizing-stack-traces
-->
<throwableConverter class="net.logstash.logback.stacktrace.ShortenedThrowableConverter">
<rootCauseFirst>${encoders.json.shortenedThrowableConverter.rootCauseFirst}</rootCauseFirst>
<inlineHash>${encoders.json.shortenedThrowableConverter.inlineHash}</inlineHash>
</throwableConverter>
</stackTrace>
</providers>
</encoder>
</included>
и произвести такой вывод:
{"id":"FfwJtsNHYSw6O0Qbm7EAAA","relative_ns":20921024,"tse_ms":1584163814965,"start_ms":null,"@timestamp":"2020-03-14T05:30:14.965Z","@version":"1","message":"Creating Pool for datasource 'logging'","logger_name":"play.api.db.HikariCPConnectionPool","thread_name":"play-dev-mode-akka.actor.default-dispatcher-7","level":"INFO","level_value":20000}