logstash-logback-encoder: Logback JSON编码器和附加器

  |   0 评论   |   0 浏览

Logstash Logback Encoder

Build Javadocs

提供logback编码器、布局和附加器,以登录JSON和Jackson支持的其他格式。

支持常规日志事件(通过Logger记录)和访问事件(通过回写访问记录)。

最初是为了支持logstash的JSON格式的输出而编写的,但现在已经演变成了用于JSON和其他Jackson数据格式的highly-configurable、general-purpose、结构化日志机制。输出的结构及其包含的数据是完全可配置的。

Contents:

  • 将其包括在项目中
  • Java Version Requirements
  • 用法UDP附加器TCP附加器Keep-alive多个目标重新连接延迟连接超时写入缓冲区大小写入超时SSL异步附加器环缓冲区完全优雅关闭等待策略附加器侦听器编码器/布局
  • LoggingEvent字段标准字段MDC字段上下文字段调用方信息字段自定义字段全局自定义字段Event-specific自定义字段
  • AccessEvent Fields
    • Standard Fields
    • Header Fields
  • 自定义Jackson数据格式自定义JSON工厂和生成器注册Jackson模块自定义角色转义
  • Masking
  • Customizing Standard Field Names
  • Customizing Version
  • Customizing Timestamp
  • Customizing LoggingEvent Message
  • Customizing AccessEvent Message
  • Customizing Logger Name Length
  • Customizing Stack Traces
  • Prefix/Suffix/Separator
  • 复合编码器/布局提供程序通用于LoggingEvents和AccessEvents提供程序用于LoggingEvents提供程序用于AccessEvents嵌套JSON提供程序模式JSON提供程序LoggingEvent模式AccessEvent模式自定义JSON提供程序
  • Status Listeners
  • Joran/XML Configuration
    • Duration Property

将其包括在项目中

Maven style:

<dependency>
    <groupId>net.logstash.logback</groupId>
    <artifactId>logstash-logback-encoder</artifactId>
    <version>7.2</version>
    <!-- Use runtime scope if the project does not have any compile-time usage of logstash-logback-encoder,
such as usage of StructuredArguments/Markers or implementations such as
JsonProvider, AppenderListener, JsonFactoryDecorator, JsonGeneratorDecorator, etc
<scope>runtime</scope>
-->
</dependency>
<!-- Your project must also directly depend on either logback-classic or logback-access.  For example: -->
<dependency>
    <groupId>ch.qos.logback</groupId>
    <artifactId>logback-classic</artifactId>
    <version>1.2.11</version>
    <!-- Use runtime scope if the project does not have any compile-time usage of logback,
such as implementations of Appender, Encoder, Layout, TurboFilter, etc
<scope>runtime</scope>
-->
</dependency>

如果在运行时获得ClassNotFoundException/NoClassDefFoundError/NoSuchMethodError,那么请确保在运行时类路径上存在maven存储库的pom文件中指定的所需依赖项(和适当版本)。具体来说,运行时类路径上需要提供以下内容:

  • jackson-databind / jackson-core / jackson-annotations >= 2.12.0
  • logback-core >= 1.2.0
  • logback-classic>=1.2.0(记录日志事件所需)
  • logback-access>=1.2.0(记录AccessEvents时需要)
  • slf4j-api
  • java-uuid-generator(如果使用uuid提供程序,则为必需)

比pom文件中指定的版本旧的版本可能可以工作,但pom文件中的版本是测试所针对的。logstash-logback-encoder7.0中删除了对1.2.0之前版本的支持。

如果您正在一个项目(例如spring-boot)中使用logstash-logback-encoder,该项目也声明了对上述任何库的依赖关系,那么您可能需要明确地告诉maven要使用哪些版本来避免冲突。您可以使用maven的dependencyManagement特性来实现这一点。例如,为了确保maven不会选择logback-core、logback-classic和logback-access的不同版本,将其添加到项目的pom.xml中

<properties>
    <logback.version>1.2.6</logback.version>
</properties>
<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>ch.qos.logback</groupId>
            <artifactId>logback-core</artifactId>
            <version>${logback.version}</version>
        </dependency>
        <dependency>
            <groupId>ch.qos.logback</groupId>
            <artifactId>logback-classic</artifactId>
            <version>${logback.version}</version>
        </dependency>
        <dependency>
            <groupId>ch.qos.logback</groupId>
            <artifactId>logback-access</artifactId>
            <version>${logback.version}</version>
        </dependency>
    </dependencies>
</dependencyManagement>

Java Version Requirements

logstash-logback-encoderMinimum Java Version supported
>= 6.01.8
5.x1.7
<= 4.x1.6

Usage

要使用JSON格式登录,必须将logback配置为使用以下任一格式:

  • logstash-logback-encoder库提供的附加器,或
  • logback(或另一个库)提供的附加器,带有logstash-logback-encoder库提供的编码器或布局

logstash-logback-encoder库提供的附加器、编码器和布局如下:

FormatProtocolFunctionLoggingEventAccessEvent
Logstash JSONSyslog/UDPAppenderLogstashUdpSocketAppenderLogstashAccessUdpSocketAppender
Logstash JSONTCPAppenderLogstashTcpSocketAppenderLogstashAccessTcpSocketAppender
anyanyAppenderLoggingEventAsyncDisruptorAppenderAccessEventAsyncDisruptorAppender
Logstash JSONanyEncoderLogstashEncoderLogstashAccessEncoder
Logstash JSONanyLayoutLogstashLayoutLogstashAccessLayout
General JSONanyEncoderLoggingEventCompositeJsonEncoderAccessEventCompositeJsonEncoder
General JSONanyLayoutLoggingEventCompositeJsonLayoutAccessEventCompositeJsonLayout

这些编码器/布局通常可以由任何logback appender(例如RollingFileAppender)使用。

通用复合JSON编码器/布局可以通过使用各种JSON提供程序配置来输出任何JSON格式/数据。Logstash编码器/布局实际上只是一般复合JSON编码器/布局的扩展,具有pre-defined组提供程序。

如果要使用标准logstash版本1输出格式,则logstash编码器/布局更易于配置。如果您想要大量定制输出,或者如果您需要使用logstash版本0输出,请使用复合编码器/布局。

*AsyncDisruptorAppender附加器与logback的AsyncAppender类似,不同之处在于,与BlockingQueue相反,使用了LMAX中断器环缓冲区作为排队机制。这些异步附加器可以委托给任何其他底层logback附加器。

UDP Appender

要将用于记录事件的JSON输出到syslog/UDP通道,请在logback.xml中使用带有LogstashLayoutLoggingEventCompositeJsonLayoutLogstashUdpSocketAppender,如下所示:

<?xmlversion="1.0"encoding="UTF-8"?>
<configuration>
    <appender name="stash" class="net.logstash.logback.appender.LogstashUdpSocketAppender">
        <host>MyAwesomeSyslogServer</host>
        <!-- port is optional (default value shown) -->
        <port>514</port>
        <!-- layout is required -->
        <layout class="net.logstash.logback.layout.LogstashLayout"/>
    </appender>
  
    <root level="all">
        <appender-ref ref="stash" />
  </root>
</configuration>

您可以通过自定义布局来进一步自定义JSON输出,如后面部分所述。

例如,要配置全局自定义字段,可以指定

<appender name="stash" class="net.logstash.logback.appender.LogstashUdpSocketAppender">
    <host>MyAwesomeSyslogServer</host>
    <!-- port is optional (default value shown) -->
    <port>514</port>
    <layout class="net.logstash.logback.layout.LogstashLayout">
        <customFields>{"appname":"myWebservice"}</customFields>
    </layout>
</appender>

要通过UDP为AccessEvents输出JSON,请在logback-access.xml中使用带有LogstashAccessLayoutAccessEventCompositeJsonLayoutLogstashAccessUdpSocketAppender,如下所示:

<?xmlversion="1.0"encoding="UTF-8"?>
<configuration>
    <appender name="stash" class="net.logstash.logback.appender.LogstashAccessUdpSocketAppender">
        <host>MyAwesomeSyslogServer</host>
        <!-- port is optional (default value shown) -->
        <port>514</port>

        <layout class="net.logstash.logback.layout.LogstashAccessLayout">
            <customFields>{"appname":"myWebservice"}</customFields>
        </layout>
    </appender>

    <appender-ref ref="stash" />
</configuration>

要在logstash中接收syslog/UDP输入,请在logstash的配置中使用json编解码器配置syslogudp输入,如下所示:

input {
    syslog {
        codec => "json"
    }
}

TCP Appenders

要输出JSON以通过TCP记录事件,请在logback.xml中使用带有LogstashEncoderLoggingEventCompositeJsonEncoderLogstashTcpSocketAppender,如下所示:

<?xmlversion="1.0"encoding="UTF-8"?>
<configuration>
    <appender name="stash" class="net.logstash.logback.appender.LogstashTcpSocketAppender">
        <destination>127.0.0.1:4560</destination>

        <!-- encoder is required -->
        <encoder class="net.logstash.logback.encoder.LogstashEncoder" />
    </appender>

    <root level="DEBUG">
        <appender-ref ref="stash" />
    </root>
</configuration>

要通过TCP为AccessEvents输出JSON,请在logback-access.xml中使用带有LogstashAccessEncoderAccessEventCompositeJsonEncoderLogstashAccessTcpSocketAppender,如下所示:

<?xmlversion="1.0"encoding="UTF-8"?>
<configuration>
    <appender name="stash" class="net.logstash.logback.appender.LogstashAccessTcpSocketAppender">
        <destination>127.0.0.1:4560</destination>

        <!-- encoder is required -->
        <encoder class="net.logstash.logback.encoder.LogstashAccessEncoder" />
    </appender>

    <appender-ref ref="stash" />
</configuration>

TCP附加器使用编码器,而不是布局作为UDP附加器。您可以使用Logstash*Encoder*EventCompositeJsonEncoder或任何其他logback编码器。所有输出格式选项均在编码器级别配置。

在内部,TCP附加器是异步的(使用LMAX Disruptor RingBuffer)。所有编码和TCP通信都委托给单个写入程序thread。不需要用另一个异步附加器(例如AsyncAppenderLoggingEventAsyncDisruptorAppender)包装TCP附加器。

