log4j2使用手册(中文)第九章 Appenders(一)

Appender负责将LogEvents传递到目的地。 每个Appender都必须实现Appender接口。 大多数Appender将扩展AbstractAppender,它增加了Lifecycle和Filterable支持。 Lifecycle允许组件在配置完成后完成初始化并在关闭期间执行清理。 Filterable允许组件加入过滤器,在事件处理期间对其进行过滤。

Appender通常只负责将事件数据写入目标地址。在大多数情况下,他们将格式化事件的责任委托给layout。一些appenders包装其他appenders,以便他们可以修改LogEvent,处理Appender中的失败,根据高级过滤条件将事件路由到从属Appender或提供类似的功能。

Appender总是有一个名称,以便可以在Loggers中引用它们。

AsyncAppender

AsyncAppender接受对其他Appender的引用,并使LogEvents在单独的Thread上写入它们。 请注意,写入这些Appender时的异常将从应用程序中隐藏。 应该在它引用的appender之后配置AsyncAppender以允许它正确关闭。

默认情况下,AsyncAppender使用java.util.concurrent.ArrayBlockingQueue,它不需要任何外部库。 请注意,多线程应用程序在使用此appender时应小心:阻塞队列容易受到锁争用的影响,并且我们的测试表明,当更多线程同时记录时性能可能会变差。 考虑使用无锁异步记录器以获得最佳性能。

AsyncAppender参数

参数名 类型 描述
AppenderRef String 要异步调用的Appender的名称。 可以配置多个AppenderRef元素。
blocking boolean 如果为true,则appender将等待,直到队列中有空闲槽。 如果为false,则在队列已满时将事件写入错误appender。 默认值为true。
shutdownTimeout integer Appender应该等待多少毫秒才能在关闭时刷新队列中的未完成日志事件。 默认值为零,这意味着永远等待。
bufferSize integer 指定可排队的最大事件数。 默认值为1024.请注意,当使用disruptor-styleBlockingQueue时,此缓冲区大小必须是2的幂。当应用程序的记录速度快于底层appender可以跟上足够长的时间来填充队列时, 行为由AsyncQueueFullPolicy决定。
errorRef String 如果由于appender中的错误或队列已满而无法调用任何appender时要调用的Appender的名称。 如果未指定,则将忽略错误。
filter Filter 一个过滤器,用于确定此Appender是否应该处理该事件。 使用CompositeFilter可以使用多个Filter。
name String Appender的名字。
ignoreExceptions boolean 默认值为true,导致在将事件附加到内部记录然后被忽略时遇到异常。 设置为false时,异常将传播给调用者。 将此Appender包装在FailoverAppender中时,必须将此参数设置为false。
includeLocation boolean 提取位置是一项昂贵的操作(它可以使记录速度慢5到20倍)。 为了提高性能,在向队列添加日志事件时,默认情况下不包括位置。 您可以通过设置includeLocation =“true”来更改此设置。
BlockingQueueFactory BlockingQueueFactory 此元素将覆盖BlockingQueueto使用的类型。 有关详细信息,请参阅文档。

即使底层appender无法跟上日志记录速率并且队列正在填满,也有一些系统属性可用于维护应用程序吞吐量。 请参阅系统属性log4j2.AsyncQueueFullPolicylog4j2.DiscardThreshold的详细信息。

典型的AsyncAppender配置可能如下所示:

<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="warn" name="MyApp" packages="">
  <Appenders>
    <File name="MyFile" fileName="logs/app.log">
      <PatternLayout>
        <Pattern>%d %p %c{1.} [%t] %m%n</Pattern>
      </PatternLayout>
    </File>
    <Async name="Async">
      <AppenderRef ref="MyFile"/>
    </Async>
  </Appenders>
  <Loggers>
    <Root level="error">
      <AppenderRef ref="Async"/>
    </Root>
  </Loggers>
</Configuration>

从Log4j 2.7开始,可以使用BlockingQueueFactory插件指定BlockingQueue或TransferQueue的自定义实现。 要覆盖默认的BlockingQueueFactory,请在元素中指定插件,如下所示:

<Configuration name="LinkedTransferQueueExample">
  <Appenders>
    <List name="List"/>
    <Async name="Async" bufferSize="262144">
      <AppenderRef ref="List"/>
      <LinkedTransferQueue/>
    </Async>
  </Appenders>
  <Loggers>
    <Root>
      <AppenderRef ref="Async"/>
    </Root>
  </Loggers>
</Configuration>

Log4j附带以下实现:
BlockingQueueFactory实现

插件名称 描述
ArrayBlockingQueue 默认使用ArrayBlockingQueue
DisruptorBlockingQueue 这使用了BlockingQueue的Conversant Disruptor实现。 这个插件只有一个可选属性spinPolicy,它对应于
JCToolsBlockingQueue 这使用JCTools,特别是MPSC有界无锁队列。
LinkedTransferQueue 这使用了Java 7中的新实现LinkedTransferQueue。 请注意,此队列不使用AsyncAppender的bufferSize配置属性,因为LinkedTransferQueue不支持最大容量。

CassandraAppender

CassandraAppender将其输出写入Apache Cassandra数据库。 必须提前配置密钥空间和表,并且该表的列将映射到配置文件中。

每列可以指定StringLayout(例如,PatternLayout)和可选的转换类型,或者只指定org.apache.logging.log4j.spi.ThreadContextMap或org.apache.logging.log4j.spi.ThreadContextStack的转换类型 将MDC或NDC分别存储在map或列表列中。与java.util.Date兼容的转换类型将使用转换为该类型的日志事件时间戳(例如,使用java.util.Date填充Cassandra中的时间戳列类型)

CassandraAppender参数

参数名称 类型 Description
batched boolean 是否使用批处理语句将日志消息写入Cassandra。 默认情况下,这是false。
batchType BatchStatement.Type 使用批量写入时要使用的批处理类型。 默认情况下,这是LOGGED。
bufferSize int 写入前缓冲或批处理的日志消息数。 默认情况下,不进行缓冲。
clusterName String 要连接的Cassandra集群的名称。
columns ColumnMapping[] 列映射配置列表。 每列必须指定列名。 每列可以具有由其完全限定类名指定的转换类型。 默认情况下,转换类型为String。 如果配置的类型与Recad兼容withReadOnlyStringMap / ThreadContextMaporThreadContextStack,那么该列将分别用MDC或NDC填充。 如果配置的类型与search.util.Date分配兼容,则日志时间戳将转换为该配置的日期类型。 如果给出了aliteralattribute,那么它的值将在INSERTquery中原样使用而不进行任何转义。 否则,指定的布局或模式将转换为已配置的类型并存储在该列中。
contactPoints SocketAddress[] 要连接的Cassandra节点的主机和端口列表。 这些必须是有效的主机名或IP地址。 默认情况下,如果未为主机指定端口或将其设置为0,则将使用默认的Cassandra端口9042。 默认情况下,将使用localhost:9042。
filter Filter 一个过滤器,用于确定此Appender是否应该处理该事件。 使用CompositeFilter可以使用多个Filter。
ignoreExceptions boolean 默认值为true,导致在将事件附加到内部记录然后被忽略时遇到异常。 设置为false时,异常将传播给调用者。 将此Appender包装在FailoverAppender中时,必须将此设置为false。
keyspace String 包含将写入日志消息的表的键空间的名称。
name String Appender的名字。
password String 要使用的密码(以及用户名)连接到Cassandra。
table String String要写日志消息的表的名称。
useClockForTimestampGenerator boolean 是否使用已配置的org.apache.logging.log4j.core.util.Clockas作为TimestampGenerator。 默认情况下,这是false。
username String 用于连接Cassandra的用户名。 默认情况下,不使用用户名或密码。
useTls boolean 是否使用TLS / SSL连接到Cassandra。 默认情况下这是错误的。

以下是CassandraAppender配置示例:

<Configuration name="CassandraAppenderTest">
  <Appenders>
    <Cassandra name="Cassandra" clusterName="Test Cluster" keyspace="test" table="logs" bufferSize="10" batched="true">
      <SocketAddress host="localhost" port="9042"/>
      <ColumnMapping name="id" pattern="%uuid{TIME}" type="java.util.UUID"/>
      <ColumnMapping name="timeid" literal="now()"/>
      <ColumnMapping name="message" pattern="%message"/>
      <ColumnMapping name="level" pattern="%level"/>
      <ColumnMapping name="marker" pattern="%marker"/>
      <ColumnMapping name="logger" pattern="%logger"/>
      <ColumnMapping name="timestamp" type="java.util.Date"/>
      <ColumnMapping name="mdc" type="org.apache.logging.log4j.spi.ThreadContextMap"/>
      <ColumnMapping name="ndc" type="org.apache.logging.log4j.spi.ThreadContextStack"/>
    </Cassandra>
  </Appenders>
  <Loggers>
    <Logger name="org.apache.logging.log4j.cassandra" level="DEBUG">
      <AppenderRef ref="Cassandra"/>
    </Logger>
    <Root level="ERROR"/>
  </Loggers>
