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.AsyncQueueFullPolicy和log4j2.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支持三种操作模式。
- 它可以充当远程Flume客户端,通过Avro将Flume事件发送到配置了Avro Source的Flume Agent。
- 它可以作为嵌入式Flume Agent,Flume事件直接传递到Flume进行处理。
- 它可以将事件持久保存到本地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)
配置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>