异步附加器的所有配置参数(除了sub-appender)对TCP附加器有效。例如,waitStrategyTyperingBufferSize

TCP附加程序永远不会阻止日志记录thread。如果RingBuffer已满(例如,由于网络速度较慢等),则事件将被丢弃。

如果连接中断,TCP附加器将自动重新连接。然而,在Java的套接字意识到连接已断开之前,事件可能会丢失。

要在logstash中接收TCP输入,请在logstash的配置中使用json_lines编解码器配置tcp输入,如下所示:

input {
    tcp {
        port => 4560
            codec => json_lines
    }
}

为了保证记录的消息有机会被TCP appender处理,您需要在应用程序退出时完全关闭logback。

Keep-Alive

如果事件不经常发生,并且由于server-side空闲超时而导致连接持续中断,则可以通过如下配置keepAliveDuration来启用保持活动功能:

<appender name="stash" class="net.logstash.logback.appender.LogstashTcpSocketAppender">
    ...
    <keepAliveDuration>5 minutes</keepAliveDuration>
</appender>

此设置接受回登录持续时间值-有关有效值的更多信息,请参阅“持续时间属性”部分。

当设置keepAliveDuration时,如果事件在持续时间内未发生,则将发送保持活动的消息。keep-alive消息默认为unix行结束(\n),但可以通过将keepAliveMessage属性设置为所需的值来更改。以下值具有特殊含义:

  • <empty string>:不,继续
  • SYSTEM:系统的行分隔符
  • UNIX:unix行结束(\n
  • WINDOWS:windows行结束(\r\n

将使用任何其他值as-is。

默认情况下,keep-alive消息编码为UTF-8。这可以通过将keepAliveCharset属性设置为所需字符集的名称来改变。

Multiple Destinations

TCP附加器可以配置为尝试连接到以下几个目的地之一:

<appender name="stash" class="net.logstash.logback.appender.LogstashTcpSocketAppender">
    <destination>destination1.domain.com:4560</destination>
    <destination>destination2.domain.com:4560</destination>
    <destination>destination3.domain.com:4560</destination>

    ...
</appender>

or this:

<appender name="stash" class="net.logstash.logback.appender.LogstashTcpSocketAppender">
    <destination>
        destination1.domain.com:4560,
        destination2.domain.com:4560,
        destination3.domain.com:4560
    </destination>

    ...
</appender>

appender使用connectionStrategy来确定:

  • 尝试目标连接的顺序,以及
  • 何时应重新建立已建立的连接(到连接策略选择的下一个目的地)。

日志一次只发送到一个目的地(即并非所有目的地)。默认情况下,appender将保持与连接的目标的连接,直到其中断或应用程序关闭。一些连接策略可以强制重新连接(见下文)。如果连接中断,则附加器将尝试连接到连接策略选择的下一个目标。

可用的连接策略如下:

StrategyDescription
preferPrimary(默认)第一个目的地被视为主要目的地。每个附加目的地都被视为次要目的地。这种策略更倾向于主要目的地,除非它停止。appender将尝试按配置顺序连接到每个目标。如果连接尝试失败,附加器将尝试连接到下一个目标。如果连接成功,然后在minConnectionTimeBeforePrimary运行之前关闭,则附加器将尝试连接到下一个目标。如果连接成功,然后在minConnectionTimeBeforePrimary运行后关闭,则附加器将尝试按照配置顺序连接到目标,从第一个/主要目标开始。SecondaryConnectionTL可以设置为在特定的持续时间后优雅地关闭到辅助目的地的连接。这将迫使附加器重新尝试按顺序连接到目标。SecondaryConnectionTL值不影响到主目标的连接。minConnectionTimeBeforePrimary(默认情况下为10秒)指定在下一次连接尝试尝试尝试主连接之前,成功建立的连接必须保持打开状态的最短时间。i、 e.如果连接保持打开的时间少于此时间,则下一次连接尝试将尝试下一个目标(而不是主目标)。这用于在主设备接受连接,然后立即关闭连接的情况下,防止与主设备的连接风暴。示例:<appender name="stash" class="net.logstash.logback.appender.LogstashTcpSocketAppender"> <destination>destination1.domain.com:4560</destination> <destination>destination2.domain.com:4560</destination> <destination>destination3.domain.com:4560</destination> <connectionStrategy> <preferPrimary> <secondaryConnectionTTL>5 minutes</secondaryConnectionTTL> </preferPrimary> </connectionStrategy> </appender>
roundRobin该策略尝试以循环顺序连接到目标。如果连接失败,则尝试下一个目标。ConnectionTL可以设置为在特定持续时间后优雅地关闭连接。这将迫使附加器重新尝试连接到下一个目标。示例:<appender name="stash" class="net.logstash.logback.appender.LogstashTcpSocketAppender"> <destination>destination1.domain.com:4560</destination> <destination>destination2.domain.com:4560</destination> <destination>destination3.domain.com:4560</destination> <connectionStrategy> <roundRobin> <connectionTTL>5 minutes</connectionTTL> </roundRobin> </connectionStrategy> </appender>
random该策略尝试以随机顺序连接到目标。如果连接失败,则尝试下一个随机目标。ConnectionTL可以设置为在特定持续时间后优雅地关闭连接。这将迫使附加器重新尝试连接到下一个随机目标。示例:<appender name="stash" class="net.logstash.logback.appender.LogstashTcpSocketAppender"> <destination>destination1.domain.com:4560</destination> <destination>destination2.domain.com:4560</destination> <destination>destination3.domain.com:4560</destination> <connectionStrategy> <random> <connectionTTL>5 minutes</connectionTTL> </random> </connectionStrategy> </appender>

您还可以通过实现DestinationConnectionStrategy接口并配置appender来使用自己的自定义连接策略,如下所示:

<appender name="stash" class="net.logstash.logback.appender.LogstashTcpSocketAppender">
    <destination>destination1.domain.com:4560</destination>
    <destination>destination2.domain.com:4560</destination>
    <destination>destination3.domain.com:4560</destination>
    <connectionStrategy class="your.package.YourDestinationConnectionStrategy">
    </connectionStrategy>
</appender>

Reconnection Delay

默认情况下,TCP appender将在与单个目标的连接尝试之间等待30秒。分别跟踪到每个目标的连接尝试之间的时间。

可以通过设置reconnectionDelay字段来更改延迟时间。

<appender name="stash" class="net.logstash.logback.appender.LogstashTcpSocketAppender">
    ...
    <reconnectionDelay>1 second</reconnectionDelay>
</appender>

此设置接受回登录持续时间值-有关有效值的更多信息,请参阅“持续时间属性”部分。

Connection Timeout

默认情况下,连接到远程目标时使用5秒的连接超时。您可以通过将appender的connectionTimeout配置属性设置为所需的值来进行调整。

<appender name="stash" class="net.logstash.logback.appender.LogstashTcpSocketAppender">
    ...
    <connectionTimeout>5 seconds</connectionTimeout>
</appender>

0意味着“不要使用超时并无限期等待”,这通常意味着“使用操作系统默认值”。

此设置接受回登录持续时间值-有关有效值的更多信息,请参阅“持续时间属性”部分。

Write Buffer Size

默认情况下,缓冲区大小8192用于缓冲套接字输出流写入。您可以通过设置附加器的writeBufferSize来调整这一点。

<appender name="stash" class="net.logstash.logback.appender.LogstashTcpSocketAppender">
    ...
    <writeBufferSize>16384</writeBufferSize>
</appender>

通过将writeBufferSize设置为0,可以禁用缓冲。如果担心因连接不牢固而丢失缓冲区中的数据,请考虑禁用写缓冲区。由于系统调用增加,禁用缓冲区可能会降低写入程序thread的速度,但在某些环境中,这似乎不会影响整体性能。请参阅此讨论。

Write Timeouts

如果目标停止从其套接字输入读取数据,但未关闭连接,则来自TCP附加器的写入最终将进行备份,从而导致环形缓冲区进行备份,从而导致事件被丢弃。

为了检测这种情况,您可以启用写入超时,这样“卡住”的写入最终将超时,此时连接将为re-established。启用写入缓冲区后,重新建立连接时,任何缓冲数据都将丢失。

默认情况下,没有写入超时。要启用写入超时,请执行以下操作:

<appender name="stash" class="net.logstash.logback.appender.LogstashTcpSocketAppender">
    ...
    <writeTimeout>1 minute</writeTimeout>
</appender>

注意,由于用于发送事件的阻塞java套接字输出流没有写入超时的概念,因此使用与写入超时频率相同的定期调度任务来检测写入超时。例如,如果写入超时设置为30秒,则每30秒执行一次任务,以查看自当前写入操作开始以来是否已过30秒。因此,建议使用更长的写入超时(例如>30s或分钟),而不是较短的写入超时,以便此任务不会执行得太频繁。此外,这种方法意味着在检测到写入超时之前,可能需要两倍的写入超时。

写入超时必须大于0。零超时被解释为无限超时,有效地表示“无写入超时”。

此设置接受回登录持续时间值-有关有效值的更多信息,请参阅“持续时间属性”部分。

SSL

要使用SSL,请在LogstashTcpSocketAppenderLogstashAccessTcpSocketAppender<appender>元素内添加一个<ssl>sub-element。

有关如何配置SSL,请参阅logback手册。Logstash*TcpSocketAppender的SSL配置方式与logback的SSLSocketAppender相同。

例如,要使用JVM的默认密钥库/信任库启用SSL,请执行以下操作:

<appender name="stash" class="net.logstash.logback.appender.LogstashTcpSocketAppender">
    ...

    <!-- Enable SSL using the JVM's default keystore/truststore -->
    <ssl/>
</appender>

要使用不同的信任库,请执行以下操作:

<appender name="stash" class="net.logstash.logback.appender.LogstashAccessTcpSocketAppender">
    ...

    <!-- Enable SSL and use a different truststore -->
    <ssl>
        <trustStore>
            <location>classpath:server.truststore</location>
            <password>${server.truststore.password}</password>
        </trustStore>
    </ssl>
</appender>

logback提供的所有定制(例如配置密码规范、协议、算法、提供者等)都受Logback*TcpSocketAppender支持。

请参阅tcp输入的logstash文档,了解如何将其配置为使用SSL。

Async Appenders

*AsyncDisruptorAppender附加器与logback的AsyncAppender类似,不同之处在于,与BlockingQueue相反,使用了LMAX中断器环缓冲区作为排队机制。这些异步附加器可以委托给任何其他底层logback附加器。

For example:

<appender name="async" class="net.logstash.logback.appender.LoggingEventAsyncDisruptorAppender">
    <appender class="ch.qos.logback.core.rolling.RollingFileAppender">
        ...
    </appender>
</appender>

RingBuffer Full

默认情况下,异步附加器不会阻止日志记录thread。如果RingBuffer已满(例如,由于网络速度较慢等),则事件将被丢弃。

或者,您可以将appender配置为等待空间可用,而不是立即删除事件。当您希望依赖appender的缓冲和异步特性,但不希望在出现超过RingBuffer大小的大型日志突发时丢失任何事件时,这可能会很有用。

当环形缓冲区由appendTimeout配置属性控制时,追加器的行为:

appendTimeoutBehaviour when RingBuffer is full
< 0禁用超时并等待空间可用
0没有超时,立即放弃并删除事件(这是默认设置)
> 0在指定的时间内重试

等待环缓冲区中空间的日志记录threads以从1ns开始的频率周期性地唤醒,并以指数形式增加到appendRetryFrequency(默认值5ms)。一次只允许一个thread重试。如果一个thread已经在重试,其他threads正在等待一个锁,直到第一个锁完成。当环形缓冲区处于(或接近)其最大容量时,该策略应有助于限制CPU消耗,同时提供足够的延迟和吞吐量。

当appender删除事件时,它会每隔droppedWarnFrequency个连续删除的事件发出一条警告状态消息。当丢弃周期结束并且第一个事件成功排队时,会发出另一条状态消息,报告丢弃的事件总数。

Graceful Shutdown

为了保证记录的消息有机会被异步附加器(包括TCP附加器)处理,并确保后台threads已停止,您需要在应用程序退出时完全关闭logback。

当正常停止时,异步附加器将等待,直到缓冲区中的所有事件都得到处理并且缓冲区为空。等待的最长时间由shutdownGracePeriod参数配置,默认设置为1 minute。在此时间段结束后,仍在缓冲区中的事件将被删除,并且appender将停止。

Wait Strategy

默认情况下,BlockingWaitStrategy由这个appender生成的workerBlockingWaitStrategy使用。BlockingWaitStrategy最小化了CPU利用率,但导致延迟和吞吐量较慢。如果您需要更快的延迟和吞吐量(以更高的CPU利用率为代价),请考虑由中断器提供的不同等待策略。

!! 无论选择哪种等待策略,一定要测试和监视CPU利用率、延迟和吞吐量,以确保其满足您的需求。例如,在某些配置中,SleepingWaitStrategy可以在静止状态下消耗90%的CPU利用率。

可以使用waitStrategyType参数在异步附加器上配置等待策略,如下所示:

<appender name="async" class="net.logstash.logback.appender.LoggingEventAsyncDisruptorAppender">
    <waitStrategyType>sleeping</waitStrategyType>
    <appender class="ch.qos.logback.core.rolling.RollingFileAppender">
        ...
    </appender>
</appender>

支持的等待策略如下:

Wait StrategyParametersImplementation
blockingnoneBlockingWaitStrategy
busySpinnoneBusySpinWaitStrategy
liteBlockingnoneLiteBlockingWaitStrategy
yieldingnoneYieldingWaitStrategy
sleeping{<span> </span><em>retries</em>,<span> </span><em>sleepTimeNs</em><span> </span>}<span> </span>例如睡觉或睡觉{5001000}retries-睡眠前旋转的次数(整数)。(默认值=200)sleepTimeNs-旋转后每次迭代的睡眠时间(以纳秒为单位)(默认值=100)SleepingWaitStrategy
phasedBackoff{<span> </span><em>spinTime</em>,<span> </span><em>yieldTime</em>,<span> </span><em>timeUnit</em>,<span> </span><em>fallbackStrategy</em><span> </span>}<span> </span>例如phasedBackoff{10,60,秒,阻塞}自旋时间-在产生yieldTime之前的自旋时间-在回落到fallbackStrategy Time之前的屈服时间单位-自旋和屈服超时的时间单位。时间单位值的字符串名称(例如秒)fallbackStrategy-超时结束后要回退的等待策略的字符串名称PhasedBackoffWaitStrategy
timeoutBlocking{<span> </span><em>timeout</em>,<span> </span><em>timeUnit</em><span> </span>}<span> </span>例如超时阻塞{1,分钟}timeout—引发异常之前的阻止时间timeUnit—超时的时间单位。时间单位值的字符串名称(例如秒)TimeoutBlockingWaitStrategy
liteTimeoutBlocking{<span> </span><em>timeout</em>,<span> </span><em>timeUnit</em><span> </span>}<span> </span>例如liteTimeoutBlocking{1,分钟}timeout—引发异常之前的阻止时间timeUnit—超时的时间单位。时间单位值的字符串名称(例如秒)LiteTimeoutBlockingWaitStrategy

有关其他配置参数(如ringBufferSizethreadNamePrefixdaemondroppedWarnFrequency),请参阅AsyncDisruptraPender

Appender Listeners

监听器可以注册到appender,以接收appender生命周期和事件处理的通知。

有关可以接收的通知类型,请参阅两个侦听器接口:

  • AppenderListener-异步附加器和udp附加器的基本通知。
  • TcpAppenderListener-扩展AppenderListener,并附加TCP-specific通知。仅适用于TCP附加器。

侦听器的一些示例用例包括:

  • 监控每秒事件数、事件处理持续时间、丢弃的事件、连接成功/失败等指标。
  • 将事件处理错误记录到不同的附加器(可能附加到不同的目标)。

提供了一个FailureSummaryLoggingAppenderListener,它将在一系列连续的追加/发送/连接失败后第一次成功时记录警告。该消息包括发生的故障的摘要详细信息(例如故障数、故障持续时间等)。要注册它:

<appender name="stash" class="net.logstash.logback.appender.LogstashAccessTcpSocketAppender">
    <listener class="net.logstash.logback.appender.listener.FailureSummaryLoggingAppenderListener">
        <loggerName>net.logstash.logback.appender.listener.FailureSummaryLoggingAppenderListener</loggerName>
    </listener>
</appender>

您还可以通过实现*Listener接口来创建自己的侦听器,并使用listenerxml元素将其注册到appender,如下所示:

<appender name="stash" class="net.logstash.logback.appender.LogstashAccessTcpSocketAppender">
    ...

    <listener class="your.package.YourListenerClass">
        <yourListenerProperty>propertyValue</yourListenerProperty>
    </listener>
</appender>

通过提供多个listenerxml元素,可以注册多个侦听器。

编码器/布局

您可以将logstash-logback-encoder库提供的任何编码器/布局与其他logback appender一起使用。

例如,要将LoggingEvents输出到文件,请在logback.xml中使用LogstashEncoderRollingFileAppender,如下所示:

<?xmlversion="1.0"encoding="UTF-8"?>
<configuration>
    <appender name="stash" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
            <level>info</level>
        </filter>
        <file>/some/path/to/your/file.log</file>
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <fileNamePattern>/some/path/to/your/file.log.%d{yyyy-MM-dd}</fileNamePattern>
            <maxHistory>30</maxHistory>
        </rollingPolicy>
        <encoder class="net.logstash.logback.encoder.LogstashEncoder" />
    </appender>
  
    <root level="all">
        <appender-ref ref="stash" />
    </root>
</configuration>

要将AccessEvents记录到文件中,请按如下方式配置logback-access.xml

<?xmlversion="1.0"encoding="UTF-8"?>
<configuration>
    <appender name="stash" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>/some/path/to/your/file.log</file>
        <encoder class="net.logstash.logback.encoder.LogstashAccessEncoder" />
    </appender>

    <appender-ref ref="stash" />
</configuration>

LogstashLayoutLogstashAccessLayout的配置方式与LogstashEncoderLogstashAccessEncoder相同。本文中的所有其他示例都使用编码器,但同样的选项也适用于布局。

要在logstash中接收文件输入,请在logstash的配置中配置file输入,如下所示:

input {
    file {
        path => "/some/path/to/your/file.log"
        codec => "json"
    }
}

LoggingEvent Fields

以下部分描述了默认情况下JSON输出中包含的字段,用于记录由

  • LogstashEncoder
  • LogstashLayout, and
  • logstash appenders

如果您使用的是复合编码器/布局,则写入的字段将因您配置的提供程序而异。

Standard Fields

除非另有说明,否则这些字段将出现在每个日志事件中。此处列出的字段名是默认字段名。可以自定义字段名(请参见自定义标准字段名)。

FieldDescription
@timestamp日志事件的时间(yyyy-MM-dd'T'HH:mm:ss.SSSZZ)-请参阅自定义时间戳
@version日志格式版本(例如1)-请参阅自定义版本
message事件的格式化日志消息-请参阅自定义消息
logger_name记录事件的记录器的名称
thread_name记录事件的thread的名称
level事件级别的字符串名称
level_value事件级别的整数值
stack_trace(仅当记录了可丢弃文件时)可丢弃文件的堆栈跟踪。堆叠框架由行尾分隔。
tags(仅当找到标记时)未明确处理的任何标记的名称。(例如,来自MarkerFactory.getMarker的标记将被包括为标记,但来自Markers的标记将不会。)这可以通过在编码器/布局/附加器配置中指定<includeTags>false</includeTags>来完全禁用。

MDC fields

默认情况下,映射诊断上下文(MDC)(org.slf4j.MDC)中的每个条目将在LoggingEvent中显示为一个字段。

这可以通过在编码器/布局/附加器配置中指定<includeMdc>false</includeMdc>来完全禁用。

您还可以将MDC中的特定条目配置为包括或排除,如下所示:

<encoder class="net.logstash.logback.encoder.LogstashEncoder">
    <includeMdcKeyName>key1ToInclude</includeMdcKeyName>
    <includeMdcKeyName>key2ToInclude</includeMdcKeyName>
</encoder>

or

<encoder class="net.logstash.logback.encoder.LogstashEncoder">
    <excludeMdcKeyName>key1ToExclude</excludeMdcKeyName>
    <excludeMdcKeyName>key2ToExclude</excludeMdcKeyName>
</encoder>

当指定要包含的关键字名称时,所有其他字段都将被排除在外。当指定要排除的键名称时,将包括所有其他字段。指定包含和排除的键名是配置错误。

默认情况下,MDC键用作输出中的字段名。要在MDC条目的输出中使用替代字段名,请指定<mdcKeyFieldName>mdcKeyName=fieldName</mdcKeyFieldName>

<encoder class="net.logstash.logback.encoder.LogstashEncoder">
    <mdcKeyFieldName>key1=alternateFieldNameForKey1</mdcKeyFieldName>
</encoder>

Context fields

默认情况下,Logback上下文(ch.qos.logback.core.Context)的每个属性将在LoggingEvent中显示为一个字段。这可以通过在编码器/布局/附加器配置中指定<includeContext>false</includeContext>来禁用。

注意,1.1.10之前的回写版本默认情况下在上下文中包含HOSTNAME属性。从logback1.1.10开始,HOSTNAME属性是延迟计算的(参见logback-1221),默认情况下不再包括在内。

Caller Info Fields

默认情况下,编码器/布局/附加器不包含调用方信息。这一计算成本很高,在繁忙的生产环境中应关闭。

要打开它,请将includeCallerData属性添加到配置中。

<encoder class="net.logstash.logback.encoder.LogstashEncoder">
    <includeCallerData>true</includeCallerData>
</encoder>

如果编码器包含在异步附加器中,例如AsyncAppenderLoggingEventAsyncDisruptorAppender、或LogstashTcpSocketAppender,那么附加器上的includeCallerData也必须设置为true。

打开后,日志事件中将包括以下字段:

FieldDescription
caller_class_name记录事件的类的完全限定类名
caller_method_name记录事件的方法的名称
caller_file_name记录事件的文件的名称
caller_line_number记录事件的文件的行号

Custom Fields

除了上面的字段之外,您可以全局地或在event-by-event的基础上向LoggingEvent添加其他字段。

Global Custom Fields

添加将出现在每个LoggingEvent中的自定义字段,如下所示:

<encoder class="net.logstash.logback.encoder.LogstashEncoder">
    <customFields>{"appname":"myWebservice","roles":["customerorder","auth"],"buildinfo":{"version":"Version 0.1.0-SNAPSHOT","lastcommit":"75473700d5befa953c45f630c6d9105413c16fe1"}}</customFields>
</encoder>

或者在这样的AccessEvent中:

<encoder class="net.logstash.logback.encoder.LogstashAccessEncoder">
    <customFields>{"appname":"myWebservice","roles":["customerorder","auth"],"buildinfo":{"version":"Version 0.1.0-SNAPSHOT","lastcommit":"75473700d5befa953c45f630c6d9105413c16fe1"}}</customFields>
</encoder>

Event-specific Custom Fields

在记录消息时,可以使用以下命令向JSON输出中添加其他字段:

  • StructuredArguments提供的结构化参数,或
  • Markers提供的标记

两者的区别在于

  • StructuredArguments包含在日志事件的格式化消息(当消息具有参数时)和JSON输出中。如果使用LogstashEncoder/Layout或使用带有arguments提供程序的复合编码器/布局,则StructuredArguments将包含在JSON输出中。
  • Markers只写入JSON输出,从不写入日志事件的格式化消息。如果使用LogstashEncoder/Layout或使用带有logstashMarkers提供程序的复合编码器/布局,则Markers将包含在JSON输出中。

即使消息不包含参数,也可以使用StructuredArguments。然而,在这种情况下,参数只会写入JSON输出,而不会写入格式化消息(实际上与标记提供的行为相同)。通常,您应该使用StructuredArguments,除非您有一个标记参数计数/参数计数不匹配的静态分析器。

StructuredArgumentsMarkers都需要构造额外的对象。因此,最好用logger.isXXXEnabled()包围日志行,以避免在禁用日志级别时构建对象。

使用StructuredArguments的示例:

import static net.logstash.logback.argument.StructuredArguments.*;

/*
* Add "name":"value" to the JSON output,
* but only add the value to the formatted message.
*
* The formatted message will be `log message value`
*/
logger.info("log message {}", value("name", "value"));

/*
* Add "name":"value" to the JSON output,
* and add name=value to the formatted message.
*
* The formatted message will be `log message name=value`
*/
logger.info("log message {}", keyValue("name", "value"));

/*
* Add "name":"value" ONLY to the JSON output.
*
* Since there is no parameter for the argument,
* the formatted message will NOT contain the key/value.
*
* If this looks funny to you or to static analyzers,
* consider using Markers instead.
*/
logger.info("log message", keyValue("name", "value"));

/*
* Add multiple key value pairs to both JSON and formatted message
*/
logger.info("log message {} {}", keyValue("name1", "value1"), keyValue("name2", "value2")));

/*
* Add "name":"value" to the JSON output and
* add name=[value] to the formatted message using a custom format.
*/
logger.info("log message {}", keyValue("name", "value", "{0}=[{1}]"));

/*
* In the JSON output, values will be serialized by Jackson's ObjectMapper.
* In the formatted message, values will follow the same behavior as logback
* (formatting of an array or if not an array `toString()` is called).
*
* Add "foo":{...} to the JSON output and add `foo.toString()` to the formatted message:
*
* The formatted message will be `log message <result of foo.toString()>`
*/
Foo foo  = new Foo();
logger.info("log message {}", value("foo", foo));

/*
* Add "name1":"value1","name2":"value2" to the JSON output by using a Map,
* and add `myMap.toString()` to the formatted message.
*
* Note the values can be any object that can be serialized by Jackson's ObjectMapper
* (e.g. other Maps, JsonNodes, numbers, arrays, etc)
*/
Map myMap = new HashMap();
myMap.put("name1", "value1");
myMap.put("name2", "value2");
logger.info("log message {}", entries(myMap));

/*
* Add "array":[1,2,3] to the JSON output,
* and array=[1,2,3] to the formatted message.
*/
logger.info("log message {}", array("array", 1, 2, 3));

/*
* Add fields of any object that can be unwrapped by Jackson's UnwrappableBeanSerializer to the JSON output.
* i.e. The fields of an object can be written directly into the JSON output.
* This is similar to the @JsonUnwrapped annotation.
*
* The formatted message will contain `myobject.toString()`
*/
logger.info("log message {}", fields(myobject));

/*
* In order to normalize a field object name, static helper methods can be created.
* For example:
*     public static StructuredArgument foo(Foo foo) {
*         return StructuredArguments.value("foo", foo);
*     }
*/
logger.info("log message {}", foo(foo));

简化方便方法适用于所有结构化参数类型。例如,您可以使用kv(key, value),而不是keyValue(key, value)

使用Markers的示例:

import static net.logstash.logback.marker.Markers.*;

/*
* Add "name":"value" to the JSON output.
*/
logger.info(append("name", "value"), "log message");

/*
* Add "name1":"value1","name2":"value2" to the JSON output by using multiple markers.
*/
logger.info(append("name1", "value1").and(append("name2", "value2")), "log message");

/*
* Add "name1":"value1","name2":"value2" to the JSON output by using a map.
*
* Note the values can be any object that can be serialized by Jackson's ObjectMapper
* (e.g. other Maps, JsonNodes, numbers, arrays, etc)
*/
Map myMap = new HashMap();
myMap.put("name1", "value1");
myMap.put("name2", "value2");
logger.info(appendEntries(myMap), "log message");

/*
* Add "array":[1,2,3] to the JSON output
*/
logger.info(appendArray("array", 1, 2, 3), "log message");

/*
* Add "array":[1,2,3] to the JSON output by using raw json.
* This allows you to use your own json seralization routine to construct the json output
*/
logger.info(appendRaw("array", "[1,2,3]"), "log message");

/*
* Add any object that can be serialized by Jackson's ObjectMapper
* (e.g. Maps, JsonNodes, numbers, arrays, etc)
*/
logger.info(append("object", myobject), "log message");

/*
* Add fields of any object that can be unwrapped by Jackson's UnwrappableBeanSerializer.
* i.e. The fields of an object can be written directly into the json output.
* This is similar to the @JsonUnwrapped annotation.
*/
logger.info(appendFields(myobject), "log message");

AccessEvent Fields

以下各节描述了默认情况下JSON输出中包含的字段,这些字段是由

  • LogstashAccessEncoder,
  • LogstashAccessLayout, and
  • logstash访问附加器。

如果您使用的是复合编码器/布局,则写入的字段将因您配置的提供程序而异。

Standard Fields

除非另有说明,否则这些字段将出现在每个AccessEvent中。此处列出的字段名是默认字段名。可以自定义字段名(请参见自定义标准字段名)。

FieldDescription
@timestamp日志事件的时间。(yyyy-MM-dd'T'HH:mm:ss.SSSZZ)请参阅自定义时间戳。
@versionLogstash格式版本(例如1)请参阅自定义版本。
message形式为${remoteHost} - ${remoteUser} [${timestamp}] "${requestUrl}" ${statusCode} ${contentLength}的消息
methodHTTP method
protocolHTTP protocol
status_codeHTTP状态代码
requested_urlRequest URL
requested_uriRequest URI
remote_hostRemote host
remote_userRemote user
content_lengthContent length
elapsed_time已用时间(毫秒)

Header Fields

默认情况下,不会记录请求和响应标头,但可以通过为其指定字段名来启用,如下所示:

<encoder class="net.logstash.logback.encoder.LogstashAccessEncoder">
    <fieldNames>
        <requestHeaders>request_headers</requestHeaders>
        <responseHeaders>response_headers</responseHeaders>
    </fieldNames>
</encoder>

有关详细信息,请参见自定义标准字段名)。