</Configuration>

此示例配置使用以下建表脚本:

CREATE TABLE logs (
    id timeuuid PRIMARY KEY,
    timeid timeuuid,
    message text,
    level text,
    marker text,
    logger text,
    timestamp timestamp,
    mdc map<text,text>,
    ndc list<text>
);

ConsoleAppender

正如人们所预料的那样,ConsoleAppender将其输出写入System.out或System.err,默认使用System.out。 必须提供Layout以格式化LogEvent。

ConsoleAppender参数

参数名称 类型 描述
filter Filter 一个过滤器,用于确定此Appender是否应该处理该事件。 使用CompositeFilter可以使用多个Filter。
layout Layout 用于格式化LogEvent的布局。 如果未提供布局,则将使用默认的模式布局“%m%n”。
follow boolean 标识appender是否通过System.setOut或System.setErr在配置后进行重新分配System.out或System.err。 请注意,follow属性不能与Windows上的Jansi一起使用。 不能直接使用。
direct boolean 直接写入java.io.FileDescriptorand并绕过java.lang.System.out / .err。 当输出重定向到文件或其他进程时,可以提高10倍的性能提升。 不能在Windows上与Jansi一起使用。 不能跟follow一起使用。 输出不会受到java.lang.System.setOut()/。setErr()的影响,并且可能与其他输出tojava.lang.System.out / .errin交织在一起,形成一个多线程的应用程序。自2.6.2以来。 请注意,这是一个新增功能,目前仅在Linux和Windows上使用Oracle JVM进行了测试。
name String Appender的名字。
ignoreExceptions boolean 默认值为true,导致异常发生是被内部记录,然后被忽略。 设置为false时,异常将传播给调用者。 将此Appender包装在FailoverAppender中时,必须将此参数设置为false。
target String “SYSTEM_OUT”或“SYSTEM_ERR”。 默认值为“SYSTEM_OUT”。

典型的 Console 配置如下所示:

<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="warn" name="MyApp" packages="">
  <Appenders>
    <Console name="STDOUT" target="SYSTEM_OUT">
      <PatternLayout pattern="%m%n"/>
    </Console>
  </Appenders>
  <Loggers>
    <Root level="error">
      <AppenderRef ref="STDOUT"/>
    </Root>
  </Loggers>
</Configuration>

FailoverAppender

FailoverAppender包装了一组appender。 如果主Appender失败,将按顺序尝试辅助appender,直到一个成功或没有更多辅助appender可以尝试。

FailoverAppender参数

参数名称 类型 描述
filter Filter 一个过滤器,用于确定此Appender是否应该处理该事件。 使用CompositeFilter可以使用多个Filter。
primary String 要使用的主要Appender的名称。
failovers String[] 要使用的辅助Appender的名称。
name String Appender的名字。
retryIntervalSeconds integer 重试主Appender之前应该经过的秒数。 默认值为60。
ignoreExceptions boolean 默认值为true,导致在将事件附加到内部记录然后被忽略时遇到异常。 设置为false时,异常将传播给调用者。
target String “SYSTEM_OUT”或“SYSTEM_ERR”。 默认值为“SYSTEM_ERR”。

Failover 配置如下所示

<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="warn" name="MyApp" packages="">
  <Appenders>
    <RollingFile name="RollingFile" fileName="logs/app.log" filePattern="logs/app-%d{MM-dd-yyyy}.log.gz"
                 ignoreExceptions="false">
      <PatternLayout>
        <Pattern>%d %p %c{1.} [%t] %m%n</Pattern>
      </PatternLayout>
      <TimeBasedTriggeringPolicy />
    </RollingFile>
    <Console name="STDOUT" target="SYSTEM_OUT" ignoreExceptions="false">
      <PatternLayout pattern="%m%n"/>
    </Console>
    <Failover name="Failover" primary="RollingFile">
      <Failovers>
        <AppenderRef ref="Console"/>
      </Failovers>
    </Failover>
  </Appenders>
  <Loggers>
    <Root level="error">
      <AppenderRef ref="Failover"/>
    </Root>
  </Loggers>
</Configuration>

FileAppender

FileAppender是一个OutputStreamAppender,它写入fileName参数中指定的文件。 FileAppender使用FileManager(扩展OutputStreamManager)来实际执行文件I / O. 虽然无法共享来自不同配置的FileAppender,但是如果可以访问Manager,则可以使用FileManagers。 例如,servlet容器中的两个Web应用程序可以拥有自己的配置,并且如果Log4j位于两个共用的ClassLoader中,则可以安全地写入同一文件。

FileAppender参数

参数名称 类型 描述
append boolean 如果为true - 默认值,则记录将附加到文件末尾。 设置为false时,将在写入新记录之前清除该文件。
bufferedIO boolean 如果为true - 默认情况下,记录将写入缓冲区,当缓冲区已满或者写入记录时设置了immediateFlush时,数据将写入磁盘。 文件锁定不能与bufferedIO一起使用。 性能测试表明,即使启用了immediateFlush,使用缓冲I / O也可以显着提高性能。
bufferSize int 当bufferedIO为true时,这是缓冲区大小,默认为8192字节。
createOnDemand boolean appender按需创建文件。 appender仅在日志事件通过所有过滤器并将其路由到此appender时创建该文件。 默认为false。
filter Filter 一个过滤器,用于确定此Appender是否应该处理该事件。 使用CompositeFilter可以使用多个Filter。
fileName String 要写入的文件的名称。 如果该文件或其任何父目录不存在,则将创建它们。
immediateFlush boolean 设置为true时 - 默认值,每次写入后都会进行刷新。 这将保证数据写入磁盘但可能影响性能。每次写入后刷新仅在将此appender与同步记录器一起使用时才有用。 即使immediateFlush设置为false,异步记录器和追加器也会在一批事件结束时自动刷新。 这也保证了数据被写入磁盘但效率更高。
layout Layout 用于格式化LogEvent的布局。 如果未提供布局,则将使用默认的模式布局“%m%n”。
locking boolean 设置为true时,I / O操作仅在保持文件锁定时发生,允许多个JVM中的FileAppender和可能多个主机同时写入同一文件。 这将显着影响性能,因此应谨慎使用。 此外,在许多系统上,文件锁定是“建议性的”,这意味着其他应用程序可以在不获取锁定的情况下对文件执行操作。 默认值为false。
name String Appender的名字。
ignoreExceptions boolean 默认值为true,导致在将事件附加到内部记录然后被忽略时遇到异常。 设置为false时,异常将传播给调用者。 将此Appender包装在FailoverAppender中时,必须将此设置为false。
filePermissions String 文件属性权限为POSIX格式,以便在创建文件时应用。下层文件系统应支持POSIX文件属性视图。示例:rw ——-或rw-rw-rw- etc …
fileOwner String 文件所有者在文件创建时定义。出于安全原因,可能会限制更改文件的所有者,并且不允许操作IOException。 只有具有有效用户ID等于文件用户ID或具有适当权限的进程才可以更改文件的所有权if_POSIX_CHOWN_RESTRICTED对路径生效。下行文件系统应支持文件所有者属性视图。
fileGroup String 文件组定义文件创建时。下层文件系统应支持POSIX文件属性视图。

这是一个示例 File配置:

<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="warn" name="MyApp" packages="">
  <Appenders>
    <File name="MyFile" fileName="logs/app.log">
      <PatternLayout>
        <Pattern>%d %p %c{1.} [%t] %m%n</Pattern>
      </PatternLayout>
    </File>
  </Appenders>
  <Loggers>
    <Root level="error">
      <AppenderRef ref="MyFile"/>
    </Root>
  </Loggers>
</Configuration>

FlumeAppender

这是一个单独的jar中提供的可选组件。

Apache Flume是一个分布式,可靠且可用的系统,用于有效地从许多不同的源收集,聚合和移动大量日志数据到集中式数据存储。 FlumeAppender接收LogEvents并将它们作为序列化的Avro事件发送到Flume代理以供使用。

