Есть ли рекомендуемый способ получить весеннюю загрузку в журналы формата JSON с logback - PullRequest
0 голосов
/ 11 декабря 2018

Используя весеннюю загрузку 2.1.1.RELEASE, можно, по-видимому, отформатировать журналы как JSON, предоставив файл logback-spring.xml следующим образом:

<appender name="stdout" class="ch.qos.logback.core.ConsoleAppender">
    <encoder class="ch.qos.logback.core.encoder.LayoutWrappingEncoder">
        <layout class="ch.qos.logback.contrib.json.classic.JsonLayout">
            <timestampFormat>yyyy-MM-dd'T'HH:mm:ss.SSSX</timestampFormat>
            <timestampFormatTimezoneId>Etc/UTC</timestampFormatTimezoneId>
            <jsonFormatter class="ch.qos.logback.contrib.jackson.JacksonJsonFormatter">
                <prettyPrint>true</prettyPrint>
            </jsonFormatter>
        </layout>
    </encoder>
</appender>

<root level="INFO">
    <appender-ref ref="stdout" />
</root>

и добавив вpom.xml

<dependency>
            <groupId>ch.qos.logback.contrib</groupId>
            <artifactId>logback-json-classic</artifactId>
            <version>0.1.5</version>
        </dependency>
        <dependency>
            <groupId>ch.qos.logback.contrib</groupId>
            <artifactId>logback-jackson</artifactId>
            <version>0.1.5</version>
        </dependency>

действительно приводит к сообщениям вроде:

{
  "timestamp" : "2018-12-11T18:20:25.641Z",
  "level" : "INFO",
  "thread" : "main",
  "logger" : "com.netflix.config.sources.URLConfigurationSource",
  "message" : "To enable URLs as dynamic configuration sources, define System property archaius.configurationSource.additionalUrls or make config.properties available on classpath.",
  "context" : "default"
}

Почему?

Я испытываю logz.io , которыйКажется, ведет себя более благоприятно, когда журналы отформатированы в JSON, некоторые грузоотправители борются с многострочными журналами, как мы видим в трассировках стека Java, и при форматировании в JSON он может автоматически анализировать поля, такие как level и message, и если есть данные MDCэто автоматически получается.

У меня был не очень хороший опыт использования нескольких методов доставки журналов в logzio, таких как их образ докера и использование rsyslog без использования сообщений журнала в формате JSON.

Проблемы с этим подходом

Работает нормально при добавлении консоли, но при весенней загрузке это похоже на logging.file=test.log, logging.level.com.example=WARN, logging.pattern.console.Я действительно могу импортировать управляемую конфигурацию из spring-boot-2.1.1.RELEASE.jar!/org/springframework/boot/logging/logback/base.xml, которая, в свою очередь, импортирует console-appender.xml and file-appender.xml`.

Пример консоли-appender

<included>
    <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
        <encoder>
            <pattern>${CONSOLE_LOG_PATTERN}</pattern>
        </encoder>
    </appender>
</included>

Примерфайла appender

<included>
    <appender name="FILE"
        class="ch.qos.logback.core.rolling.RollingFileAppender">
        <encoder>
            <pattern>${FILE_LOG_PATTERN}</pattern>
        </encoder>
        <file>${LOG_FILE}</file>
        <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
            <fileNamePattern>${LOG_FILE}.%d{yyyy-MM-dd}.%i.gz</fileNamePattern>
            <maxFileSize>${LOG_FILE_MAX_SIZE:-10MB}</maxFileSize>
            <maxHistory>${LOG_FILE_MAX_HISTORY:-0}</maxHistory>
        </rollingPolicy>
    </appender>
</included>

Это именно то, что мне нужно для поддержки весенней конфигурации свойств, но они не включают кодировщик / макет, который мне понадобится.

В моих первоначальных тестах оказалось, что я не могу просто назвать моего аппендера так же, как те, и предоставить свои макеты.Например:

<configuration>

    <include resource="org/springframework/boot/logging/logback/base.xml"/>

    <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
        <encoder class="ch.qos.logback.core.encoder.LayoutWrappingEncoder">
            <layout class="ch.qos.logback.contrib.json.classic.JsonLayout">
                <timestampFormat>yyyy-MM-dd'T'HH:mm:ss.SSSX</timestampFormat>
                <timestampFormatTimezoneId>Etc/UTC</timestampFormatTimezoneId>
                <jsonFormatter class="ch.qos.logback.contrib.jackson.JacksonJsonFormatter">
                    <prettyPrint>true</prettyPrint>
                </jsonFormatter>
            </layout>
        </encoder>
    </appender>



    <root level="INFO">
        <appender-ref ref="CONSOLE" />
    </root>
</configuration>

приводит к тому, что сообщение регистрируется как в формате JSON, так и в текстовом формате.

Я действительно могу просто скопировать и вставить содержимое этих 3 файлов в мою пользовательскую конфигурацию, а нечем импортировать их вообще.Затем я могу переопределить то, что я хочу настроить.

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

Есть ли лучший способ, которым я могу:

  • Просто вносить аддитивные изменения в дополнения, а не переопределять их полностью, например, сохранять конфигурацию веснойно предоставьте мой собственный кодер или макет для использования этими приложениями.
  • Сконфигурируйте spring для журнала JSON через свойства полностью без какой-либо конфигурации - я сомневаюсь в этом: S

Сноска: logzio предоставляет зависимость , которую можно импортировать, но мне не нравится идея связать провайдера журналирования с кодом напрямую.Я чувствую, что, если серво генерирует журналы JSON для stdout или файла, любой провайдер может легко их обработать и отправить в какой-либо пункт назначения.

1 Ответ

0 голосов
/ 16 июля 2019

Я не использую никаких зависимостей.Просто, делая это через application.yml, и все.Это решение решает проблему многострочного журнала.

logging:
  pattern:
    console: "{\"time\": \"%d\", \"level\": \"%p\", \"correlation-id\": \"%X{X-Correlation-Id}\", \"source\": \"%logger{63}:%L\", \"message\": \"%replace(%m%wEx{6}){'[\r\n]+', '\\n'}%nopex\"}%n"
...