要以小写形式写入头名称(以便只按大小写不同的头名称被视为相同),请将lowerCaseFieldNames设置为true,如下所示:

<encoder class="net.logstash.logback.encoder.LogstashAccessEncoder">
    <fieldNames>
        <requestHeaders>request_headers</requestHeaders>
        <responseHeaders>response_headers</responseHeaders>
    </fieldNames>
    <lowerCaseHeaderNames>true</lowerCaseHeaderNames>
</encoder>

可以通过将requestHeaderFilter和/或responseHeaderFilter配置为HeaderFilter,例如IncludeExcludeHeaderFilter,来过滤标头。

IncludeExcludeHeaderFilter可以这样配置:

<encoder class="net.logstash.logback.encoder.LogstashAccessEncoder">
    <fieldNames>
        <requestHeaders>request_headers</requestHeaders>
    </fieldNames>
    <requestHeaderFilter>
        <include>Content-Type</include>
    </requestHeaderFilter>
</encoder>

通过如下指定过滤器类,可以使用实现HeaderFilter的自定义过滤器:

<requestHeaderFilter class="your.package.YourFilterClass"/>

Customizing Jackson

Logstash-logback-encoder使用Jackson对日志进行编码并访问事件。

Logstash-logback-encoder为Jackson提供了合理的默认值,但可以完全控制Jackson配置。