Flume Appender支持三种操作模式。

  1. 它可以充当远程Flume客户端,通过Avro将Flume事件发送到配置了Avro Source的Flume Agent。
  2. 它可以作为嵌入式Flume Agent,Flume事件直接传递到Flume进行处理。
  3. 它可以将事件持久保存到本地BerkeleyDB数据存储,然后异步将事件发送到Flume,类似于嵌入式Flume Agent,但没有大多数Flume依赖项。

用作嵌入式代理将导致消息直接传递到Flume Channel,然后控件将立即返回给应用程序。 与远程代理的所有交互都将异步进行。 将“type”属性设置为“Embedded”将强制使用嵌入式代理。 此外,在appender配置中配置代理属性也将导致使用嵌入式代理。

FlumeAppender参数

参数类型 类型 描述
agents Agent[] 应将日志记录事件发送到的代理数组。 如果指定了多个代理程序,则第一个代理程序将是主要代理程序,后续代理程序将按主要代理程序失败时指定为辅助程序的顺序使用。 每个代理定义都提供代理主机和端口。 代理和属性的规范是互斥的。 如果两者都配置,将导致错误。
agentRetries integer 在使用辅助节点之前应重试代理的次数。 当指定type =“persistent”时,将忽略此参数(代理在未通过下一次之前尝试过一次).
batchSize integer 指定应作为批处理发送的事件数。 默认值为1.此参数仅适用于Flume Appender。
compress boolean 设置为true时,将使用gzip压缩消息体
connectTimeoutMillis integer Flume将在超时连接之前等待的毫秒数。
dataDir String 应写入Flume预写日志的目录。 仅当embedded设置为true且使用Agent元素而不是Property元素时才有效。
filter Filter 一个过滤器,用于确定此Appender是否应该处理该事件。 使用CompositeFilter可以使用多个Filter。
eventPrefix String要添加到每个事件属性的字符串,以便将其与MDC属性区分开来。 默认值为空字符串。
flumeEventFactory FlumeEventFactory 从Log4j事件生成Flume事件的工厂。 默认工厂是FlumeAvroAppender本身。
layout Layout 用于格式化LogEvent的布局。 如果未指定布局,则将使用RFC5424Layout。
lockTimeoutRetries integer 在写入Berkeley DB时发生LockConflictException时重试的次数。 默认值为5。
maxDelayMillis integer 发布批处理之前等待batchSize事件的最大毫秒数。
mdcExcludes String 以逗号分隔的mdc键列表,应从FlumeEvent中排除。 这与mdcIncludes属性互斥。
mdcIncludes String 以逗号分隔的mdc键列表,应包含在FlumeEvent中。 将排除列表中未找到的MDC中的任何键。 此选项与mdcExcludes属性互斥。
mdcRequired String 以逗号分隔的mdc键列表,必须存在于MDC中。 如果没有键,则抛出LoggingException。
mdcPrefix String 应添加到每个MDC密钥的字符串,以便将其与事件属性区分开来。 默认字符串是“mdc:”。
name String Appender的名字。
properties Property[] 一个或多个用于配置Flume代理的Property元素。 必须在没有代理名称的情况下配置属性(appender名称用于此目的),并且不能配置任何源。 可以使用“sources.log4j-source.interceptors”为源指定拦截器。 允许使用所有其他Flume配置属性。 指定代理和属性元素都将导致错误。当用于在Persistent模式下配置时,有效属性为:“keyProvider”,用于指定要为加密提供密钥的插件的名称。
requestTimeoutMillis integer Flume将在超时请求之前等待的毫秒数。
ignoreExceptions boolean 默认值为true,导致在将事件附加到内部记录然后被忽略时遇到异常。 设置为false时,异常将传播给调用者。 将此Appender包装在FailoverAppender中时,必须将此设置为false。
type enumeration “Avro”,“Embedded”或“Persistent”之一,用于指示需要哪种Appender变体。

使用主代理和辅助代理配置的FlumeAppender配置示例,压缩消息体,并使用RFC5424Layout格式化消息:

<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="warn" name="MyApp" packages="">
  <Appenders>
    <Flume name="eventLogger" compress="true">
      <Agent host="192.168.10.101" port="8800"/>
      <Agent host="192.168.10.102" port="8800"/>
      <RFC5424Layout enterpriseNumber="18060" includeMDC="true" appName="MyApp"/>
    </Flume>
  </Appenders>
  <Loggers>
    <Root level="error">
      <AppenderRef ref="eventLogger"/>
    </Root>
  </Loggers>
</Configuration>

使用主代理和辅助代理配置的FlumeAppender配置示例,压缩消息,使用RFC5424Layout格式化消息并将事件传递给嵌入式Flume代理。

<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="warn" name="MyApp" packages="">
  <Appenders>
    <Flume name="eventLogger" compress="true" type="Embedded">
      <Agent host="192.168.10.101" port="8800"/>
      <Agent host="192.168.10.102" port="8800"/>
      <RFC5424Layout enterpriseNumber="18060" includeMDC="true" appName="MyApp"/>
    </Flume>
    <Console name="STDOUT">
      <PatternLayout pattern="%d [%p] %c %m%n"/>
    </Console>
  </Appenders>
  <Loggers>
    <Logger name="EventLogger" level="info">
      <AppenderRef ref="eventLogger"/>
    </Logger>
    <Root level="warn">
      <AppenderRef ref="STDOUT"/>
    </Root>
  </Loggers>
</Configuration>

使用Flume配置属性配置主代理和辅助代理的FlumeAppender配置示例,压缩消息体,使用RFC5424Layout格式化消息并将事件传递给嵌入式Flume代理。

<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="error" name="MyApp" packages="">
  <Appenders>
    <Flume name="eventLogger" compress="true" type="Embedded">
      <Property name="channels">file</Property>
      <Property name="channels.file.type">file</Property>
      <Property name="channels.file.checkpointDir">target/file-channel/checkpoint</Property>
      <Property name="channels.file.dataDirs">target/file-channel/data</Property>
      <Property name="sinks">agent1 agent2</Property>
      <Property name="sinks.agent1.channel">file</Property>
      <Property name="sinks.agent1.type">avro</Property>
      <Property name="sinks.agent1.hostname">192.168.10.101</Property>
      <Property name="sinks.agent1.port">8800</Property>
      <Property name="sinks.agent1.batch-size">100</Property>
      <Property name="sinks.agent2.channel">file</Property>
      <Property name="sinks.agent2.type">avro</Property>
      <Property name="sinks.agent2.hostname">192.168.10.102</Property>
      <Property name="sinks.agent2.port">8800</Property>
      <Property name="sinks.agent2.batch-size">100</Property>
      <Property name="sinkgroups">group1</Property>
      <Property name="sinkgroups.group1.sinks">agent1 agent2</Property>
      <Property name="sinkgroups.group1.processor.type">failover</Property>
      <Property name="sinkgroups.group1.processor.priority.agent1">10</Property>
      <Property name="sinkgroups.group1.processor.priority.agent2">5</Property>
      <RFC5424Layout enterpriseNumber="18060" includeMDC="true" appName="MyApp"/>
    </Flume>
    <Console name="STDOUT">
      <PatternLayout pattern="%d [%p] %c %m%n"/>
    </Console>
  </Appenders>
  <Loggers>
    <Logger name="EventLogger" level="info">
      <AppenderRef ref="eventLogger"/>
    </Logger>
    <Root level="warn">
      <AppenderRef ref="STDOUT"/>
    </Root>
  </Loggers>
</Configuration

JDBCAppender

JDBCAppender使用标准JDBC将日志事件写入关系数据库表。 可以将其配置为使用JNDI DataSource或自定义工厂方法获取JDBC连接。 无论采用哪种方法,都必须由连接池支持。 否则,记录性能将受到很大影响。 如果配置的JDBC驱动程序支持批处理语句,并且bufferSize配置为正数,则将批处理日志事件。 请注意,从Log4j 2.8开始,有两种方法可以将日志事件配置为列映射:原始的ColumnConfig样式只允许字符串和时间戳,而新的ColumnMapping插件使用Log4j的内置类型转换来允许更多的数据类型( 这是与Cassandra Appender相同的插件)。

要在开发过程中快速启动,使用基于JNDI的连接源的替代方法是使用非池化DriverManager连接源。 此连接源使用JDBC连接字符串,用户名和密码。 您也可以选择使用属性。

JDBCAppender参数:

参数名称 类型 描述
name String 必需。附加器的名称。
ignoreExceptions boolean 默认值为true,导致在将事件附加到内部记录然后被忽略时遇到异常。 设置为false时,异常将传播给调用者。 将此Appender包装在FailoverAppender中时,必须将此设置为false。
filter Filter 一个过滤器,用于确定此Appender是否应该处理该事件。 使用CompositeFilter可以使用多个Filter。
bufferSize int 如果是大于0的整数,则会导致appender缓冲日志事件,并在缓冲区达到此大小时进行刷新。
connectionSource ConnectionSource 必需。应从中检索数据库连接的连接源。
tableName String 必需。要将日志事件插入的数据库表的名称。
columnConfigs ColumnConfig[] 必需(and/or columnMappings)。有关应插入日志事件数据的列以及如何插入该数据的信息。 这用多个<Column>元素表示。
columnMappings ColumnMapping[] 必需(和/或columnConfigs)。列映射配置列表。每列必须指定列名。每列可以具有由其完全限定类名指定的转换类型。默认情况下,转换类型为String。如果配置的类型与ReadOnlyStringMap / ThreadContextMap或ThreadContextStack分配兼容,则该列将分别使用MDC或NDC填充(这是特定于数据库的处理插入Map或List值的方式)。如果配置的类型与java.util.Date分配兼容,则日志时间戳将转换为该配置的日期类型。如果配置的类型与java.sql.Cloborjava.sql.NClob分配兼容,则格式化的事件将分别设置为Clob或NClob(类似于传统的ColumnConfig插件)。如果给出了文字属性,则其值将在INSERT查询中原样使用,而不进行任何转义。否则,指定的布局或模式将转换为已配置的类型并存储在该列中。
boolean false 设置为true时,日志事件将不会等待尝试重新连接,并且如果JDBC资源不可用,则会立即失败。 2.11.2中的新功能
long 5000 如果设置为大于0的值,则在发生错误后,JDBCDatabaseManager将在等待指定的毫秒数后尝试重新连接到数据库。 如果重新连接失败,则抛出异常(如果ignoreExceptions设置为false,则应用程序可以捕获该异常)。 2.11.2中的新功能。

配置JDBCAppender时,必须指定Appender从中获取JDBC连接的ConnectionSource实现。 您必须使用以下嵌套元素之一。

  • DataSource:使用JNDI。
  • ConnectionFactory:指向类 - 方法对以提供JDBC连接。
  • DriverManager: A quick and dirty way to get off the ground, no connection pooling。
  • PoolingDriver:使用Apache Commons DBCP提供连接池。

DataSource参数

参数名称 类型 描述
jndiName String 必填。 javax.sql.DataSource绑定的完整的前缀JNDI名称,例如java:/ comp / env / jdbc / LoggingDatabase。 DataSource必须由连接池支持; 否则,日志记录将非常缓慢。

ConnectionFactory参数

参数名称 类型 描述
class Class 必填。 包含用于获取JDBC连接的静态工厂方法的类的标准名称。
method Method 必填。 用于获取JDBC连接的静态工厂方法的名称。 此方法必须没有参数,其返回类型必须是java.sql.ConnectionorDataSource。 如果方法返回了Connections,它必须从连接池中获取它们(当Log4j完成它们时它们将被返回到池中); 否则,日志记录将非常缓慢。 如果该方法返回一个DataSource,则只会检索一次DataSource,并且由于相同的原因,它必须由连接池支持。

DriverManager参数

参数名称 类型 描述
connectionString String 必填。 特定于驱动程序的JDBC连接字符串。
userName String 数据库用户名。 您不能同时指定属性和用户名或密码。
password String 数据库密码。 您不能同时指定属性和用户名或密码。
driverClassName String JDBC驱动程序类名称。 某些旧的JDBC驱动程序只能通过按类名显式加载来发现。
properties Property[] 属性列表。 您不能同时指定属性和用户名或密码。

PoolingDriver参数(Apache Commons DBCP)

参数名称 类型 描述
DriverManager parameters DriverManager parameters 此连接源继承DriverManager连接源中的所有参数。
poolName String 用于池JDBC连接的池名称。 默认为示例。 如果要在其他位置使用池连接,可以使用JDBC连接字符串prefixjdbc:apache:commons:dbcp:后跟池名称。 例如:jdbc:apache:commons:dbcp:example。
PoolableConnectionFactory PoolableConnectionFactory element 定义PoolableConnectionFactory。

PoolableConnectionFactory参数(Apache Commons DBCP)

参数名称 类型 描述
autoCommitOnReturn boolean 请参阅Apache Commons DBCP PoolableConnectionFactory.
cacheState boolean 请参阅Apache Commons DBCP PoolableConnectionFactory.
ConnectionInitSqls Strings 请参阅Apache Commons DBCP PoolableConnectionFactory.
defaultAutoCommit boolean 请参阅Apache Commons DBCP PoolableConnectionFactory.
defaultCatalog String 请参阅Apache Commons DBCP PoolableConnectionFactory.
defaultQueryTimeoutSeconds integer 请参阅Apache Commons DBCP PoolableConnectionFactory.
defaultReadOnly boolean 请参阅Apache Commons DBCP PoolableConnectionFactory.
defaultTransactionIsolation integer 请参阅Apache Commons DBCP PoolableConnectionFactory.
disconnectionSqlCodes Strings 请参阅Apache Commons DBCP PoolableConnectionFactory.
fastFailValidation boolean 请参阅Apache Commons DBCP PoolableConnectionFactory.
maxConnLifetimeMillis long 请参阅Apache Commons DBCP PoolableConnectionFactory.
maxOpenPreparedStatements integer 请参阅Apache Commons DBCP PoolableConnectionFactory.
poolStatements boolean 请参阅Apache Commons DBCP PoolableConnectionFactory.
rollbackOnReturn boolean 请参阅Apache Commons DBCP PoolableConnectionFactory.
validationQuery String 请参阅Apache Commons DBCP PoolableConnectionFactory.
validationQueryTimeoutSeconds integer 请参阅Apache Commons DBCP PoolableConnectionFactory.

配置JDBCAppender时,使用嵌套的Column元素指定应该写入表中的哪些列以及如何写入它们。 JDBCAppender使用此信息来制定PreparedStatement以插入没有SQL注入漏洞的记录。

Column 参数