例如,您可以:

  • 指定数据格式
  • 自定义JsonFactoryJsonGenerator
  • 注册jackson模块
  • 配置字符转义

Data Format

默认情况下使用JSON,但也可以使用Jackson支持的其他数据格式。

  • 文本数据格式
  • 二进制数据格式

⚠️ 当使用non-JSON数据格式时,必须在运行时类路径上包括适当的jackson dataformat库,通常通过maven/gradle依赖项(例如,对于Smile,包括jackson-dataformat-smile)。

为以下数据格式提供了装饰器:

  • cbor - CborJsonFactoryDecorator
  • smile - SmileJsonFactoryDecorator
  • yaml - YamlJsonFactoryDecorator

要使用这些格式之一,请如下指定<jsonFactoryDecorator>

<encoder class="net.logstash.logback.encoder.LogstashEncoder">
    <jsonFactoryDecorator class="net.logstash.logback.decorate.smile.SmileJsonFactoryDecorator"/>
</encoder>

其他数据格式可以通过实现自定义net.logstash.logback.decorate.JsonFactoryDecorator来使用。

以下装饰器可用于配置data-format-specific生成器功能:

  • SmileFeatureJsonGeneratorDecorator
  • CborFeatureJsonGeneratorDecorator
  • YamlFeatureJsonGeneratorDecorator

For example:

<encoder class="net.logstash.logback.encoder.LogstashEncoder">
    <jsonFactoryDecorator class="net.logstash.logback.decorate.smile.SmileJsonFactoryDecorator"/>
    <jsonGeneratorDecorator class="net.logstash.logback.decorate.smile.SmileFeatureJsonGeneratorDecorator">
        <disable>WRITE_HEADER</disable>
    </jsonGeneratorDecorator>
</encoder>

自定义JSON工厂和生成器

用于写入输出的JsonFactoryJsonGenerator可以通过以下实例进行自定义:

  • JsonFactoryDecorator
  • JsonGeneratorDecorator

例如,可以使用PrettyPrintingJsonGeneratorDecorator启用漂亮打印

或者像这样自定义对象映射:

public class ISO8601DateDecorator implements JsonFactoryDecorator  {

    @Override
    public JsonFactory decorate(JsonFactory factory) {
        ObjectMapper codec = (ObjectMapper) factory.getCodec();
        codec.setDateFormat(new ISO8601DateFormat());
        return factory;
    }
}

然后在logback.xml文件中指定装饰器,如下所示:

<encoder class="net.logstash.logback.encoder.LogstashEncoder">
    <jsonGeneratorDecorator class="net.logstash.logback.decorate.PrettyPrintingJsonGeneratorDecorator"/>
    <jsonFactoryDecorator class="your.package.ISO8601DateDecorator"/>
</encoder>

JsonFactoryJsonGenerator特性可以分别通过使用FeatureJsonFactoryDecoratorFeatureJsonGeneratorDecorator启用/禁用。例如:

<encoder class="net.logstash.logback.encoder.LogstashEncoder">
    <jsonFactoryDecorator class="net.logstash.logback.decorate.FeatureJsonFactoryDecorator">
        <disable>USE_THREAD_LOCAL_FOR_BUFFER_RECYCLING</disable>
    </jsonFactoryDecorator>
    <jsonGeneratorDecorator class="net.logstash.logback.decorate.FeatureJsonGeneratorDecorator">
        <enable>WRITE_NUMBERS_AS_STRINGS</enable>
    </jsonGeneratorDecorator>
</encoder>

请参阅net.logstash.logback.decorate包和sub-packages了解其他装饰器。

Registering Jackson Modules

默认情况下,Jackson模块通过ObjectMapper.findAndRegisterModules()动态注册。

因此,您只需要将jackson模块(例如jackson-datatype-jdk8)添加到类路径中,它们将被动态注册。

要禁用自动发现,请在编码器/布局上设置<findAndRegisterJacksonModules>false</findAndRegisterJacksonModules>

如果您有一个Jackson无法动态发现的模块,您可以通过JsonFactoryDecorator手动注册它。

Customizing Character Escapes

默认情况下,当字符串作为JSON字符串值写入时,JSON字符串中不允许的任何字符都将被转义。例如,换行符(ASCII 10)将转义为\n

要自定义这些转义序列,请使用net.logstash.logback.decorate.CharacterEscapesJsonFactoryDecorator

例如,如果要使用\n以外的内容作为换行符的转义序列,可以执行以下操作:

<encoder class="net.logstash.logback.encoder.LogstashEncoder">
    <jsonFactoryDecorator class="net.logstash.logback.decorate.CharacterEscapesJsonFactoryDecorator">
        <escape>
            <targetCharacterCode>10</targetCharacterCode>
            <escapeSequence>\u2028</escapeSequence>
        </escape>
    </jsonFactoryDecorator>
</encoder>

您还可以通过在CharacterEscapesJsonFactoryDecorator上指定<includeStandardAsciiEscapesForJSON>false</includeStandardAsciiEscapesForJSON>来禁用所有默认转义序列。如果这样做,则需要为JSON字符串值中非法的每个字符注册自定义转义。否则,可能会写入无效的JSON。

Masking

MaskingJsonGeneratorDecorator可用于掩盖敏感值(例如个人识别信息(PII)或财务数据)。

要屏蔽的数据可以通过路径和/或值来识别。

通过路径识别要屏蔽的字段值

可以通过多种方式指定要屏蔽的字段路径,如以下示例所示:

<encoder class="net.logstash.logback.encoder.LogstashEncoder">
    <jsonGeneratorDecorator class="net.logstash.logback.mask.MaskingJsonGeneratorDecorator">
  
        <!-- The default mask string can optionally be specified by <defaultMask>.