参数名称 类型 描述
name String 必填。 数据库列的名称。
pattern String 使用此属性可使用PatternLayout模式在此列中的日志事件中插入一个或多个值。 只需在此属性中指定任何合法模式即可。 必须指定此属性,literal或isEventTimestamp =“true”,但不能超过其中一个。
literal String 使用此属性可在此列中插入文字值。 该值将直接包含在插入SQL中,不带任何引号(这意味着如果您希望它是一个字符串,则您的值应该包含单引号,如下所示:literal =“’Literal String’”)。 这对于不支持标识列的数据库特别有用。 例如,如果您使用的是Oracle,则可以使用specifyliteral =“NAME_OF_YOUR_SEQUENCE.NEXTVAL”在ID列中插入唯一ID。 必须指定此属性,pattern或isEventTimestamp =“true”,但不能超过其中一个。
parameter String 使用此属性插入带有参数标记’?’的表达式 在这个专栏中。 该值将直接包含在插入SQL中,没有任何引用(这意味着如果您希望这是一个字符串,您的值应该包含它周围的单引号:<ColumnMapping name =“instant”parameter =“TIMESTAMPADD( ‘MILLISECOND’,?,TIMESTAMP’1970-01-01’)“/>你只能指定一个文字或参数。
isEventTimestamp boolean 使用此属性可在此列中插入事件时间戳,该列应为SQL日期时间。 该值将作为java.sql.Types.TIMESTAMP插入。 必须指定此属性(等于true),pattern或isEventTimestamp,但不能超过其中一个。
isUnicode boolean 除非指定了pattern,否则将忽略此属性。 如果为true或省略(默认),则该值将作为unicode(setNString或setNClob)插入。 否则,该值将插入非unicode(setString或setClob)。
isClob boolean 除非指定了pattern,否则将忽略此属性。 使用此属性指示该列存储字符大对象(CLOB)。 如果为true,则该值将作为CLOB(setCloborsetNClob)插入。 如果为false或省略(默认),则该值将作为VARCHAR或NVARCHAR(setString或setNString)插入。

ColumnMapping参数

参数名称 类型 描述
name String 必填。 数据库列的名称。
pattern String 使用此属性可使用PatternLayout模式在此列中的日志事件中插入一个或多个值。 只需在此属性中指定任何合法模式即可。 必须指定此属性,literal或isEventTimestamp =“true”,但不能超过其中一个。
literal String 使用此属性可在此列中插入文字值。 该值将直接包含在插入SQL中,不带任何引号(这意味着如果您希望它是一个字符串,则您的值应该包含单引号,如下所示:literal =“’Literal String’”)。 这对于不支持标识列的数据库特别有用。 例如,如果您使用的是Oracle,则可以指定literal =“NAME_OF_YOUR_SEQUENCE.NEXTVAL”以在ID列中插入唯一ID。 必须指定此属性,pattern或isEventTimestamp =“true”,但不能超过其中一个。
layout Layout 用于格式化LogEvent的布局。
type String 转换类型名称,完全限定的类名称。

以下是JDBCAppender的一些示例配置,以及一个使用共享池和共享DBCP来共享数据库连接的示例工厂实现:

<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="error">
  <Appenders>
    <JDBC name="databaseAppender" tableName="dbo.application_log">
      <DataSource jndiName="java:/comp/env/jdbc/LoggingDataSource" />
      <Column name="eventDate" isEventTimestamp="true" />
      <Column name="level" pattern="%level" />
      <Column name="logger" pattern="%logger" />
      <Column name="message" pattern="%message" />
      <Column name="exception" pattern="%ex{full}" />
    </JDBC>
  </Appenders>
  <Loggers>
    <Root level="warn">
      <AppenderRef ref="databaseAppender"/>
    </Root>
  </Loggers>
</Configuration>
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="error">
  <Appenders>
    <JDBC name="databaseAppender" tableName="LOGGING.APPLICATION_LOG">
      <ConnectionFactory class="net.example.db.ConnectionFactory" method="getDatabaseConnection" />
      <Column name="EVENT_ID" literal="LOGGING.APPLICATION_LOG_SEQUENCE.NEXTVAL" />
      <Column name="EVENT_DATE" isEventTimestamp="true" />
      <Column name="LEVEL" pattern="%level" />
      <Column name="LOGGER" pattern="%logger" />
      <Column name="MESSAGE" pattern="%message" />
      <Column name="THROWABLE" pattern="%ex{full}" />
    </JDBC>
  </Appenders>
  <Loggers>
    <Root level="warn">
      <AppenderRef ref="databaseAppender"/>
    </Root>
  </Loggers>
</Configuration>
package net.example.db;
 
import java.sql.Connection;
import java.sql.SQLException;
import java.util.Properties;
 
import javax.sql.DataSource;
 
import org.apache.commons.dbcp.DriverManagerConnectionFactory;
import org.apache.commons.dbcp.PoolableConnection;
import org.apache.commons.dbcp.PoolableConnectionFactory;
import org.apache.commons.dbcp.PoolingDataSource;
import org.apache.commons.pool.impl.GenericObjectPool;
 
public class ConnectionFactory {
    private static interface Singleton {
        final ConnectionFactory INSTANCE = new ConnectionFactory();
    }
 
    private final DataSource dataSource;
 
    private ConnectionFactory() {
        Properties properties = new Properties();
        properties.setProperty("user", "logging");
        properties.setProperty("password", "abc123"); // or get properties from some configuration file
 
        GenericObjectPool<PoolableConnection> pool = new GenericObjectPool<PoolableConnection>();
        DriverManagerConnectionFactory connectionFactory = new DriverManagerConnectionFactory(
                "jdbc:mysql://example.org:3306/exampleDb", properties
        );
        new PoolableConnectionFactory(
                connectionFactory, pool, null, "SELECT 1", 3, false, false, Connection.TRANSACTION_READ_COMMITTED
        );
 
        this.dataSource = new PoolingDataSource(pool);
    }
 
    public static Connection getDatabaseConnection() throws SQLException {
        return Singleton.INSTANCE.dataSource.getConnection();
    }
}

这个appender是MapMessage-aware

以下配置使用MessageLayout指示Appender在设置Appender的SQL INSERT语句的值时应将MapMessage的键与ColumnMappings的名称匹配。 这使您可以基于Log4j MapMessage而不是LogEvents中的值,在数据库表中插入自定义值的行。

<Configuration status="debug">
 
  <Appenders>
    <Console name="STDOUT">
      <PatternLayout pattern="%C{1.} %m %level MDC%X%n"/>
    </Console>
    <Jdbc name="databaseAppender" tableName="dsLogEntry" ignoreExceptions="false">
      <DataSource jndiName="java:/comp/env/jdbc/TestDataSourceAppender" />
      <ColumnMapping name="Id" />
      <ColumnMapping name="ColumnA" />
      <ColumnMapping name="ColumnB" />
      <MessageLayout />
    </Jdbc>
  </Appenders>
 
  <Loggers>
    <Logger name="org.apache.logging.log4j.core.appender.db" level="debug" additivity="false">
      <AppenderRef ref="databaseAppender" />
    </Logger>
 
    <Root level="fatal">
      <AppenderRef ref="STDOUT"/>
    </Root>
  </Loggers>
 
</Configuration>

JMS Appender

MS Appender将格式化的日志事件发送到JMS目的地。

请注意,在Log4j 2.0中,此appender被拆分为JMSQueueAppender和JMSTopicAppender。 从Log4j 2.1开始,这些appender被组合到JMS Appender中,它不区分Queue和Topic。 但是,为2.0编写的使用或元素的配置将继续使用新的配置元素。

JMS Appender参数

参数名称 类型 是否必填 描述
factoryBindingName String Required 要在提供ConnectionFactory的Context中定位的名称。 这也可以是ConnectionFactory的任何子接口。
factoryName String Required 应该用于定义INITIAL_CONTEXT_FACTORY中定义的初始上下文工厂的完全限定类名。 如果在没有providerURL的情况下指定了factoryName,则会记录警告消息,因为这可能会导致问题。
filter Filter null 一个过滤器,用于确定此Appender是否应该处理该事件。 使用CompositeFilter可以使用多个Filter。
layout Layout Required 用于格式化LogEvent的布局。 自2.9以来的新版本,在以前的版本中,SerializedLayout是默认的。
name String Required Appender的名字。
password String null 用于创建JMS连接的密码。
providerURL String Required PROVIDER_URL定义的提供程序的URL。
destinationBindingName String Required 用于定位目标的名称。 这可以是Queue或Topic,因此,属性名称queueBindingName和topicBindingName是别名,以保持与Log4j 2.0 JMS appender的兼容性。
securityPrincipalName String null SECURITY_PRINCIPAL指定的Principal身份的名称。 如果指定securityPrincipalName而没有securityCredentials,则会记录一条警告消息,因为这可能会导致问题。
securityCredentials String null 由SCIURITY_CREDENTIALS指定的主体的安全凭证。
ignoreExceptions boolean true 如果为true,则在追加事件时捕获的异常将在内部记录,然后被忽略。 当错误异常传播给调用者时。 将此Appender包装在FailoverAppender中时,必须将此参数设置为false。
immediateFail boolean false 设置为true时,日志事件将不会等待尝试重新连接,如果JMS资源不可用,则会立即失败。 2.9的新功能。
reconnectIntervalMillis long 5000 如果设置为大于0的值,则在发生错误后,JMSManager将在等待指定的毫秒数后尝试重新连接到代理。 如果重新连接失败,则抛出异常(如果ignoreExceptions设置为false,则应用程序可以捕获该异常)。 2.9的新功能。
urlPkgPrefixes String null 用于工厂类的类名的以冒号分隔的包前缀列表,它将创建由URLLK_P_PGFREES定义的URL上下文工厂。
userName String null 用于创建JMS连接的用户标识

以下是JMS Appender配置示例:

<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="warn" name="MyApp">
  <Appenders>
    <JMS name="jmsQueue" destinationBindingName="MyQueue"
         factoryBindingName="MyQueueConnectionFactory">
      <JsonLayout properties="true"/>
    </JMS>
  </Appenders>
  <Loggers>
    <Root level="error">
      <AppenderRef ref="jmsQueue"/>
    </Root>
  </Loggers>
</Configuration>

要将Log4j MapMessages映射到JMS javax.jms.MapMessages,请使用< MessageLayout />(自2.9以来)将appender的布局设置为MessageLayout:

<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="warn" name="MyApp">
  <Appenders>
    <JMS name="jmsQueue" destinationBindingName="MyQueue"
         factoryBindingName="MyQueueConnectionFactory">
      <MessageLayout />
    </JMS>
  </Appenders>
  <Loggers>
    <Root level="error">
      <AppenderRef ref="jmsQueue"/>
    </Root>
  </Loggers>
</Configuration>

JPAAppender

从Log4j 2.11.0开始,JPA支持已从现有模块logj-core转移到新模块log4j-jpa。

JPAAppender使用Java Persistence API 2.1将日志事件写入关系数据库表。 它需要API和提供程序实现在类路径上。 它还需要一个装饰实体,配置为持久保存到所需的表。 实体应该扩展org.apache.logging.log4j.core.appender.db.jpa.BasicLogEventEntity(如果你最想使用默认映射)并提供至少一个@Id属性,或者org.apache.logging.log4j .core.appender.db.jpa.AbstractLogEventWrapperEntity(如果要显着自定义映射)。 有关更多信息,请参阅这两个类的Javadoc。 您还可以查阅这两个类的源代码,作为如何实现该实体的示例。

JPAAppender参数

参数名称 类型 描述
name String 必填。 Appender的名字。
ignoreExceptions boolean 默认值为true,导致在将事件附加到内部记录然后被忽略时遇到异常。 设置为false时,异常将传播给调用者。 将此Appender包装在FailoverAppender中时,必须将此参数设置为false。
filter Filter 一个过滤器,用于确定此Appender是否应该处理该事件。 使用CompositeFilter可以使用多个Filter。
bufferSize int 如果是大于0的整数,则会导致appender缓冲日志事件,并在缓冲区达到此大小时进行刷新。
entityClassName String 必填。 具有JPA注释的具体LogEventWrapperEntity实现的完全限定名称,该注释将其映射到数据库表。
persistenceUnitName String 必填。 应该用于保存日志事件的JPA持久性单元的名称。

以下是JPAAppender的示例配置。 第一个XML示例是Log4j配置文件,第二个是persistence.xml文件。 这里假设是EclipseLink,但任何JPA 2.1或更高版本的提供程序都可以。 您应始终为记录创建单独的持久性单元,原因有两个。 首先,< shared-cache-mode>必须设置为“NONE”,这在正常的JPA使用中通常是不希望的。 此外,出于性能原因,日志记录实体应该在其自己的持久性单元中与所有其他实体隔离,并且您应该使用非JTA数据源。 请注意,您的持久性单元还必须包含所有org.apache.logging.log4j.core.appender.db.jpa的< class>元素。 转换器转换器类。

<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="error">
  <Appenders>
    <JPA name="databaseAppender" persistenceUnitName="loggingPersistenceUnit"
         entityClassName="com.example.logging.JpaLogEntity" />
  </Appenders>
  <Loggers>
    <Root level="warn">
      <AppenderRef ref="databaseAppender"/>
    </Root>
  </Loggers>
</Configuration>
<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="http://xmlns.jcp.org/xml/ns/persistence"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence
                                 http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd"
             version="2.1">
 
  <persistence-unit name="loggingPersistenceUnit" transaction-type="RESOURCE_LOCAL">
    <provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
    <class>org.apache.logging.log4j.core.appender.db.jpa.converter.ContextMapAttributeConverter</class>
    <class>org.apache.logging.log4j.core.appender.db.jpa.converter.ContextMapJsonAttributeConverter</class>
    <class>org.apache.logging.log4j.core.appender.db.jpa.converter.ContextStackAttributeConverter</class>
    <class>org.apache.logging.log4j.core.appender.db.jpa.converter.ContextStackJsonAttributeConverter</class>
    <class>org.apache.logging.log4j.core.appender.db.jpa.converter.MarkerAttributeConverter</class>
    <class>org.apache.logging.log4j.core.appender.db.jpa.converter.MessageAttributeConverter</class>
    <class>org.apache.logging.log4j.core.appender.db.jpa.converter.StackTraceElementAttributeConverter</class>
    <class>org.apache.logging.log4j.core.appender.db.jpa.converter.ThrowableAttributeConverter</class>
    <class>com.example.logging.JpaLogEntity</class>
    <non-jta-data-source>jdbc/LoggingDataSource</non-jta-data-source>
    <shared-cache-mode>NONE</shared-cache-mode>
  </persistence-unit>
 
</persistence>
package com.example.logging;
...
@Entity
@Table(name="application_log", schema="dbo")
public class JpaLogEntity extends BasicLogEventEntity {
    private static final long serialVersionUID = 1L;
    private long id = 0L;
 
    public TestEntity() {
        super(null);
    }
    public TestEntity(LogEvent wrappedEvent) {
        super(wrappedEvent);
    }
 
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id")
    public long getId() {
        return this.id;
    }
 
    public void setId(long id) {
        this.id = id;
    }
 
    // If you want to override the mapping of any properties mapped in BasicLogEventEntity,
    // just override the getters and re-specify the annotations.
}
package com.example.logging;
...
@Entity
@Table(name="application_log", schema="dbo")
public class JpaLogEntity extends AbstractLogEventWrapperEntity {
    private static final long serialVersionUID = 1L;
    private long id = 0L;
 
    public TestEntity() {
        super(null);
    }
    public TestEntity(LogEvent wrappedEvent) {
        super(wrappedEvent);
    }
 
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "logEventId")
    public long getId() {
        return this.id;
    }
 
    public void setId(long id) {
        this.id = id;
    }
 
    @Override
    @Enumerated(EnumType.STRING)
    @Column(name = "level")
    public Level getLevel() {
        return this.getWrappedEvent().getLevel();
    }
 
    @Override
    @Column(name = "logger")
    public String getLoggerName() {
        return this.getWrappedEvent().getLoggerName();
    }
 
    @Override
    @Column(name = "message")
    @Convert(converter = MyMessageConverter.class)
    public Message getMessage() {
        return this.getWrappedEvent().getMessage();
    }
    ...
}

HttpAppender

HttpAppender通过HTTP发送日志事件。 必须提供Layout以格式化LogEvent。
将等待来自服务器的响应,如果没有收到2xx响应则抛出错误。
使用HttpURLConnection实现。

HttpAppender参数

参数名称 类型 描述
name String Appender的名字。
filter Filter 一个过滤器,用于确定此Appender是否应该处理该事件。 使用CompositeFilter可以使用多个Filter。
layout Layout 用于格式化LogEvent的布局。
Ssl SslConfiguration 包含https的KeyStore和TrustStore的配置。 可选,如果未指定,则使用Java运行时默认值。 请参阅SSL
verifyHostname boolean 是否根据证书验证服务器主机名。 仅对https有效。 可选,默认为true
url string 要使用的URL。 URL方案必须是“http”或“https”。
method string 要使用的HTTP方法。 可选,默认为“POST”。
connectTimeoutMillis integer 连接超时(以毫秒为单位)。 可选,默认为0(无限超时)。
readTimeoutMillis integer 套接字读取超时(以毫秒为单位)。 可选,默认为0(无限超时)。
headers Property[] 要使用的其他HTTP标头。 这些值支持lookups
ignoreExceptions boolean 默认值为true,导致在将事件附加到内部记录然后被忽略时遇到异常。 设置为false时,异常将传播给调用者。 将此Appender包装在FailoverAppender中时,必须将此参数设置为false。

以下是HttpAppender配置代码示例:

<?xml version="1.0" encoding="UTF-8"?>
  ...
  <Appenders>
    <Http name="Http" url="https://localhost:9200/test/log4j/">
      <Property name="X-Java-Runtime" value="$${java:runtime}" />
      <JsonLayout properties="true"/>
      <SSL>
        <KeyStore   location="log4j2-keystore.jks" passwordEnvironmentVariable="KEYSTORE_PASSWORD"/>
        <TrustStore location="truststore.jks"      passwordFile="${sys:user.home}/truststore.pwd"/>
      </SSL>
    </Http>
  </Appenders>

KafkaAppender

KafkaAppender将事件记录到Apache Kafka。 每个日志事件都作为Kafka记录发送。

KafkaAppender参数

参数名称 类型 描述
topic String 要使用的Kafka主题。 必填。
key String 每条消息都将发送给Kafka的密钥。 可选值默认为null。 可以包括任何一个连接。
filter Filter 一个过滤器,用于确定此Appender是否应该处理该事件。 使用CompositeFilter可以使用多个Filter。
layout Layout 用于格式化LogEvent的布局。 必需,没有默认值。自2.9以来,在以前的版本中<PatternLayout pattern =“%m”/>是默认值。
name String Appender的名字。 必填。
ignoreExceptions boolean 默认值为true,导致在将事件附加到内部记录然后被忽略时遇到异常。 设置为false时,异常将传播给调用者。 将此Appender包装在FailoverAppender中时,必须将此参数设置为false。
syncSend boolean 默认值为true,导致发送阻止,直到Kafka服务器确认记录为止。 当设置tofalsesends立即返回时,允许更低的延迟和显着更高的吞吐量。自2.8以来。 请注意,这是一个新增功能,尚未经过广泛测试。 发送到Kafka的任何失败都将报告为StatusLogger的错误,并且将丢弃日志事件(ignoreExceptions参数将无效)。 日志事件可能无序到达Kafka服务器。
properties Property[] 您可以在Kafka生产者属性中设置属性。 您需要设置bootstrap.servers属性,其他人有合理的默认值。 不要设置value.serializer和key.serializer属性。