When the default mask string is not specified, **** is used.
-->
        <defaultMask>****</defaultMask>
      
        <!-- Field paths to mask added via <path> will use the default mask string -->
        <path>singleFieldName</path>
        <path>/absolute/path/to/mask</path>
        <path>partial/path/to/mask</path>
        <path>partial/path/with/*/wildcard</path>
        <path>tilde~0slash~1escapedPath</path>
      
        <!-- Multiple field paths can be specified as a comma separated string in the <paths> element. -->
        <paths>path1,path2,path3</paths>
      
        <!-- Field paths to mask added via <pathMask> can use a non-default mask string -->
        <pathMask>
            <path>some/path</path>
            <path>some/other/path</path>
            <mask>[masked]</mask>
        </pathMask>
        <pathMask>
            <paths>anotherFieldName,anotherFieldName2</paths>
            <mask>**anotherCustomMask**</mask>
        </pathMask>
      
        <!-- Field paths to mask can be supplied dynamically with an implementation
of MaskingJsonGeneratorDecorator.PathMaskSupplier
-->
        <pathMaskSupplier class="your.custom.PathMaskSupplierA"/>
      
        <!-- Custom implementations of net.logstash.logback.mask.FieldMasker
can be used for more advanced masking behavior
-->
        <fieldMasker class="your.custom.FieldMaskerA"/>
        <fieldMasker class="your.custom.FieldMaskerB"/>
    </jsonGeneratorDecorator>
</encoder>

有关路径字符串格式和更多示例,请参见PathBasedFieldMasker。但总的来说:

  • 路径的格式与JSON指针类似(但不完全相同)。
  • 绝对路径以/开始,并且绝对到JSON输出事件的根(例如/@timestamp将屏蔽默认时间戳字段)
  • 部分路径不以/开头,并且与输出中看到的任何路径序列都匹配。
  • 具有单个令牌(即没有/个字符)的路径将匹配具有给定名称的字段的所有匹配项
  • 通配符标记(*)将匹配路径中该位置的任何内容
  • 使用~1在令牌内转义/
  • 使用~0在令牌内转义~

识别要按值屏蔽的字段值

可以通过多种方式指定要屏蔽的特定值,如以下示例所示:

<encoder class="net.logstash.logback.encoder.LogstashEncoder">
    <jsonGeneratorDecorator class="net.logstash.logback.mask.MaskingJsonGeneratorDecorator">
  
        <!-- The default mask string can optionally be specified by <defaultMask>.
When the default mask string is not specified, **** is used.
-->
        <defaultMask>****</defaultMask>
      
        <!-- Values to mask added via <value> will use the default mask string -->
        <value>^foo$</value>
        <value>bar</value>
      
        <!-- Multiple values can be specified as a comma separated string in the <values> element. -->
        <values>^baz$,^blah$</values>
      
        <!-- Values to mask added via <valueMask> can use a non-default mask string
The mask string here can reference regex capturing groups if needed
-->
        <valueMask>
            <value>^(foo)-.*$</value>
            <value>^(bar)-.*$</value>
            <mask>$1****</mask>
        </valueMask>
      
        <!-- Values to mask can be supplied dynamically with an implementation of
MaskingJsonGeneratorDecorator.ValueMaskSupplier
-->
        <valueMaskSupplier class="your.custom.ValueMaskSupplierA"/>
      
        <!-- Custom implementations of net.logstash.logback.mask.ValueMasker
can be used for more advanced masking behavior
-->
        <valueMasker class="your.custom.ValueMaskerA"/>
        <valueMasker class="your.custom.ValueMaskerB"/>
    </jsonGeneratorDecorator>
</encoder>

通过值识别要屏蔽的数据比通过路径识别要屏蔽的数据要昂贵得多。因此,更喜欢通过路径屏蔽识别数据。

要掩码的值通过每个值掩码传递,其中一个掩码的输出作为输入传递给下一个掩码。这允许每个掩码器在值内屏蔽特定的子字符串。掩体的执行顺序没有定义,也不应依赖。

当使用正则表达式识别要屏蔽的字符串时,每个字符串字段值中的所有匹配项都将被替换。如果要匹配完整的字符串字段值,请使用行首(^)和行尾($)标记。

Customizing Standard Field Names

上面用于记录事件(LoggingEvents)和访问事件(AccessEvents)的标准字段名可以通过使用编码器或附加器配置中的fieldNames配置元素进行自定义。

For example:

<encoder class="net.logstash.logback.encoder.LogstashEncoder">
    <fieldNames>
        <timestamp>time</timestamp>
        <message>msg</message>
        <stackTrace>stacktrace</stackTrace>
        ...
    </fieldNames>
</encoder>

通过将字段名设置为[ignore],防止输出字段。

对于LoggingEvents,请参阅LogstashFieldNames,了解所有可以自定义的字段名。该类中的每个java字段名都是用于指定字段名的xml元素的名称(例如loggerlevelValue)。此外,可以这样配置一组单独的缩短字段名:

<encoder class="net.logstash.logback.encoder.LogstashEncoder">
    <fieldNames class="net.logstash.logback.fieldnames.ShortenedFieldNames"/>
</encoder>

对于LoggingEvents,通过分别为callermdccontext指定字段名,将调用方信息、MDC属性和上下文属性记录在JSON事件的sub-objects中。

对于AccessEvents,请参阅LogstashAccessFieldNames,了解所有可以自定义的字段名。该类中的每个java字段名都是用于指定字段名的xml元素的名称(例如fieldsMethodfieldsProtocol)。

Customizing Version

版本字段值默认为字符串值1

该值可以如下更改:

<encoder class="net.logstash.logback.encoder.LogstashEncoder">
    <version>2</version>
</encoder>

该值可以写成数字(而不是字符串),如下所示:

<encoder class="net.logstash.logback.encoder.LogstashEncoder">
    <writeVersionAsInteger>true</writeVersionAsInteger>
</encoder>

Customizing Timestamp

默认情况下,时间戳以DateTimeFormatter.ISO_OFFSET_DATE_TIME(例如2019-11-03T10:15:30.123+01:00)指定的格式写入主机Java平台的默认时区中的字符串值。

您可以这样更改图案:

<encoder class="net.logstash.logback.encoder.LogstashEncoder">
    <timestampPattern>yyyy-MM-dd'T'HH:mm:ss.SSS</timestampPattern>
</encoder>

timestampPattern的值可以是以下任意值:

  • [UNIX_TIMESTAMP_AS_NUMBER]-自unix时代以来以毫秒的JSON数值写入的时间戳
  • [UNIX_TIMESTAMP_AS_STRING]-自unix时代以来以毫秒的JSON字符串值写入的时间戳
  • [``constant``]-(例如[ISO_OFFSET_DATE_TIME])使用给定的DateTimeFormatter常数写入的时间戳
  • 使用从给定模式创建的DateTimeFormatter写入的任何其他值-(例如yyyy-MM-dd'T'HH:mm:ss.SSS)时间戳

提供者在后台使用标准的Java DateTimeFormatter。但是,当使用以下标准ISO格式之一时,会进行特殊优化,使其速度快近7倍:

  • [ISO_OFFSET_DATE_TIME]
  • [ISO_ZONED_DATE_TIME]
  • [ISO_LOCAL_DATE_TIME]
  • [ISO_DATE_TIME]
  • [ISO_INSTANT]

默认情况下,格式化程序使用主机Java平台的默认时区。您可以这样更改:

<encoder class="net.logstash.logback.encoder.LogstashEncoder">
    <timeZone>UTC</timeZone>
</encoder>

timeZone元素的值可以是java的TimeZone.getTimeZone(String id)方法接受的任何字符串。例如America/Los_AngelesGMT+10UTC。使用特殊值[DEFAULT]来使用系统的默认时区。

Customizing LoggingEvent Message

默认情况下,LoggingEvent消息写为JSON字符串。JSON字符串中不允许的任何字符(如换行符)都将被转义。有关详细信息,请参见“自定义角色转义”部分。

您还可以通过指定messageSplitRegex来拆分消息文本,将消息编写为JSON数组而不是字符串。此配置元素可以采用以下值:

  • 任何有效的正则表达式模式
  • SYSTEM(使用system-default行分隔符)
  • UNIX (uses \n)
  • WINDOWS (uses \r\n)

如果通过原始系统的行分隔符拆分日志消息,则写入的消息不包含任何嵌入的行分隔符。目标系统可以明确地解析消息,而不需要了解原始系统的行分隔符。

For example:

<encoder class="net.logstash.logback.encoder.LogstashEncoder">
    <messageSplitRegex>SYSTEM</messageSplitRegex>
</encoder>
<encoder class="net.logstash.logback.encoder.LogstashEncoder">
    <messageSplitRegex>\r?\n</messageSplitRegex>
</encoder>
<encoder class="net.logstash.logback.encoder.LogstashEncoder">
    <messageSplitRegex>#+</messageSplitRegex>
</encoder>

Customizing AccessEvent Message

默认情况下,AccessEvent消息以以下格式编写:

%clientHost - %user [%date] "%requestURL" %statusCode %bytesSent

要自定义消息模式,请如下指定messagePattern

<encoder class="net.logstash.logback.encoder.LogstashAccessEncoder">
    <messagePattern>%clientHost [%date] "%requestURL" %statusCode %bytesSent</messagePattern>
</encoder>

该模式可以包含任何AccessEvent转换字。

Customizing Logger Name Length

对于LoggingEvents,可以缩短记录器名称字段的长度,类似于%logger{36}的正常模式样式。可以在这里找到如何缩短的示例

<encoder class="net.logstash.logback.encoder.LogstashEncoder">
    <shortenedLoggerNameLength>36</shortenedLoggerNameLength>
</encoder>

Customizing Stack Traces

在记录异常时,默认情况下使用logback的ExtendedThrowableProxyConverter格式化堆栈跟踪。但是,您可以将编码器配置为使用任何ThrowableHandlingConverter来格式化堆栈跟踪。

请注意,ThrowableHandlingConverter仅适用于作为额外参数传递给log方法的异常,这是您通常在slf4j中记录异常的方式。不要对异常使用结构化参数或标记。

强大的ShortenedThrowableConverter包含在logstash-logback-encoder库中,通过以下方式格式化堆栈跟踪:

  • 限制每个可丢弃的堆叠元素的数量(适用于每个单独的可丢弃元素。例如caused-bys和抑制)
  • 限制轨迹字符的总长度
  • 缩写类名
  • 基于正则表达式过滤出连续不需要的堆栈跟踪元素。
  • 使用计算器确定是否应记录堆栈跟踪。
  • 以“正常”顺序(root-cause-last)或root-cause-first输出。
  • 使用inlineHashstackHash提供程序为每个异常堆栈计算和内联十六进制哈希(更多信息)。
  • 对堆栈跟踪使用自定义行分隔符。行分隔符可以指定为:SYSTEM(使用系统默认值)UNIX(使用\nWINDOWS(使用\r\n),或任何其他字符串。

For example:

<encoder class="net.logstash.logback.encoder.LogstashEncoder">
    <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>
        <evaluator class="myorg.MyCustomEvaluator"/>
        <rootCauseFirst>true</rootCauseFirst>
        <inlineHash>true</inlineHash>
        <lineSeparator>\\n</lineSeparator>
    </throwableConverter>
</encoder>

ShortenedThrowableConverter甚至可以在PatternLayout中用于格式化您可能拥有的任何non-JSON日志中的堆栈跟踪。

Prefix/Suffix/Separator

您可以指定正在使用的日志管道可能需要的前缀(写在JSON对象之前)、后缀(写在JSON对象之后)和/或行分隔符(写在后缀之后),例如:

  • 如果您正在为syslog使用公共事件表达式(CEE)格式,则需要添加@cee:前缀。
  • 如果您正在使用其他syslog目标,则可能需要添加标准syslog头。
  • 如果您正在使用Loggly,则可能需要添加您的客户令牌。

例如,要为UDP上的syslog添加标准syslog头,请配置以下内容:

<configuration>
    <conversionRule conversionWord="syslogStart" converterClass="ch.qos.logback.classic.pattern.SyslogStartConverter"/>

    <appender name="stash" class="net.logstash.logback.appender.LogstashUdpSocketAppender">
        <host>MyAwesomeSyslogServer</host>
        <!-- port is optional (default value shown) -->
        <port>514</port>
        <layout>
            <prefix class="ch.qos.logback.classic.PatternLayout">
                <pattern>%syslogStart{USER}</pattern>
            </prefix>
        </layout>
    </appender>

    ...
</configuration>

当使用LogstashEncoderLogstashAccessEncoder或复合编码器时,前缀是Encoder,而不是Layout,因此需要将前缀PatternLayout包装在LayoutWrappingEncoder中,如下所示:

<configuration>
    ...
    <appender ...>
        <encoder class="net.logstash.logback.encoder.LogstashEncoder">
            ...
            <prefix class="ch.qos.logback.core.encoder.LayoutWrappingEncoder">
                <layout class="ch.qos.logback.classic.PatternLayout">
                    <pattern>@cee:</pattern>
                </layout>
            </prefix>  
        </encoder>
    </appender>
</configuration>

注意,logback的xml配置读取器将删除xml元素值中的空白。因此,如果您想用空格结束前缀或后缀模式,首先添加空格,然后在其后面添加类似%mdc{keyThatDoesNotExist}的内容。例如<pattern>your pattern %mdc{keyThatDoesNotExist}</pattern>。这将导致logback根据需要输出空白,然后输出不存在的MDC键的空白字符串。

⚠️ 如果您遇到以下警告:A "net.logstash.logback.encoder.LogstashEncoder" object is not assignable to a "ch.qos.logback.core.Appender" variable.,您将遇到logback 1.2.1中引入的向后不兼容。请投票支持LOGBACK-1326,并向PR#383竖起大拇指,以尝试在logback中解决此问题。同时,唯一的解决方案是将logback-classic和logback-core降级到1.2.0

在后缀后写入的行分隔符可以指定为:

  • SYSTEM(使用系统默认值)
  • UNIX (uses \n)
  • WINDOWS (uses \r\n), or
  • 任何其他字符串。

For example:

<configuration>
    ...
    <appender ...>
        <encoder class="net.logstash.logback.encoder.LogstashEncoder">
            ...
            <lineSeparator>UNIX</lineSeparator>
        </encoder>
    </appender>
</configuration>

Composite Encoder/Layout

如果希望在LoggingEvents和AccessEvents中包含的JSON格式和数据具有更大的灵活性,请使用LoggingEventCompositeJsonEncoderAccessEventCompositeJsonEncoder(或相应的布局)。

这些编码器/布局由一个或多个有助于JSON输出的JSON提供程序组成。默认情况下,在复合编码器/布局中未配置任何提供程序。你必须添加你想要的。

For example:

<encoder class="net.logstash.logback.encoder.LoggingEventCompositeJsonEncoder">
    <providers>
        <mdc/>
        <pattern>
            <pattern>
                {
                  "timestamp": "%date{ISO8601}",
                  "myCustomField": "fieldValue",
                  "relative": "#asLong{%relative}"
                }
            </pattern>
        </pattern>
        <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>
                <evaluator class="myorg.MyCustomEvaluator"/>
                <rootCauseFirst>true</rootCauseFirst>
            </throwableConverter>
        </stackTrace>
    </providers>
</encoder>

logstash-logback-encoder库包含许多提供者out-of-the-box,您甚至可以通过扩展JsonProvider来plug-in自己的提供者。每个提供者都有自己的配置选项来进一步自定义。

这些编码器/布局利用内部缓冲区在渲染过程中保存JSON输出。默认情况下,该缓冲区的大小设置为1024字节。通过将minBufferSize属性设置为所需的值,可以配置不同的大小。当需要适应较大的事件时,缓冲区会自动增长到minBufferSize以上。然而,只有前minBufferSize字节将被后续调用重用。因此,强烈建议将最小大小设置为至少等于编码事件的平均大小,以减少不必要的内存分配,并减少垃圾收集器的压力。

LoggingEvents和AccessEvents通用的提供程序

下表列出了可用于LoggingEvents和AccessEvents的提供程序。提供者名称是配置时要使用的xml元素名称。

ProviderDescription/Properties
context从logback的上下文输出条目。字段名Sub-object字段名(否sub-object)
nestedField在配置的字段名下嵌套JSON对象。嵌套对象由添加到此提供程序的其他提供程序填充。请参阅嵌套JSON提供程序。fieldName-输出字段名提供程序-应填充嵌套对象的提供程序。
pattern从配置的JSON对象字符串输出字段,同时替换logback的PatternLayout支持的模式。请参阅模式JSON提供程序模式-JSON对象字符串(无默认值)省略EmptyFields-是否省略具有空值的字段(false)
sequence为每个日志事件输出递增的序列号。用于跟踪传输过程中的潜在消息丢失(例如UDP)。fieldName-输出字段名(序列)
threadName记录事件的thread的名称。fieldName-输出字段名(thread\u name)
timestamp事件时间戳。fieldName-输出字段名(@timestamp)模式-输出格式([ISO\u OFFSET\u DATE\u TIME])有关可能的值,请参见上文。时区-时区(系统时区)
uuid输出随机UUID作为字段值。当您想为日志行提供唯一标识符时,它非常方便。fieldName-输出字段名(uuid)策略-uuid生成策略(随机)。支持的选项:随机-用于类型4 UUID时间-用于类型1基于时间的UUID以太网-仅用于“时间”策略。定义时-用于UUID位置部分的MAC地址。将其设置为接口值以使用真实的底层网络接口,或设置为特定值,如00:C0:F0:3D:5B:7C注意:com.fasterxml.uuid:java-uuid-generator可选依赖项必须添加到使用“uuid”提供程序的应用程序中。
versionLogstash JSON格式版本。fieldName-输出字段名(@version)version-输出值(1)writeAsInteger-将版本作为整数值写入(false=作为字符串值写入)

记录事件的提供者

上面提到的常见提供者以及下表中列出的提供者可用于记录事件。提供者名称是配置时要使用的xml元素名称。显示每个提供程序的配置属性,括号中包含默认配置值。

ProviderDescription/Properties
arguments从事件参数数组输出字段。请参阅Event-specific自定义字段。fieldName-Sub-object字段名(无sub-object)includeNonStructuredArguments-包括不是StructuredArgument实例的参数。对象字段名将是参数索引的非结构化DargumentsFieldPrefix前缀。(默认值=false)非结构化DargumentsFieldPrefix-对象字段名称前缀(默认值=arg)
callerData输出有关从何处调用记录器的数据(类/方法/文件/行)。fieldName-Sub-objectfield name(nosub-object)classFieldName-类名的字段名(caller\u class\u name)methodFieldName-方法名的字段名(caller\u method\u name)fileFieldName-文件名的字段名(caller\u file\u name)lineFieldName-行号的字段名(caller\u line\u number)
contextName输出logback上下文的名称。fieldName-输出字段名(上下文)
loggerName记录消息的记录器的名称。fieldName-输出字段名(logger_name)shortenedLoggerNameLength-名称将尝试缩写的长度(无缩写)
logLevel记录器级文本(信息、警告等)。fieldName-输出字段名(级别)
logLevelValue记录器级别数值。fieldName-输出字段名(level_值)
logstashMarkers用于输出Event-specific自定义字段中指定的日志标记。
mdc从映射的诊断上下文(MDC)输出条目。默认情况下将包括所有条目。当指定要包含的关键字名称时,所有其他字段都将被排除在外。当指定要排除的键名称时,将包括所有其他字段。指定包含和排除的键名是配置错误。fieldName-Sub-objectfield name(nosub-object)includeMdcKeyName-要包含的键的名称(all)excludeMdcKeyName-要排除的键的名称(none)mdcKeyFieldName-格式为mdcKeyName=fieldName的字符串,指定要为特定MDC键输出的备用字段名(none)
message格式化日志事件消息。fieldName-输出字段名(消息)messageSplitRegex-如果为null或为空,则按原样写入消息文本(默认行为)。否则,使用指定的正则表达式拆分消息文本并将其作为数组写入。有关详细信息,请参阅自定义消息部分。
rawMessage原始日志事件消息,与解析参数的格式化日志相反。fieldName-输出字段名(raw_消息)
rootStackTraceElement(仅当记录了throwable时)输出一个JSON对象,该对象包含引发outer-most异常的类和方法名。fieldName-输出字段名(root\u stack\u trace\u元素)classFieldName-包含引发最外层异常的类名的字段名(class\u name)methodFieldName-包含引发最外层异常的方法名的字段名(method\u name)
stackHash(仅当记录了可丢弃文件时)计算并输出可丢弃堆栈的十六进制哈希。这有助于识别同一错误的多次出现(更多信息)。fieldName-输出字段名(stack\u hash)exclude-计算错误哈希排除时要排除的与堆栈跟踪元素匹配的正则表达式模式-计算错误哈希时要排除的与堆栈跟踪元素匹配的正则表达式模式的逗号分隔列表
stackTrace与事件一起记录的任何可丢弃的堆栈跟踪。堆栈帧由换行符分隔。fieldName-输出字段名(stack\u trace)throwableConverter-用于格式化stacktrace(stack\u trace)的ThrowableHandlingConverter
tags以逗号分隔的列表形式输出回写标记。fieldName-输出字段名(标记)
throwableClassName(仅当记录了可丢弃文件时)输出一个包含可丢弃文件类名的字段。fieldName-输出字段名(throwable_class)useSimpleClassName-为true时,将使用throwable的简单类名。如果为false,将使用完全限定的类名。(正确)
throwableMessage(仅当记录了可丢弃文件时)输出一个包含可丢弃文件消息的字段。fieldName-输出字段名(throwable_消息)
throwableRootCauseClassName(仅当记录了可丢弃项并且可以确定根本原因时)输出一个字段,该字段包含可丢弃项的根本原因的类名。fieldName-输出字段名(throwable\u root\u cause\u class)useSimpleClassName-为true时,将使用throwable的简单类名。如果为false,将使用完全限定的类名。(正确)
throwableRootCauseMessage(仅当记录了可丢弃项并且可以确定根本原因时)输出一个字段,该字段包含可丢弃项的根本原因的消息。fieldName-输出字段名(throwable\u root\u cause\u消息)

AccessEvents的提供程序

上面提到的常见提供程序以及下表中列出的提供程序可用于AccessEvents。提供者名称是配置时要使用的xml元素名称。显示每个提供程序的配置属性,括号中包含默认配置值。

ProviderDescription/Properties
contentLength内容长度。fieldName-输出字段名(content\u长度)
elapsedTime已用时间(毫秒)。fieldName-输出字段名(已用时间)
message消息格式为${remoteHost}-${remoteUser}[${timestamp}]“${requestUrl}”${statusCode}${contentLength}”。fieldName-输出字段名(消息)模式-时间戳的输出格式([ISO\u OFFSET\u DATE\u TIME])。有关可能的值,请参见上文。时区-时区(系统时区)
methodHTTP方法。fieldName—输出字段名(方法)
protocolHTTP协议。fieldName-输出字段名(协议)
remoteHost远程主机。fieldName-输出字段名(remote_host)
remoteUser远程用户。fieldName-输出字段名(remote_user)
requestedUri请求的URI。fieldName-输出字段名(请求的uri)
requestedUrl请求的URL。fieldName-输出字段名(请求的url)
requestHeaders包括请求头。fieldName-输出字段名(无默认值,必须提供)小写头名称-以小写形式写入头名称(false)过滤器-用于确定要包括/排除哪些头的过滤器。参见HeaderFilter和IncludeExcludeHeaderFilter
responseHeaders包括响应标头。fieldName-输出字段名(无默认值,必须提供)小写头名称-以小写形式写入头名称(false)过滤器-用于确定要包括/排除哪些头的过滤器。参见HeaderFilter和IncludeExcludeHeaderFilter
statusCodeHTTP状态代码。fieldName-输出字段名(状态代码)

Nested JSON Provider

使用nestedField提供程序在JSON事件输出中创建sub-object。

For example...

<encoder class="net.logstash.logback.encoder.LoggingEventCompositeJsonEncoder">
    <providers>
        <timestamp/>
        <nestedField>
            <fieldName>fields</fieldName>
            <providers>
                <logLevel/>
            </providers>
        </nestedField>
    </providers>
</encoder>

…将产生类似。。。

{
    "@timestamp": "...",
    "fields": {
        "level": "DEBUG"
    }
}

Pattern JSON Provider

当与复合JSON编码器/布局一起使用时,patternJSON提供程序可用于为记录的JSON输出的一部分定义模板。编码器/布局将填充模板内的值。模板中的每个值都被视为logback标准PatternLayout的模式,因此它可以是文字字符串(对于某些常量)和各种转换说明符(例如%d表示日期)的组合。

模式字符串(在模式提供程序中配置)必须是JSON对象。JSON对象的内容包含在记录的JSON输出中。

This example...

<encoder class="net.logstash.logback.encoder.LoggingEventCompositeJsonEncoder">
    <providers>
        <!-- provides the timestamp -->
        <timestamp/>

        <!-- provides the version -->
        <version/>

        <!-- provides the fields in the configured pattern -->
        <pattern>
            <!-- the pattern that defines what to include -->
            <pattern>
                { "level": "%level" }
            </pattern>
        </pattern>
    </providers>
</encoder>

…将产生类似。。。

{
    "@timestamp": "...",
    "@version": "1",
    "level": "DEBUG"
}

真正的力量来自这样一个事实,即有许多标准转换说明符,因此您可以自定义记录的内容和方式。例如,您可以使用%mdc{mykey}从MDC记录单个特定值。或者,对于访问日志,您可以使用%i{User-Agent}记录单个请求头。

可以在图案中使用嵌套对象和阵列。

如果在模式中使用null、数字或布尔常量,它将在生成的JSON中保留其类型。但是,仅在文本值中搜索转换模式。而且,由于这些模式是通过PatternLayout发送的,因此结果总是一个字符串,即使对于一些您可能觉得应该是数字的东西,比如%b(在访问日志中发送的字节)。

您可以在日志存储端处理类型转换,也可以使用此编码器提供的特殊操作。操作包括:

  • #asLong{...}-计算大括号中的模式,然后将结果字符串转换为长字符串(如果转换失败,则转换为null)。
  • #asDouble{...}-计算大括号中的模式,然后将结果字符串转换为双精度(如果转换失败,则转换为null)。
  • #asBoolean{...}-计算大括号中的模式,然后将结果字符串转换为布尔值。转换不区分大小写。trueyesy1(不区分大小写)转换为布尔值truenull或空字符串转换为null,其他任何内容都返回false
  • asNullIfEmpty{...}-计算大括号中的模式,如果结果字符串为空,则将其转换为null
  • #asJson{...}-计算花括号中的模式,然后将结果字符串转换为json(如果转换失败,则转换为null)。
  • #tryJson{...}-计算花括号中的模式,然后将结果字符串转换为json(如果转换失败,则仅转换字符串)。

所以这个例子。。。

<pattern>
    {
        "line_str": "%line",
        "line_long": "#asLong{%line}",
        "has_message": "#asBoolean{%mdc{hasMessage}}",
        "json_message": "#asJson{%message}"
    }
</pattern>

…这个日志代码。。。

MDC.put("hasMessage", "true");
LOGGER.info("{\"type\":\"example\",\"msg\":\"example of json message with type\"}");

…将产生类似。。。

{
    "line_str": "97",
    "line_long": 97,
    "has_message": true,
    "json_message": {"type":"example","msg":"example of json message with type"}
}

注意,为line_long发送的值是一个数字,即使在您的模式中它是一个带引号的文本。json_message字段值是一个json对象,而不是字符串。

如果您不想解释某个操作,可以通过在其前面加\来对其进行转义。

省略具有空值的字段

模式提供程序可以配置为省略具有以下空值的字段:

  • null
  • 空字符串(""
  • 空数组([]
  • 空对象({}
  • 仅包含空值字段的对象
  • 仅包含空值的数组

要省略具有空值的字段,请将omitEmptyFields配置为true(默认值为false),如下所示:

<encoder class="net.logstash.logback.encoder.LoggingEventCompositeJsonEncoder">
    <providers>
        <pattern>
            <omitEmptyFields>true</omitEmptyFields>
            <pattern>
                {
                    "logger": "%logger",
                    "level": "%level",
                    "thread": "%thread",
                    "message": "%message",
                    "traceId": "%mdc{traceId}"
                }
            </pattern>
        </pattern>
    </providers>
</encoder>

如果MDC不包含traceId项,那么来自上述模式的JSON日志事件将不包含traceId字段。。。

{
    "logger": "com.example...",
    "level": "DEBUG",
    "thread": "exec-1",
    "message": "Hello World!"
}

LoggingEvent patterns

对于LoggingEvents,支持来自logback-classic'sPatternLayout的转换说明符。

For example:

<encoder class="net.logstash.logback.encoder.LoggingEventCompositeJsonEncoder">
    <providers>
        <timestamp/>
        <pattern>
            <pattern>
                {
                    "custom_constant": "123",
                    "tags": ["one", "two"],
                    "logger": "%logger",
                    "level": "%level",
                    "thread": "%thread",
                    "message": "%message",
                    ...
                }
            </pattern>
        </pattern>
    </providers>
</encoder>

请注意,%property{key}转换说明符在模式Json提供程序的上下文中使用时的行为略有不同。如果在记录器上下文或系统属性中找不到该属性,它将返回一个空字符串,而不是像通常那样返回null。例如,假设未定义“foo”属性,%property{foo}将返回""(空字符串),而不是"null"(内容由4个字母组成的字符串)。

属性转换说明符还允许您指定未定义属性时使用的默认值。默认值是可选的,可以在Bash shell中使用:-操作符指定。例如,假设未定义“foo”属性,%property{foo:-bar}将返回bar

AccessEvent patterns

对于AccessEvents,支持来自logback-access'sPatternLayout的转换说明符。

For example:

<encoder class="net.logstash.logback.encoder.AccessEventCompositeJsonEncoder">
    <providers>
        <pattern>
            <pattern>
                {
                    "custom_constant": "123",
                    "tags": ["one", "two"],
                    "remote_ip": "%a",
                    "status_code": "%s",
                    "elapsed_time": "%D",
                    "user_agent": "%i{User-Agent}",
                    "accept": "%i{Accept}",
                    "referer": "%i{Referer}",
                    "session": "%requestCookie{JSESSIONID}",
                    ...
                }
            </pattern>
        </pattern>
    </providers>
</encoder>

还有一个特殊操作可用于此AccessEvents:

  • #nullNA{...}-如果大括号中的模式计算为破折号(-),则它将替换为null值。

您可能想使用它,因为logback-access中的许多PatternLayout转换字将针对non-existent值计算为-(例如,对于cookie、头或请求属性)。

所以下面的模式。。。

<pattern>
    {
        "default_cookie": "%requestCookie{MISSING}",
        "filtered_cookie": "#nullNA{%requestCookie{MISSING}}"
    }
</pattern>

...will produce...

{
    "default_cookie": "-",
    "filtered_cookie": null
}

Custom JSON Provider

您可以通过实现JsonProvider接口(或扩展实现JsonProvider接口的现有类之一)来创建自己的JSON提供程序。

然后,将提供者添加到LoggingEventCompositeJsonEncoder,如下所示:

<encoder class="net.logstash.logback.encoder.LoggingEventCompositeJsonEncoder">
    <providers>
        ...
        <provider class="your.provider.YourJsonProvider">
            <!-- Any properties exposed by your provider can be set here -->
        </provider>
        ...
    </providers>
</encoder>

或者像这样的LogstashEncoder

<encoder class="net.logstash.logback.encoder.LogstashEncoder">
    ...
    <provider class="your.provider.YourJsonProvider">
        <!-- Any properties exposed by your provider can be set here -->
    </provider>
    ...
</encoder>

如果您的JsonProvider处理IAccessEvent,您也可以对AccessEventCompositeJsonEncoderLogstashAccessEncoder执行类似的操作。

Status Listeners

在执行过程中,logstash-logback-encoder中提供的编码器/附加器/布局将向回写StatusManager添加回写状态消息。这些状态消息通常通过logbackStatusListener报告。

由于异步附加器(尤其是tcp附加器)通过状态管理器报告警告和错误,如果尚未注册状态侦听器,则在启动时将注册向standard out输出警告和错误级别状态消息的默认状态侦听器。要禁用appender自动注册默认状态侦听器,请执行以下操作之一:

  • 注册其他logback状态侦听器,或
  • 在每个异步附加器中设置<addDefaultStatusListener>false</addDefaultStatusListener

Joran/XML Configuration

使用XML配置Logback由Logback的Joran配置系统处理。本节简要介绍Joran支持的高级数据类型。有关更多信息,请参阅官方文件。

Duration property

持续时间表示时间的圈数。可以将其指定为表示毫秒数的整数值,或将由logback的配置系统自动转换为持续时间实例的字符串,如“20秒”、“3.5分钟”或“5小时”。公认的时间单位是millisecondsecondminutehourday。装置名称后面可以跟一个“s”。因此,“2000毫秒”和“2000毫秒”是等效的。在没有时间单位规范的情况下,假设为毫秒。

因此,以下示例是等效的:

<duration>2000</duration>
<duration>2000 millisecond</duration>
<duration>2000 milliseconds</duration>

标题:logstash-logback-encoder: Logback JSON编码器和附加器
作者:michael
地址:https://blog.junxworks.cn/articles/2023/11/25/1700880717202.html