以下是KafkaAppender配置代码示例:

<?xml version="1.0" encoding="UTF-8"?>
  ...
  <Appenders>
    <Kafka name="Kafka" topic="log-test">
      <PatternLayout pattern="%date %message"/>
        <Property name="bootstrap.servers">localhost:9092</Property>
    </Kafka>
  </Appenders>

此appender默认是同步的,并且将阻塞,直到Kafka服务器确认记录为止,可以使用timeout.ms属性设置超时(默认为30秒)。 使用Async appender换行和/或将syncSend设置为false以异步记录。

这个appender需要Kafka客户端库。 请注意,您需要使用与所使用的Kafka服务器匹配的Kafka客户端库版本。

注意:确保不要让org.apache.kafka登录到DEBUG级别的Kafka appender,因为这会导致递归日志记录

<?xml version="1.0" encoding="UTF-8"?>
 ...
 <Loggers>
   <Root level="DEBUG">
     <AppenderRef ref="Kafka"/>
   </Root>
   <Logger name="org.apache.kafka" level="INFO" /> <!-- avoid recursive logging -->
 </Loggers>

MemoryMappedFileAppender

2.1以来的新功能。 请注意,这是一个新增功能,虽然它已经在多个平台上进行了测试,但它没有其他文件追加器那么多的跟踪记录。

MemoryMappedFileAppender将指定文件的一部分映射到内存中,并将日志事件写入此内存,依赖操作系统的虚拟内存管理器将更改同步到存储设备。 使用内存映射文件的主要好处是I / O性能。 这个appender可以简单地改变程序的本地内存,而不是进行系统调用来写入磁盘,这个内存的速度要快几个数量级。 此外,在大多数操作系统中,实际映射的内存区域是内核的页面缓存(文件缓存),这意味着不需要在用户空间中创建副本。 (TODO:将此appender的性能与RandomAccessFileAppender和FileAppender进行比较的性能测试。)

将文件区域映射到内存有一些开销,特别是非常大的区域(半千兆字节或更多)。 默认区域大小为32 MB,这应该在重映射操作的频率和持续时间之间达到合理的平衡。 (TODO:性能测试重新映射各种尺寸。)

与FileAppender和RandomAccessFileAppender类似,MemoryMappedFileAppender使用MemoryMappedFileManager实际执行文件I / O. 虽然无法共享来自不同Configuration的MemoryMappedFileAppender,但MemoryMappedFileManagers可以是Manager可访问的。 例如,servlet容器中的两个Web应用程序可以拥有自己的配置,并且如果Log4j位于两个共用的ClassLoader中,则可以安全地写入同一文件。

MemoryMappedFileAppender参数

参数名称 类型 描述
append boolean 如果为true - 默认值,则记录将附加到文件末尾。 设置为false时,将在写入新记录之前清除该文件。
fileName String 要写入的文件的名称。 如果该文件或其任何父目录不存在,则将创建它们。
filters Filter 一个过滤器,用于确定此Appender是否应该处理该事件。 使用CompositeFilter可以使用多个Filter。
immediateFlush boolean 设置为true时,每次写入后都会调用MappedByteBuffer.force()。 这样可以保证将数据写入存储设备。此参数的默认值为false。 这意味着即使Java进程崩溃,数据也会写入存储设备,但如果操作系统崩溃,可能会丢失数据。请注意,在每个日志事件上手动强制同步会失去使用内存的大部分性能优势 映射文件。每次写入后刷新仅在将此appender与同步记录器一起使用时才有用。 即使immediateFlush设置为false,异步记录器和追加器也会在一批事件结束时自动刷新。 这也保证了数据被写入磁盘但效率更高
regionLength int 映射区域的长度,默认为32 MB(32 * 1024 * 1024字节)。 此参数必须介于256和1,073,741,824之间(1 GB或2 ^ 30); 超出此范围的值将调整为最接近的有效值。 Log4j将指定值四舍五入到最接近的2的幂。
layout Layout 用于格式化LogEvent的布局。 如果未提供布局,则将使用默认的模式布局“%m%n”。
name String Appender的名字。
ignoreExceptions boolean 默认值为true,导致在将事件附加到内部记录然后被忽略时遇到异常。 设置为false时,异常将传播给调用者。 将此Appender包装在FailoverAppender中时,必须将此参数设置为false。

以下是MemoryMappedFile配置示例:

<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="warn" name="MyApp" packages="">
  <Appenders>
    <MemoryMappedFile name="MyFile" fileName="logs/app.log">
      <PatternLayout>
        <Pattern>%d %p %c{1.} [%t] %m%n</Pattern>
      </PatternLayout>
    </MemoryMappedFile>
  </Appenders>
  <Loggers>
    <Root level="error">
      <AppenderRef ref="MyFile"/>
    </Root>
  </Loggers>
</Configuration>

NoSQLAppender

NoSQLAppender使用内部轻量级提供程序接口将日志事件写入NoSQL数据库。 MongoDB和Apache CouchDB目前存在Provider实现,编写自定义提供程序非常简单。

参数名称 类型 描述
name String 必填。 Appender的名字。
ignoreExceptions boolean 默认值为true,导致在将事件附加到内部记录然后被忽略时遇到异常。 设置为false时,异常将传播给调用者。 将此Appender包装在FailoverAppender中时,必须将此参数设置为false。
filter Filter 一个过滤器,用于确定此Appender是否应该处理该事件。 使用CompositeFilter可以使用多个Filter。
bufferSize int 如果是大于0的整数,则会导致appender缓冲日志事件,并在缓冲区达到此大小时进行刷新。
NoSqlProvider NoSQLProvider<C extends NoSQLConnection<W, T extends NoSQLObject<W>>> 必填。 提供与所选NoSQL数据库的连接的NoSQL提供程序。

您可以通过在< NoSql>元素中指定适当的配置元素来指定要使用的NoSQL提供程序。 目前支持的类型是< MongoDb>和< CouchDb>。 要创建自己的自定义提供程序,请阅读NoSQLProvider,NoSQLConnection和NoSQLObject类的JavaDoc以及有关创建Log4j插件的文档。 我们建议您查看MongoDB和CouchDB提供程序的源代码,作为创建自己的提供程序的指南。

以下示例演示了如果以JSON格式表示,日志事件如何在NoSQL数据库中保留:

{
    "level": "WARN",
    "loggerName": "com.example.application.MyClass",
    "message": "Something happened that you might want to know about.",
    "source": {
        "className": "com.example.application.MyClass",
        "methodName": "exampleMethod",
        "fileName": "MyClass.java",
        "lineNumber": 81
    },
    "marker": {
        "name": "SomeMarker",
        "parent" {
            "name": "SomeParentMarker"
        }
    },
    "threadName": "Thread-1",
    "millis": 1368844166761,
    "date": "2013-05-18T02:29:26.761Z",
    "thrown": {
        "type": "java.sql.SQLException",
        "message": "Could not insert record. Connection lost.",
        "stackTrace": [
                { "className": "org.example.sql.driver.PreparedStatement$1", "methodName": "responder", "fileName": "PreparedStatement.java", "lineNumber": 1049 },
                { "className": "org.example.sql.driver.PreparedStatement", "methodName": "executeUpdate", "fileName": "PreparedStatement.java", "lineNumber": 738 },
                { "className": "com.example.application.MyClass", "methodName": "exampleMethod", "fileName": "MyClass.java", "lineNumber": 81 },
                { "className": "com.example.application.MainClass", "methodName": "main", "fileName": "MainClass.java", "lineNumber": 52 }
        ],
        "cause": {
            "type": "java.io.IOException",
            "message": "Connection lost.",
            "stackTrace": [
                { "className": "java.nio.channels.SocketChannel", "methodName": "write", "fileName": null, "lineNumber": -1 },
                { "className": "org.example.sql.driver.PreparedStatement$1", "methodName": "responder", "fileName": "PreparedStatement.java", "lineNumber": 1032 },
                { "className": "org.example.sql.driver.PreparedStatement", "methodName": "executeUpdate", "fileName": "PreparedStatement.java", "lineNumber": 738 },
                { "className": "com.example.application.MyClass", "methodName": "exampleMethod", "fileName": "MyClass.java", "lineNumber": 81 },
                { "className": "com.example.application.MainClass", "methodName": "main", "fileName": "MainClass.java", "lineNumber": 52 }
            ]
        }
    },
    "contextMap": {
        "ID": "86c3a497-4e67-4eed-9d6a-2e5797324d7b",
        "username": "JohnDoe"
    },
    "contextStack": [
        "topItem",
        "anotherItem",
        "bottomItem"
    ]
}

NoSQLAppender for MongoDB

从Log4 2.11.0开始,我们提供了两个MongoDB模块:

  • log4j-mongodb2定义与MongoDB驱动程序版本2匹配的配置元素MongoDb2。
  • log4j-mongodb3定义了匹配MongoDB驱动程序版本3的配置元素MongoDb3。
    我们不再提供log4j-mongodb模块。
    模块log4j-mongodb2将旧配置元素MongoDb别名为MongoDb2。

MongoDB 2的NoSQLAppender

本节详细介绍使用MongoDB驱动程序版本2的MongoDB NoSQLAppender提供程序的特殊性.NoSQLAppender Appender使用内部轻量级提供程序接口将日志事件写入NoSQL数据库。

MongoDB2提供的参数

参数名称 类型 描述
collectionName String 必填。 要将事件插入的MongoDB集合的名称。
writeConcernConstant Field 默认情况下,MongoDB提供程序使用com.mongodb.WriteConcern.ACKNOWLEDGED指令插入记录。 使用此可选属性指定除ACKNOWLEDGED之外的常量的名称。
writeConcernConstantClass Class 如果指定writeConcernConstant,则可以使用此属性指定除com.mongodb.WriteConcernt之外的类,以查找常量(创建自己的自定义指令)。
factoryClassName Class 要提供与MongoDB数据库的连接,可以使用此属性和factoryMethodName指定要从中获取连接的类和静态方法。 该方法必须返回acom.mongodb。 DB或acom.mongodb.MongoClient。 如果未对数据库进行身份验证,则还必须指定用户名和密码。 如果使用工厂方法提供连接,则不得指定databaseName,server或port属性。
factoryMethodName Method 请参阅文档以获取属性factoryClassName。
databaseName String 如果未指定用于提供MongoDB连接的factoryClassName和factoryMethodName,则必须使用此属性指定MongoDB数据库名称。 您还必须指定用户名和密码。 您也可以选择指定服务器(默认为localhost)和aport(默认为默认的MongoDB端口)。
server String 请参阅属性databaseName的文档。
port int 请参阅属性databaseName的文档。
username String 请参阅属性databaseName和factoryClassName的文档。
password String 请参阅属性databaseName和factoryClassName的文档。
capped boolean 启用对上限集合的支持
collectionSize int 指定要启用的上限集合的大小(以字节为单位)。 最小大小为4096字节,较大的大小将增加到256的最接近的整数倍。有关详细信息,请参阅上面链接的上限集合文档。

这个appender是 MapMessage-aware。

以下是NoSQLAppender和MongoDB2提供程序的一些示例配置:

<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="error">
  <Appenders>
    <NoSql name="databaseAppender">
      <MongoDb2 databaseName="applicationDb" collectionName="applicationLog" server="mongo.example.org"
               username="loggingUser" password="abc123" />
    </NoSql>
  </Appenders>
  <Loggers>
    <Root level="warn">
      <AppenderRef ref="databaseAppender"/>
    </Root>
  </Loggers>
</Configuration>
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="error">
  <Appenders>
    <NoSql name="databaseAppender">
      <MongoDb2 collectionName="applicationLog" factoryClassName="org.example.db.ConnectionFactory"
               factoryMethodName="getNewMongoClient" />
    </NoSql>
  </Appenders>
  <Loggers>
    <Root level="warn">
      <AppenderRef ref="databaseAppender"/>
    </Root>
  </Loggers>
</Configuration>

从Log4j版本2.11.0开始,提供程序元素名称为MongoDb2。 名称MongoDb现在是MongoDb2的弃用别名。

MongoDB 3的NoSQLAppender

本节详细介绍使用MongoDB驱动程序版本3的MongoDB NoSQLAppender提供程序的特殊化.NoSQLAppender Appender使用内部轻量级提供程序接口将日志事件写入NoSQL数据库。

MongoDB3提供的参数

参数名称 类型 描述
collectionName String 必填。 要将事件插入的MongoDB集合的名称。
writeConcernConstant Field 默认情况下,MongoDB提供程序使用com.mongodb.WriteConcern.ACKNOWLEDGED指令插入记录。 使用此可选属性指定除ACKNOWLEDGED之外的常量的名称。
writeConcernConstantClass Class 如果指定writeConcernConstant,则可以使用此属性指定com.mongodb.WriteConcernto以外的类来查找常量(以创建自己的自定义指令)。
factoryClassName Class 要提供与MongoDB数据库的连接,可以使用此属性和factoryMethodName指定要从中获取连接的类和静态方法。 该方法必须返回acom.mongodb.client.MongoDatabase或acom.mongodb.MongoClient。 如果未对com.mongodb.client.MongoDatabase进行身份验证,则还必须指定用户名和密码。 如果使用工厂方法提供连接,则不得指定databaseName,server或port属性。
factoryMethodName Method 请参阅文档以获取属性factoryClassName。
databaseName String 如果未指定用于提供MongoDB连接的factoryClassName和factoryMethodName,则必须使用此属性指定MongoDB数据库名称。 您还必须指定用户名和密码。 您也可以选择指定服务器(默认为localhost)和端口(默认为默认的MongoDB端口)。
server String 请参阅属性databaseName的文档。
port int 请参阅属性databaseName的文档。
username String 请参阅属性databaseName和factoryClassName的文档。
password String 请参阅属性databaseName和factoryClassName的文档。
capped boolean 启用对上限集合的支持
collectionSize int 指定要启用的上限集合的大小(以字节为单位)。 最小大小为4096字节,较大的大小将增加到256的最接近的整数倍。有关详细信息,请参阅上面链接的上限集合文档。

这个appender是MapMessage-aware。

以下是NoSQLAppender和MongoDB3提供程序的一些示例配置:

<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="error">
  <Appenders>
    <NoSql name="databaseAppender">
      <MongoDb3 databaseName="applicationDb" collectionName="applicationLog" server="mongo.example.org"
               username="loggingUser" password="abc123" />
    </NoSql>
  </Appenders>
  <Loggers>
    <Root level="warn">
      <AppenderRef ref="databaseAppender"/>
    </Root>
  </Loggers>
</Configuration>
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="error">
  <Appenders>
    <NoSql name="databaseAppender">
      <MongoDb3 collectionName="applicationLog" factoryClassName="org.example.db.ConnectionFactory"
               factoryMethodName="getNewMongoClient" />
    </NoSql>
  </Appenders>
  <Loggers>
    <Root level="warn">
      <AppenderRef ref="databaseAppender"/>
    </Root>
  </Loggers>
</Configuration>
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,839评论 6 482
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,543评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 153,116评论 0 344
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,371评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,384评论 5 374
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,111评论 1 285
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,416评论 3 400
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,053评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,558评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,007评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,117评论 1 334
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,756评论 4 324
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,324评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,315评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,539评论 1 262
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,578评论 2 355
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,877评论 2 345

推荐阅读更多精彩内容

  • 在应用程序中添加日志记录总的来说基于三个目的:监视代码中变量的变化情况,周期性的记录到文件中供其他应用进行统计分析...
    时待吾阅读 4,953评论 1 13
  • 在应用程序中添加日志记录总的来说基于三个目的:监视代码中变量的变化情况,周期性的记录到文件中供其他应用进行统计分析...
    时待吾阅读 4,966评论 0 6
  • 架构 架构 主要组件 Log4J类结构如下图所示: 使用Log4j 2 API的应用程序将从LogManager请...
    在下喵星人阅读 2,122评论 0 0
  • from:https://www.cnblogs.com/ITtangtang/p/3926665.html一、L...
    enshunyan阅读 3,276评论 0 0
  • 公司:三亚蔚蓝时代实业有限公司 【日精进打卡第188天】 【知-学习】 陪伴家人 《六项精进》背诵 1遍 累计24...
    胖姑阅读 100评论 0 0