Appenders

Appender 负责将 LogEvents 传递到其目的地。每个 Appender 必须实现Appender接口。大多数 Appender 都会扩展AbstractAppender,从而增加LifecycleFilterable支持。生命周期允许组件在配置完成后完成初始化,并在关机期间执行清理。可过滤允许组件具有附加的过滤器,这些过滤器将在事件处理期间进行评估。

Appender 通常仅负责将事件数据写入目标目的地。在大多数情况下,他们将格式化事件的责任委派给layout。一些附加程序会包装其他附加程序,以便他们可以修改 LogEvent,处理 Appender 中的故障,基于高级筛选器条件将事件路由到下级 Appender 或提供不会直接格式化事件以供查看的类似功能。

Appender 始终有一个名称,以便可以从 Loggers 中引用它们。

在下表中,“类型”列对应于所需的 Java 类型。对于非 JDK 类,除非另有说明,否则它们通常应位于Log4j Core中。

AsyncAppender

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

默认情况下,AsyncAppender 使用java.util.concurrent.ArrayBlockingQueue,不需要任何外部库。请注意,在使用这种附加程序时,多线程应用程序应格外小心:阻塞队列很容易发生锁争用,并且同时记录更多线程时,我们的tests showed性能可能会变差。考虑使用无锁异步 Logger以获得最佳性能。

AsyncAppender Parameters

Parameter Name Type Description
AppenderRef String 要异步调用的 Appender 的名称。可以配置多个 AppenderRef 元素。
blocking boolean 如果为 true,则追加程序将 await,直到队列中有空闲插槽。如果为 false,则在队列已满的情况下将事件写入错误附加程序。默认值为 true。
shutdownTimeout integer Appender 在关闭时应 await 多少毫秒来刷新队列中的未完成日志事件。默认值为零,表示永远 await。
bufferSize integer 指定可以排队的最大事件数。默认值为 1024.请注意,在使用破坏者样式的 BlockingQueue 时,此缓冲区大小必须为 2 的幂。


当应用程序的日志记录速度快于基础附加程序无法满足的足够长的时间来填充队列时,其行为由AsyncQueueFullPolicy决定。
| errorRef | String |如果没有一个附加程序可以调用,则是由于附加程序中的错误或队列已满而要调用的附加程序的名称。如果未指定,则错误将被忽略。
| filter | Filter |一个过滤器,用于确定事件是否应由此 Appender 处理。通过使用 CompositeFilter,可以使用多个过滤器。
| name | String |Appender 的名称。
| ignoreExceptions | boolean |缺省值为 true,导致在追加事件时遇到的异常将在内部记录,然后被忽略。设置为 false 时,异常将传播到调用方。当将此 Appender 包装在FailoverAppender中时,必须将其设置为 false。
| includeLocation | boolean |提取位置是一项昂贵的操作(它会使记录速度降低 5-20 倍)。为了提高性能,将日志事件添加到队列时,默认情况下不包括位置。您可以通过设置 includeLocation =“ true”来更改此设置。
| BlockingQueueFactory | BlockingQueueFactory |此元素将覆盖要使用的类型的 BlockingQueue。有关更多详细信息,请参见below documentation

即使基础追加程序无法跟上日志记录速率并且队列已满,也有一些系统属性可用于维持应用程序吞吐量。请参阅系统属性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 Implementations

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

CassandraAppender

CassandraAppender 将其输出写入Apache Cassandra数据库。必须提前配置键空间和表,并且该表的列 Map 在配置文件中。每列都可以指定StringLayout(例如PatternLayout)以及可选的转换类型,或者仅将 org.apache.logging.log4j.spi.ThreadContextMap 或 org.apache.logging.log4j.spi.ThreadContextStack 的转换类型指定为将MDC 或 NDC分别存储在 Map 或列表列中。与 java.util.Date 兼容的转换类型将使用转换为该类型的日志事件时间戳(例如,使用 java.util.Date 填充 Cassandra 中的 timestamp 列类型)。

CassandraAppender Parameters

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

这是一个 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 为默认目标。必须提供一个布局以格式化 LogEvent。

ConsoleAppender Parameters

Parameter Name Type Description
filter Filter 确定事件是否应由此 Appender 处理的过滤器。通过使用 CompositeFilter,可以使用多个过滤器。
layout Layout 用于格式化 LogEvent 的 Layout。如果未提供任何布局,则将使用默认图案布局“%m%n”。
follow boolean 标识附加程序是否通过配置后进行的 System.setOut 或 System.setErr 兑现 System.out 或 System.err 的重新分配。请注意,在 Windows 上,follow 属性不能与 Jansi 一起使用。不能直接使用。
direct boolean 直接写入 java.io.FileDescriptor 并绕过 java.lang.System.out/.err。将输出重定向到文件或其他进程时,最多可以使性能提高 10 倍。在 Windows 上不能与 Jansi 一起使用。不能与关注一起使用。输出将不遵守 java.lang.System.setOut()/。setErr(),并且可能与多线程应用程序中 java.lang.System.out/.err 的其他输出交织在一起。自 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”。

典型的控制台配置可能如下所示:

<?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 失败,则将按 Sequences 尝试次要 Appender,直到一个成功或没有其他次要 Appender 为止。

FailoverAppender Parameters

Parameter Name Type Description
filter Filter 确定事件是否应由此 Appender 处理的过滤器。通过使用 CompositeFilter,可以使用多个过滤器。
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”。

故障转移配置可能如下所示:

<?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 参数中命名的 File。 FileAppender 使用 FileManager(扩展了 OutputStreamManager)来实际执行文件 I/O。虽然无法共享来自不同配置的 FileAppender,但是如果可以访问 Manager,则可以使用 FileManager。例如,如果 Log4j 位于两个容器都通用的 ClassLoader 中,则 Servlet 容器中的两个 Web 应用程序可以具有自己的配置,并可以安全地写入同一文件。

FileAppender Parameters

Parameter Name Type Description
append boolean 如果为 true-默认值,记录将附加到文件末尾。设置为 false 时,将在写入新记录之前清除文件。
bufferedIO boolean 如果为 true-默认值,则记录将被写入缓冲区,并且当缓冲区已满或(如果设置了 InstantFlush 时)记录被写入时,数据将被写入磁盘。文件锁定不能与 bufferedIO 一起使用。性能测试表明,即使启用了 InstantFlush,使用缓冲 I/O 也会显着提高性能。
bufferSize int 当 bufferedIO 为 true 时,这是缓冲区大小,默认值为 8192 字节。
createOnDemand boolean 附加器按需创建文件。仅当日志事件通过所有过滤器并将其路由到此附加程序时,附加程序才创建文件。默认为 false。
filter Filter 确定事件是否应由此 Appender 处理的过滤器。通过使用 CompositeFilter,可以使用多个过滤器。
fileName String 要写入的文件名。如果该文件或其任何父目录不存在,则将创建它们。
immediateFlush boolean 设置为 true-默认值时,每次写操作后都会进行刷新。这将确保将数据写入磁盘,但可能会影响性能。


每次写入后刷新仅在将此追加器与同步 Logger 一起使用时才有用。即使将 InstantFlush 设置为 false,异步 Logger 和附加器也将在一批事件结束时自动刷新。这也保证了将数据写入磁盘但效率更高。
| layout | Layout |用于格式化 LogEvent 的布局。如果未提供任何布局,则将使用默认样式布局“%m%n”。
| locking | boolean |设置为 true 时,仅在保持文件锁定的同时才发生 I/O 操作,从而允许多个 JVM 中的 FileAppenders 以及可能有多个主机的 FileAppenders 同时写入同一文件。这将严重影响性能,因此应谨慎使用。此外,在许多系统上,文件锁定是“建议”的,这意味着其他应用程序可以在不获取锁定的情况下对文件执行操作。缺省值为 false。
| name | String |Appender 的名称。
| ignoreExceptions | boolean |缺省值为 true,导致在追加事件时遇到的异常将在内部记录,然后被忽略。设置为 false 时,异常将传播到调用方。当将此 Appender 包装在FailoverAppender中时,必须将其设置为 false。
| filePermissions | String |文件属性权限(采用 POSIX 格式)在创建文件时应用。
基础文件系统应支持POSIX文件属性视图。
例如:rw -------或 rw-rw-rw-等... |
| fileOwner | String |文件所有者,用于定义何时创建文件。
出于安全原因,更改文件的所有者可能受到限制,并且不允许操作 IOException 抛出。如果_POSIX_CHOWN_RESTRICTED对路径有效,则只有有效用户 ID 等于文件用户 ID 或具有适当特权的进程才可以更改文件的所有权。
基础文件系统应支持文件owner属性视图。
| fileGroup | String |文件组,用于在创建文件时进行定义。
基础文件系统应支持POSIX文件属性视图。

这是一个示例文件配置:

<?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

这是在单独的广口瓶中提供的可选组件。

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

Flume Appender 支持三种操作模式。

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

FlumeAppender Parameters

Parameter Name Type Description
agents Agent[] 日志事件应发送到的一组代理。如果指定了多个代理,则第一个代理将成为主要代理,如果主要代理失败,则将按指定为次要代理的 Sequences 使用后续代理。每个代理定义都提供代理主机和端口。代理规范和属性是互斥的。如果两者都配置,将导致错误。
agentRetries integer 代理失败后应重试代理的次数。当指定 type =“ persistent”时,此参数将被忽略(代理尝试一次,然后再失败)。
batchSize integer 指定应作为批次发送的事件数。默认值为 1.此参数仅适用于 Flume Appender。
compress boolean 设置为 true 时,邮件正文将使用 gzip 压缩
connectTimeoutMillis integer Flume 将在超时之前 await 的毫秒数。
dataDir String Flume 提前写入日志应写入的目录。仅当 Embedded 设置为 true 且使用 Agent 元素而不是 Property 元素时才有效。
filter Filter 确定事件是否应由此 Appender 处理的过滤器。通过使用 CompositeFilter,可以使用多个过滤器。
eventPrefix String 为了区别于 MDC 属性,在每个事件属性之前附加字符串。默认值为空字符串。
flumeEventFactory FlumeEventFactory 从 Log4j 事件生成 Flume 事件的工厂。默认工厂是 FlumeAvroAppender 本身。
layout Layout 用于格式化 LogEvent 的 Layout。如果未指定布局,则将使用 RFC5424Layout。
lockTimeoutRetries integer 写入 Berkeley DB 时发生 LockConflictException 时重试的次数。预设值为 5.
maxDelayMillis integer 发布批处理之前 awaitbatchSize 事件的最大毫秒数。
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 Agent 的属性元素。必须配置属性时不使用代理名称(为此使用附加器名称),并且无法配置任何源。可以使用“ sources.log4j-source.interceptors”为源指定拦截器。允许所有其他 Flume 配置属性。同时指定 Agent 和 Property 元素将导致错误。


在持久模式下配置时,有效属性为:
“ keyProvider”指定用于提供加密密钥的插件名称。
| | requestTimeoutMillis | integer | Flume 在超时之前将 await 的毫秒数。
| ignoreExceptions | boolean |缺省值为 true,导致在追加事件时遇到的异常将在内部记录,然后被忽略。设置为 false 时,异常将传播到调用方。当将此 Appender 包装在FailoverAppender中时,必须将其设置为 false。
||类型|枚举|“ 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 格式化主体,并将加密后的事件持久保存到磁盘:

<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="warn" name="MyApp" packages="">
  <Appenders>
    <Flume name="eventLogger" compress="true" type="persistent" dataDir="./logData">
      <Agent host="192.168.10.101" port="8800"/>
      <Agent host="192.168.10.102" port="8800"/>
      <RFC5424Layout enterpriseNumber="18060" includeMDC="true" appName="MyApp"/>
      <Property name="keyProvider">MySecretProvider</Property>
    </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>

一个示例 FlumeAppender 配置,该配置使用 Flume 配置属性配置了一级代理和二级代理,压缩主体,使用 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 开始,有两种方法可以配置日志事件到列的 Map:原始的 ColumnConfig 样式仅允许字符串和时间戳,以及新的 ColumnMapping 插件,该插件使用 Log4j 的内置类型转换来允许更多数据类型(该插件与Cassandra Appender)中的插件相同。

为了在开发过程中迅速起步,使用基于 JNDI 的连接源的另一种方法是使用非池化的 DriverManager 连接源。此连接源使用 JDBC 连接字符串,用户名和密码。您也可以选择使用属性。

JDBCAppender Parameters

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

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

DataSource Parameters

Parameter Name Type Description
jndiName String 需要。绑定 javax.sql.DataSource 的完整,带前缀的 JNDI 名称,例如 java:/ comp/env/jdbc/LoggingDatabase。数据源必须由连接池支持;否则,日志记录将非常缓慢。

ConnectionFactory Parameters

Parameter Name Type Description
class Class 需要。类的完全限定名称,该类包含用于获取 JDBC 连接的静态工厂方法。
method Method 需要。用于获取 JDBC 连接的静态工厂方法的名称。此方法必须没有参数,其返回类型必须为 java.sql.Connection 或 DataSource。如果该方法返回 Connections,则它必须从连接池中获取它们(使用 Log4j 完成连接后,它们将返回到该池中);否则,日志记录将非常缓慢。如果该方法返回一个数据源,则该数据源将仅被检索一次,并且出于相同的原因,它必须由连接池支持。

DriverManager Parameters

Parameter Name Type Description
connectionString String 需要。驱动程序特定的 JDBC 连接字符串。
userName String 数据库用户名。您不能同时指定属性和用户名或密码。
password String 数据库密码。您不能同时指定属性和用户名或密码。
driverClassName String JDBC 驱动程序类名称。某些旧的 JDBC 驱动程序只能通过按类名显式加载它们来发现。
properties Property[] 属性列表。您不能同时指定属性和用户名或密码。

Parameter Name Type Description
DriverManager parameters DriverManager parameters 此连接源从 DriverManager 连接源继承所有参数。
poolName String 用于池化 JDBC 连接的池名称。默认为 example。如果要在其他地方使用池化连接,则可以使用 JDBC 连接字符串前缀 jdbc:apache:commons:dbcp:后跟池名称。例如:jdbc:apache:commons:dbcp:example。
PoolableConnectionFactory PoolableConnectionFactory element 定义一个 PoolableConnectionFactory。

Parameter Name Type Description
autoCommitOnReturn boolean See Apache Commons DBCP PoolableConnectionFactory。
cacheState boolean See Apache Commons DBCP PoolableConnectionFactory。
ConnectionInitSqls Strings See Apache Commons DBCP PoolableConnectionFactory。
defaultAutoCommit boolean See Apache Commons DBCP PoolableConnectionFactory。
defaultCatalog String See Apache Commons DBCP PoolableConnectionFactory。
defaultQueryTimeoutSeconds integer See Apache Commons DBCP PoolableConnectionFactory。
defaultReadOnly boolean See Apache Commons DBCP PoolableConnectionFactory。
defaultTransactionIsolation integer See Apache Commons DBCP PoolableConnectionFactory。
disconnectionSqlCodes Strings See Apache Commons DBCP PoolableConnectionFactory。
fastFailValidation boolean See Apache Commons DBCP PoolableConnectionFactory。
maxConnLifetimeMillis long See Apache Commons DBCP PoolableConnectionFactory。
maxOpenPreparedStatements integer See Apache Commons DBCP PoolableConnectionFactory。
poolStatements boolean See Apache Commons DBCP PoolableConnectionFactory。
rollbackOnReturn boolean See Apache Commons DBCP PoolableConnectionFactory。
validationQuery String See Apache Commons DBCP PoolableConnectionFactory。
validationQueryTimeoutSeconds integer See Apache Commons DBCP PoolableConnectionFactory。

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

Column Parameters

Parameter Name Type Description
name String 需要。数据库列的名称。
pattern String 使用此属性可以使用 PatternLayout 模式在此列中的日志事件中插入一个或多个值。只需在此属性中指定任何合法模式即可。必须指定此属性,Literals 或 isEventTimestamp =“ true”,但不得超过一个。
literal String 使用此属性可在此列中插入 Literals 值。该值将直接包含在插入 SQL 中,不带引号(这意味着如果您希望它是一个字符串,则值应在其周围包含单引号,例如:literal =“'Literal String'”)。这对于不支持标识列的数据库特别有用。例如,如果您使用的是 Oracle,则可以指定 Literals=“ NAME_OF_YOUR_SEQUENCE.NEXTVAL”在 ID 列中插入唯一 ID。必须指定此属性,模式或 isEventTimestamp =“ true”,但不能超过一个。
parameter String 使用此属性可插入带有参数标记“?”的表达式在此列中。该值将直接包含在插入 SQL 中,不带引号(这意味着如果您希望将其作为字符串,则值应在其周围包含单引号,如下所示:


\
您只能指定 Literals 或参数之一。
| isEventTimestamp | boolean |使用此属性将事件时间戳记插入此列中,该时间戳记应为 SQL 日期时间。该值将作为 java.sql.Types.TIMESTAMP 插入。必须指定此属性(等于 true),pattern 或 isEventTimestamp,但不能超过一个。
| isUnicode | boolean |除非指定模式,否则将忽略此属性。如果为 true 或省略(默认),则该值将作为 unicode(setNString 或 setNClob)插入。否则,将以非 Unicode 值(setString 或 setClob)插入该值。
| isClob | boolean |除非指定模式,否则将忽略此属性。使用此属性指示该列存储字符大对象(CLOB)。如果为 true,则该值将作为 CLOB(setClob 或 setNClob)插入。如果为 false 或省略(默认值),则该值将作为 VARCHAR 或 NVARCHAR(setString 或 setNString)插入。 |

ColumnMapping Parameters

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

以下是 JDBCAppender 的几个示例配置,以及使用 Commons Pooling 和 Commons 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();
    }
}

此附加程序知道MapMessage

以下配置使用 MessageLayout 来指示在设置 Appender 的 SQL INSERT 语句的值时 Appender 应该将 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

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

请注意,在 Log4j 2.0 中,此追加器已拆分为 JMSQueueAppender 和 JMSTopicAppender。从 Log4j 2.1 开始,这些附加器被合并到 JMS Appender 中,该 JMS Appender 在队列和主题之间没有区别。但是,为 2.0 使用\ 或\ 元素编写的配置将 continue 与新的\ 配置元素一起使用。

Parameter Name Type Default Description
factoryBindingName String Required 要在提供ConnectionFactory的上下文中找到的名称。这也可以是 ConnectionFactory 的任何子接口。
factoryName String Required 用来定义INITIAL_CONTEXT_FACTORY中定义的初始上下文工厂的标准类名。如果指定了没有提供者 URL 的 factoryName,将记录一条警告消息,因为这很可能会引起问题。
filter Filter null 确定事件是否应由此 Appender 处理的过滤器。通过使用 CompositeFilter,可以使用多个过滤器。
layout Layout Required 用于格式化 LogEvent 的 Layout。从 2.9 开始新增,在以前的版本中,默认为 SerializedLayout。
name String Required Appender的名字。
password String null 用于创建 JMS 连接的密码。
providerURL String Required PROVIDER_URL定义使用的提供者的 URL。
destinationBindingName String Required 用于查找Destination的名称。这可以是 Queue 或 Topic,因此,属性名称 queueBindingName 和 topicBindingName 是别名,以保持与 Log4j 2.0 JMS 追加程序的兼容性。
securityPrincipalName String null SECURITY_PRINCIPAL指定的委托人的身份名称。如果指定的 securityPrincipalName 没有 securityCredentials,则会记录一条警告消息,因为这很可能会引起问题。
securityCredentials String null SECURITY_CREDENTIALS指定的主体的安全凭证。
ignoreExceptions boolean true 为 true 时,将在内部记录附加事件时捕获的异常,然后将其忽略。当错误异常传播到调用方时。当将此 Appender 封装在FailoverAppender中时,必须将其设置为 false。
immediateFail boolean false 设置为 true 时,日志事件将不 await 尝试重新连接,如果 JMS 资源不可用,则日志事件将立即失败。 2.9 中的新功能。
reconnectIntervalMillis long 5000 如果设置为大于 0 的值,则在发生错误后,JMSManager 将在 await 指定的毫秒数后尝试重新连接到代理。如果重新连接失败,则将引发异常(如果将 ignoreExceptions 设置为 false,则应用程序可以捕获该异常)。 2.9 中的新功能。
urlPkgPrefixes String null 用冒号分隔的工厂类的类名称的包前缀列表,它将创建由URL_PKG_PREFIXES定义的 URL 上下文工厂。
userName String null 用于创建 JMS 连接的用户 ID。

这是一个示例 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 MapMessagesMap 到 JMS javax.jms.MapMessages,请使用\ (从 2.9 版开始)将附加程序的布局设置为 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 支持已从现有模块 log4j-core 移至新模块 log4j-jpa。

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

JPAAppender Parameters

Parameter Name Type Description
name String 需要。Appender的名字。
ignoreExceptions boolean 默认值为 true,导致在追加事件时遇到的异常会在内部记录下来,然后被忽略。设置为 false 时,异常将传播到调用方。当将此 Appender 封装在FailoverAppender中时,必须将其设置为 false。
filter Filter 确定事件是否应由此 Appender 处理的过滤器。通过使用 CompositeFilter,可以使用多个过滤器。
bufferSize int 如果大于 0 的整数,这将导致附加程序缓冲日志事件并在缓冲区达到此大小时刷新。
entityClassName String 需要。具体的 LogEventWrapperEntity 实现的完全限定名称,该实现具有 JPA 注解将其 Map 到数据库表。
persistenceUnitName String 需要。应用于持久日志事件的 JPA 持久单元的名称。

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

<?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 发送日志事件。必须提供一个布局以格式化 LogEvent。

将根据布局设置 Content-TypeHeaders。可以使用嵌入的 Property 元素指定其他 Headers。

将 await 服务器的响应,如果未收到 2xx 响应,则抛出错误。

HttpURLConnection实现。

HttpAppender Parameters

Parameter Name Type Description
name String Appender的名字。
filter Filter 确定事件是否应由此 Appender 处理的过滤器。通过使用 CompositeFilter,可以使用多个过滤器。
layout Layout 用于格式化 LogEvent 的 Layout。
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[] 要使用的其他 HTTPHeaders。这些值支持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 Parameters

Parameter Name Type Description
topic String 要使用的 Kafka 主题。需要。
key String 随每条消息一起发送给 Kafka 的密钥。可选值,默认为 null。可以包含任何Lookups)。
filter Filter 确定事件是否应由此 Appender 处理的过滤器。通过使用 CompositeFilter,可以使用多个过滤器。
layout Layout 用于格式化 LogEvent 的 Layout。必需,没有默认值。自 2.9 起新增,在以前的版本\ 中为默认值。
name String Appender的名字。需要。
ignoreExceptions boolean 默认值为 true,导致在追加事件时遇到的异常会在内部记录下来,然后被忽略。设置为 false 时,异常将传播到调用方。当将此 Appender 封装在FailoverAppender中时,必须将其设置为 false。
syncSend boolean 默认值为 true,导致发送阻塞,直到 Kafka 服务器确认记录为止。设置为 false 时,将立即发送返回消息,从而降低了 await 时间并显着提高了吞吐量。自 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>

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

此附加程序需要KafkaClient 端库。请注意,您需要使用与所使用的 Kafka 服务器匹配的 KafkaClient 端库版本。

注意:确保不要让 org.apache.kafka 记录到 DEBUG 级别的 Kafka 附加程序,因为这将导致递归记录:

<?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 将指定文件的一部分 Map 到内存中,并将日志事件写入此内存,这取决于 os 的虚拟内存 Management 器以将更改同步到存储设备。使用内存 Map 文件的主要好处是 I/O 性能。无需进行系统调用来写入磁盘,该附加器可以简单地更改程序的本地内存,速度快了几个数量级。同样,在大多数 os 中,实际 Map 的内存区域是内核的page cache(文件高速缓存),这意味着无需在用户空间中创建任何副本。 (TODO:性能测试,用于比较此附加程序与 RandomAccessFileAppender 和 FileAppender 的性能.)

将文件区域 Map 到内存中会产生一些开销,尤其是非常大的区域(半 GB 或更多)。默认区域大小为 32 MB,这应该在重新 Map 操作的频率和持续时间之间取得合理的平衡。 (TODO:重新 Map 各种尺寸的性能测试.)

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

MemoryMappedFileAppender Parameters

Parameter Name Type Description
append boolean 如果为 true-默认值,记录将附加到文件末尾。设置为 false 时,将在写入新记录之前清除文件。
fileName String 要写入的文件名。如果该文件或其任何父目录不存在,则将创建它们。
filters Filter 确定事件是否应由此 Appender 处理的过滤器。通过使用 CompositeFilter,可以使用多个过滤器。
immediateFlush boolean 设置为 true 时,每次写入后都会调用MappedByteBuffer.force()。这将确保将数据写入存储设备。


此参数的默认值为 false。这意味着即使 Java 进程崩溃,也将数据写入存储设备,但如果 os 崩溃,则可能会丢失数据。
请注意,在每个日志事件上手动强制进行同步会失去使用内存 Map 文件的大多数性能优势。
每次写入后刷新仅在将此追加器与同步 Logger 一起使用时才有用。即使将 InstantFlush 设置为 false,异步 Logger 和附加器也将在一批事件结束时自动刷新。这也保证了将数据写入磁盘但效率更高。
| regionLength | int |Map 区域的长度,默认为 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 的提供程序实现,并且编写自定义提供程序非常简单。

NoSQLAppender Parameters

Parameter Name Type Description
name String 需要。Appender的名字。
ignoreExceptions boolean 默认值为 true,导致在追加事件时遇到的异常会在内部记录下来,然后被忽略。设置为 false 时,异常将传播到调用方。当将此 Appender 封装在FailoverAppender中时,必须将其设置为 false。
filter Filter 确定事件是否应由此 Appender 处理的过滤器。通过使用 CompositeFilter,可以使用多个过滤器。
bufferSize int 如果大于 0 的整数,这将导致附加程序缓冲日志事件并在缓冲区达到此大小时刷新。
NoSqlProvider NoSQLProvider<C extends NoSQLConnection<W, T extends NoSQLObject >> 需要。提供与所选 NoSQL 数据库的连接的 NoSQL 提供程序。

您可以通过在\ 元素中指定适当的配置元素来指定要使用的 NoSQL 提供程序。当前支持的类型为\ 和\ 。要创建自己的自定义提供程序,请阅读 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"
    ]
}

适用于 MongoDB 的 NoSQLAppender

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

我们不再提供模块 log4j-mongodb。

模块 log4j-mongodb2 将旧配置元素 MongoDb 别名为MongoDb2

适用于 MongoDB 2 的 NoSQLAppender

本节详细说明使用 MongoDB 驱动程序版本 2 的 MongoDB NoSQLAppender提供程序的专业化。NoSQLAppender Appender 使用内部轻量级提供程序接口将日志事件写入 NoSQL 数据库。

Parameter Name Type Description
collectionName String 需要。要插入事件的 MongoDB 集合的名称。
writeConcernConstant Field 默认情况下,MongoDB 提供程序使用 com.mongodb.WriteConcern.ACKNOWLEDGED 指令插入记录。使用此可选属性可以指定 ACKNOWLEDGED 以外的常量的名称。
writeConcernConstantClass Class 如果指定 writeConcernConstant,则可以使用此属性指定 com.mongodb.WriteConcern 以外的其他类来查找常量(以创建自己的自定义指令)。
factoryClassName Class 要提供与 MongoDB 数据库的连接,可以使用此属性和 factoryMethodName 来指定用于获取连接的类和静态方法。该方法必须返回 com.mongodb.DB 或 com.mongodb.MongoClient。如果数据库未通过身份验证,则还必须指定用户名和密码。如果使用工厂方法提供连接,则不得指定 databaseName,服务器或端口属性。
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 启用对capped collections的支持
collectionSize int 指定启用封顶的集合的大小(以字节为单位)。最小大小为 4096 字节,较大的大小将增加为最接近的 256 的整数倍。有关更多信息,请参见上面链接的带帽集合文档。

此附加程序知道MapMessage

以下是 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 数据库。

Parameter Name Type Description
collectionName String 需要。要插入事件的 MongoDB 集合的名称。
writeConcernConstant Field 默认情况下,MongoDB 提供程序使用 com.mongodb.WriteConcern.ACKNOWLEDGED 指令插入记录。使用此可选属性可以指定 ACKNOWLEDGED 以外的常量的名称。
writeConcernConstantClass Class 如果指定 writeConcernConstant,则可以使用此属性指定 com.mongodb.WriteConcern 以外的其他类来查找常量(以创建自己的自定义指令)。
factoryClassName Class 要提供与 MongoDB 数据库的连接,可以使用此属性和 factoryMethodName 来指定用于获取连接的类和静态方法。该方法必须返回 com.mongodb.client.MongoDatabase 或 com.mongodb.MongoClient。如果 com.mongodb.client.MongoDatabase 未通过身份验证,则还必须指定用户名和密码。如果使用工厂方法提供连接,则不得指定 databaseName,服务器或端口属性。
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 启用对capped collections的支持
collectionSize int 指定启用封顶的集合的大小(以字节为单位)。最小大小为 4096 字节,较大的大小将增加为最接近的 256 的整数倍。有关更多信息,请参见上面链接的带帽集合文档。

此附加程序知道MapMessage

以下是 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>

适用于 Apache CouchDB 的 NoSQLAppender

本节详细介绍NoSQLAppender CouchDB 提供程序的专业化。 NoSQLAppender 使用内部轻量级提供程序接口将日志事件写入 NoSQL 数据库。

Parameter Name Type Description
factoryClassName Class 要提供与 CouchDB 数据库的连接,可以使用此属性和 factoryMethodName 来指定从中获取连接的类和静态方法。该方法必须返回 org.lightcouch.CouchDbClient 或 org.lightcouch.CouchDbProperties。如果使用工厂方法提供连接,则不得指定 databaseName,协议,服务器,端口,用户名或密码属性。
factoryMethodName Method 请参阅有关属性 factoryClassName 的文档。
databaseName String 如果未指定用于提供 CouchDB 连接的 factoryClassName 和 factoryMethodName,则必须使用此属性指定 CouchDB 数据库名称。您还必须指定用户名和密码。您还可以选择指定协议(默认为 http),服务器(默认为 localhost)和端口(http 的默认值为 80,https 的默认值为 443)。
protocol String 必须为“ http”或“ https”。请参阅有关属性 databaseName 的文档。
server String 请参阅有关属性 databaseName 的文档。
port int 请参阅有关属性 databaseName 的文档。
username String 请参阅有关属性 databaseName 的文档。
password String 请参阅有关属性 databaseName 的文档。

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

<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="error">
  <Appenders>
    <NoSql name="databaseAppender">
      <CouchDb databaseName="applicationDb" protocol="https" server="couch.example.org"
               username="loggingUser" password="abc123" />
    </NoSql>
  </Appenders>
  <Loggers>
    <Root level="warn">
      <AppenderRef ref="databaseAppender"/>
    </Root>
  </Loggers>
</Configuration>

OutputStreamAppender

OutputStreamAppender 为许多其他 Appender 提供了基础,例如将事件写入输出流的 File 和 Socket 附加程序。不能直接配置。 OutputStreamAppender 提供对 InstantFlush 和缓冲的支持。 OutputStreamAppender 使用 OutputStreamManager 处理实际的 I/O,从而允许 Appender 在多种配置中共享流。

RandomAccessFileAppender

RandomAccessFileAppender 与标准FileAppender相似,不同之处在于它始终被缓冲(无法关闭),并且在内部使用 ByteBuffer RandomAccessFile 而不是 BufferedOutputStream。与measurements中具有“ bufferedIO = true”的 FileAppender 相比,我们看到了 20-200%的性能提升。与 FileAppender 相似,RandomAccessFileAppender 使用 RandomAccessFileManager 实际执行文件 I/O。虽然不能共享来自不同配置的 RandomAccessFileAppender,但可以访问 Manager,则可以使用 RandomAccessFileManagers。例如,如果 Log4j 位于两个容器都通用的 ClassLoader 中,则 Servlet 容器中的两个 Web 应用程序可以具有自己的配置,并可以安全地写入同一文件。

RandomAccessFileAppender Parameters

Parameter Name Type Description
append boolean 如果为 true-默认值,记录将附加到文件末尾。设置为 false 时,将在写入新记录之前清除文件。
fileName String 要写入的文件名。如果该文件或其任何父目录不存在,则将创建它们。
filters Filter 确定事件是否应由此 Appender 处理的过滤器。通过使用 CompositeFilter,可以使用多个过滤器。
immediateFlush boolean 设置为 true-默认值时,每次写操作后都会进行刷新。这将确保将数据写入磁盘,但可能会影响性能。


每次写入后刷新仅在将此追加器与同步 Logger 一起使用时才有用。即使将 InstantFlush 设置为 false,异步 Logger 和附加器也将在一批事件结束时自动刷新。这也保证了将数据写入磁盘但效率更高。
|| bufferSize |||缓冲区大小,默认为 262,144 字节(256 * 1024)。
| layout | Layout |用于格式化 LogEvent 的布局。如果未提供任何布局,则将使用默认样式布局“%m%n”。
| name | String |Appender 的名称。
| ignoreExceptions | boolean |缺省值为 true,导致在追加事件时遇到的异常将在内部记录,然后被忽略。设置为 false 时,异常将传播到调用方。当将此 Appender 包装在FailoverAppender中时,必须将其设置为 false。

这是一个示例 RandomAccessFile 配置:

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

RewriteAppender

RewriteAppender 允许在 LogEvent 被另一个 Appender 处理之前对其进行操作。这可用于掩盖敏感信息(例如密码)或将信息注入每个事件。 RewriteAppender 必须配置为RewritePolicy。应该在 RewriteAppender 引用的所有 Appender 之后对其进行配置,以使其能够正常关闭。

RewriteAppender Parameters

Parameter Name Type Description
AppenderRef String 在操纵 LogEvent 之后要调用的 Appender 的名称。可以配置多个 AppenderRef 元素。
filter Filter 确定事件是否应由此 Appender 处理的过滤器。通过使用 CompositeFilter,可以使用多个过滤器。
name String Appender的名字。
rewritePolicy RewritePolicy 将操纵 LogEvent 的 RewritePolicy。
ignoreExceptions boolean 默认值为 true,导致在追加事件时遇到的异常会在内部记录下来,然后被忽略。设置为 false 时,异常将传播到调用方。当将此 Appender 封装在FailoverAppender中时,必须将其设置为 false。

RewritePolicy

RewritePolicy 是一个接口,允许实现在将 LogEvent 传递给 Appender 之前检查并可能对其进行修改。 RewritePolicy 声明一个必须执行的名为 rewrite 的方法。该方法通过 LogEvent 传递,并且可以返回相同事件或创建一个新事件。

MapRewritePolicy

MapRewritePolicy 将评估包含 MapMessage 的 LogEvent,并添加或更新 Map 的元素。

Parameter Name Type Description
mode String “添加”或“更新”
keyValuePair KeyValuePair[] 键及其值的数组。

以下配置显示了一个 RewriteAppender,该 RewriteAppender 配置为将产品密钥及其值添加到 MapMessage。

<?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>
    <Rewrite name="rewrite">
      <AppenderRef ref="STDOUT"/>
      <MapRewritePolicy mode="Add">
        <KeyValuePair key="product" value="TestProduct"/>
      </MapRewritePolicy>
    </Rewrite>
  </Appenders>
  <Loggers>
    <Root level="error">
      <AppenderRef ref="Rewrite"/>
    </Root>
  </Loggers>
</Configuration>
PropertiesRewritePolicy

PropertiesRewritePolicy 会将在策略上配置的属性添加到正在记录的 ThreadContextMap 中。该属性将不会添加到实际的 ThreadContextMap 中。属性值可能包含变量,这些变量将在处理配置以及记录事件时进行评估。

Parameter Name Type Description
properties Property[] 用于定义要添加到 ThreadContextMap 的键和值的多个 Property 元素之一。

以下配置显示了一个 RewriteAppender,该 RewriteAppender 配置为将产品密钥及其值添加到 MapMessage:

<?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>
    <Rewrite name="rewrite">
      <AppenderRef ref="STDOUT"/>
      <PropertiesRewritePolicy>
        <Property name="user">${sys:user.name}</Property>
        <Property name="env">${sys:environment}</Property>
      </PropertiesRewritePolicy>
    </Rewrite>
  </Appenders>
  <Loggers>
    <Root level="error">
      <AppenderRef ref="Rewrite"/>
    </Root>
  </Loggers>
</Configuration>
LoggerNameLevelRewritePolicy

您可以使用此策略通过更改事件级别来减少第三方代码中的 Logger 的闲聊。 LoggerNameLevelRewritePolicy 将重写给定 Logger 名称前缀的日志事件级别。您可以使用 Logger 名称前缀和一对级别来配置 LoggerNameLevelRewritePolicy,其中一对定义了源级别和目标级别。

Parameter Name Type Description
logger String 记录程序名称用作测试每个事件的记录程序名称的前缀。
LevelPair KeyValuePair[] 键及其值的数组,每个键是一个源级别,每个值是一个目标级别。

以下配置显示了一个 RewriteAppender,该配置为所有以 com.foo.bar 开头的 Logger 将 INFO 级别 Map 到 DEBUG,将 WARNMap 到 INFO。

<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="warn" name="MyApp">
  <Appenders>
    <Console name="STDOUT" target="SYSTEM_OUT">
      <PatternLayout pattern="%m%n"/>
    </Console>
    <Rewrite name="rewrite">
      <AppenderRef ref="STDOUT"/>
      <LoggerNameLevelRewritePolicy logger="com.foo.bar">
        <KeyValuePair key="INFO" value="DEBUG"/>
        <KeyValuePair key="WARN" value="INFO"/>
      </LoggerNameLevelRewritePolicy>
    </Rewrite>
  </Appenders>
  <Loggers>
    <Root level="error">
      <AppenderRef ref="Rewrite"/>
    </Root>
  </Loggers>
</Configuration>

RollingFileAppender

RollingFileAppender 是一个 OutputStreamAppender,它写入在 fileName 参数中命名的 File 并根据 TriggeringPolicy 和 RolloverPolicy 将文件滚动。 RollingFileAppender 使用 RollingFileManager(扩展了 OutputStreamManager)来实际执行文件 I/O 并执行过渡。虽然无法共享来自不同配置的 RolloverFileAppenders,但如果可访问 Manager,则可以使用 RollingFileManagers。例如,如果 Log4j 位于两个容器都通用的 ClassLoader 中,则 Servlet 容器中的两个 Web 应用程序可以具有自己的配置,并可以安全地写入同一文件。

RollingFileAppender 需要TriggeringPolicyRolloverStrategy。触发策略确定是否应执行过渡,而 RolloverStrategy 定义应如何进行过渡。如果未配置 RolloverStrategy,则 RollingFileAppender 将使用DefaultRolloverStrategy。从 log4j-2.5 开始,可以在 DefaultRolloverStrategy 中将自定义删除动作配置为在翻转时运行。从 2.8 开始,如果未配置任何文件名,则将使用DirectWriteRolloverStrategy代替 DefaultRolloverStrategy。从 log4j-2.9 开始,可以在 DefaultRolloverStrategy 中将自定义 POSIX 文件属性视图操作配置为在过渡时运行,如果未定义,则将应用从 RollingFileAppender 继承的 POSIX 文件属性视图。

RollingFileAppender 不支持文件锁定。

RollingFileAppender Parameters

Parameter Name Type Description
append boolean 如果为 true-默认值,记录将附加到文件末尾。设置为 false 时,将在写入新记录之前清除文件。
bufferedIO boolean 如果为 true-默认值,则记录将被写入缓冲区,并且当缓冲区已满或(如果设置了 InstantFlush 时)记录被写入时,数据将被写入磁盘。文件锁定不能与 bufferedIO 一起使用。性能测试表明,即使启用了 InstantFlush,使用缓冲 I/O 也会显着提高性能。
bufferSize int 当 bufferedIO 为 true 时,这是缓冲区大小,默认值为 8192 字节。
createOnDemand boolean 附加器按需创建文件。仅当日志事件通过所有过滤器并将其路由到此附加程序时,附加程序才创建文件。默认为 false。
filter Filter 确定事件是否应由此 Appender 处理的过滤器。通过使用 CompositeFilter,可以使用多个过滤器。
fileName String 要写入的文件名。如果该文件或其任何父目录不存在,则将创建它们。
filePattern String 归档日志文件的文件名的模式。模式的格式取决于所使用的 RolloverPolicy。 DefaultRolloverPolicy 将接受与SimpleDateFormat兼容的日期/时间模式和/或接受表示整数计数器的%i。该模式还支持在运行时进行插值,因此任何 Lookup(例如DateLookup)都可以包含在该模式中。
immediateFlush boolean 设置为 true-默认值时,每次写操作后都会进行刷新。这将确保将数据写入磁盘,但可能会影响性能。


每次写入后刷新仅在将此追加器与同步 Logger 一起使用时才有用。即使将 InstantFlush 设置为 false,异步 Logger 和附加器也将在一批事件结束时自动刷新。这也保证了将数据写入磁盘但效率更高。
| layout | Layout |用于格式化 LogEvent 的布局。如果未提供任何布局,则将使用默认样式布局“%m%n”。
| name | String |Appender 的名称。
| policy | TriggeringPolicy |用于确定是否应该发生过渡的策略。
| strategy | RolloverStrategy |用于确定存档文件的名称和位置的策略。
| ignoreExceptions | boolean |缺省值为 true,导致在追加事件时遇到的异常将在内部记录,然后被忽略。设置为 false 时,异常将传播到调用方。当将此 Appender 包装在FailoverAppender中时,必须将其设置为 false。
| filePermissions | String |文件属性权限(采用 POSIX 格式)在创建文件时应用。
基础文件系统应支持POSIX文件属性视图。
例如:rw -------或 rw-rw-rw-等... |
| fileOwner | String |文件所有者,用于定义何时创建文件。
出于安全原因,更改文件的所有者可能受到限制,并且不允许操作 IOException 抛出。如果_POSIX_CHOWN_RESTRICTED对路径有效,则只有有效用户 ID 等于文件用户 ID 或具有适当特权的进程才可以更改文件的所有权。
基础文件系统应支持文件owner属性视图。
| fileGroup | String |文件组,用于在创建文件时进行定义。
基础文件系统应支持POSIX文件属性视图。

Triggering Policies

复合触发策略

CompositeTriggeringPolicy 组合了多个触发策略,如果任何已配置的策略返回 true,则返回 true。通过将其他策略包装在 Policy 元素中,即可简单地配置 CompositeTriggeringPolicy。

例如,以下 XML 片段定义了以下策略:在 JVM 启动时,日志大小达到 20 兆字节以及当前日期与日志的开始日期不匹配时,对日志进行滚动。

<Policies>
  <OnStartupTriggeringPolicy />
  <SizeBasedTriggeringPolicy size="20 MB" />
  <TimeBasedTriggeringPolicy />
</Policies>
Cron 触发 Policy

CronTriggeringPolicy 基于 cron 表达式触发翻转。此策略由计时器控制,并且与处理日志事件异步,因此上一个或下一个时间段的日志事件可能会出现在日志文件的开头或结尾。 Appender 的 filePattern 属性应包含时间戳,否则目标文件将在每次翻转时被覆盖。

CronTriggeringPolicy Parameters

Parameter Name Type Description
schedule String cron 表达式。该表达式与 Quartz 调度程序中允许的表达式相同。有关表达式的完整说明,请参见CronExpression
evaluateOnStartup boolean 启动时,将根据文件的最后修改时间戳评估 cron 表达式。如果 cron 表达式指示应该在该时间和当前时间之间发生过渡,则文件将立即被过渡。
OnStartup 触发策略

如果日志文件早于当前 JVM 的启动时间并且达到或超过了最小文件大小,则 OnStartupTriggeringPolicy 策略将导致过渡。

OnStartupTriggeringPolicy Parameters

Parameter Name Type Description
minSize long 文件必须翻转的最小大小。大小为零将导致翻转,无论文件大小如何。默认值为 1,这将防止将空文件翻转。

Google App Engine 注意:
在 Google App Engine 中运行时,如果日志文件早于 Log4J 初始化的时间,则 OnStartup 策略会导致过渡。 (Google App Engine 限制了对某些类的访问,因此 Log4J 无法使用 java.lang.management.ManagementFactory.getRuntimeMXBean()。getStartTime()来确定 JVM 的启动时间,而是回退到 Log4J 初始化时间。)

基于大小的触发策略

文件达到指定大小后,SizeBasedTriggeringPolicy 会导致翻转。大小可以字节为单位,后缀为 KB,MB 或 GB,例如 20MB。与基于时间的触发策略结合使用时,文件模式必须包含%i,否则目标文件将在每次翻转时均被覆盖,因为基于大小的触发策略不会导致文件名中的时间戳值更改。当不使用基于时间的触发策略时,基于大小的触发策略将导致时间戳值更改。

基于时间的触发策略

一旦日期/时间模式不再适用于活动文件,则 TimeBasedTriggeringPolicy 会导致翻转。该策略接受一个 interval 属性,该属性根据时间模式和一个 boolean 布尔属性指示发生翻转的频率。

TimeBasedTriggeringPolicy Parameters

Parameter Name Type Description
interval integer 基于日期模式中最具体的时间单位应进行翻转的频率。例如,对于一个日期模式,其中以小时为最具体的项目,并且每 4 个小时将发生 4 次翻转。预设值为 1.
modulate boolean 指示是否应调整时间间隔以使下一次翻转发生在时间间隔边界上。例如,如果项目是小时,当前小时是 3 am,间隔是 4,则第一次滚动将在 4 am 发生,然后下一个滚动将在 8 am,中午,4pm 等发生。
maxRandomDelay integer 指示随机延迟过渡的最大秒数。默认情况下,该值为 0,表示没有延迟。此设置在配置了多个应用程序以同时滚动日志文件的服务器上很有用,并且可以在整个时间上分散这样做的负担。

Rollover Strategies

默认过渡策略

默认的过渡策略从 RollingFileAppender 本身指定的 filePattern 属性中接受日期/时间模式和整数。如果存在日期/时间模式,它将被当前日期和时间值替换。如果模式包含整数,则它将在每次翻转时递增。如果模式在模式中同时包含日期/时间和整数,则整数将递增,直到日期/时间模式的结果更改。如果文件模式以“ .gz”,“。zip”,“。bz2”,“。deflate”,“。pack200”或“ .xz”结尾,则将使用与后缀匹配的压缩方案来压缩生成的 Files。格式 bzip2,Deflate,Pack200 和 XZ 需要Apache Commons Compress。另外,XZ 需要XZ for Java。该模式还可能包含可以在运行时解析的查找引用,如下面的示例所示。

默认的翻转策略支持三种递增计数器的方法。为了说明它是如何工作的,假设将 min 属性设置为 1,将 max 属性设置为 3,文件名是“ foo.log”,文件名模式是“ foo-%i.log”。

展期数 有效输出目标 存档的日志文件 Description
0 foo.log - 所有日志记录都将转到初始文件。
1 foo.log foo-1.log 在第一次翻转期间,foo.log 重命名为 foo-1.log。一个新的 foo.log 文件被创建并开始被写入。
2 foo.log foo-2.log, foo-1.log 在第二次翻转期间,foo.log 重命名为 foo-2.log。一个新的 foo.log 文件被创建并开始被写入。
3 foo.log foo-3.log,foo-2.log,foo-1.log 在第三次翻转期间,foo.log 重命名为 foo-3.log。一个新的 foo.log 文件被创建并开始被写入。
4 foo.log foo-3.log,foo-2.log,foo-1.log 在第四次及以后的翻转中,删除 foo-1.log,将 foo-2.log 重命名为 foo-1.log,将 foo-3.log 重命名为 foo-2.log,将 foo.log 重命名为 foo -3.log。一个新的 foo.log 文件被创建并开始被写入。

相比之下,当 fileIndex 属性设置为“ min”但所有其他设置相同时,将执行“ fixed window”策略。

展期数 有效输出目标 存档的日志文件 Description
0 foo.log - 所有日志记录都将转到初始文件。
1 foo.log foo-1.log 在第一次翻转期间,foo.log 重命名为 foo-1.log。一个新的 foo.log 文件被创建并开始被写入。
2 foo.log foo-1.log, foo-2.log 在第二次翻转期间,将 foo-1.log 重命名为 foo-2.log,并将 foo.log 重命名为 foo-1.log。一个新的 foo.log 文件被创建并开始被写入。
3 foo.log foo-1.log,foo-2.log,foo-3.log 在第三次翻转期间,将 foo-2.log 重命名为 foo-3.log,将 foo-1.log 重命名为 foo-2.log,将 foo.log 重命名为 foo-1.log。一个新的 foo.log 文件被创建并开始被写入。
4 foo.log foo-1.log,foo-2.log,foo-3.log 在第四次及以后的过渡中,删除 foo-3.log,将 foo-2.log 重命名为 foo-3.log,将 foo-1.log 重命名为 foo-2.log,将 foo.log 重命名为 foo -1.log。一个新的 foo.log 文件被创建并开始被写入。

最后,从 2.8 版开始,如果 fileIndex 属性设置为“ nomax”,则最小值和最大值将被忽略,文件编号将增加 1,并且每个翻转将具有递增的较高值,没有最大文件数。

DefaultRolloverStrategy Parameters

Parameter Name Type Description
fileIndex String 如果设置为“ max”(默认值),则索引较高的文件将比索引较小的文件更新。如果设置为“ min”,则文件重命名和计数器将遵循上述“固定窗口”策略。
min integer 计数器的最小值。预设值为 1.
max integer 计数器的最大值。达到此值后,较旧的归档文件将在以后的转换中被删除。预设值为 7.
compressionLevel integer 将压缩级别设置为 0-9,其中 0 =无,1 =最佳速度,直到 9 =最佳压缩。仅针对 ZIP 文件实现。
tempCompressedFilePattern String 压缩期间归档日志文件的文件名的模式。

DirectWrite 过渡策略

DirectWriteRolloverStrategy 导致日志事件直接写入由文件模式表示的文件。使用此策略文件将不执行重命名。如果基于大小的触发策略导致在指定的时间段内写入多个文件,则它们将从一个开始编号,并不断递增直到发生基于时间的翻转。

警告:如果文件模式的后缀表示应该进行压缩,则在关闭应用程序时不会压缩当前文件。此外,如果时间更改使得文件模式不再与当前文件匹配,则启动时也不会对其进行压缩。

DirectWriteRolloverStrategy Parameters

Parameter Name Type Description
maxFiles String 在与文件模式匹配的时间段内允许的最大文件数。如果超出文件数量,则最早的文件将被删除。如果指定,则该值必须大于 1.如果该值小于零或省略,则文件数量将不受限制。
compressionLevel integer 将压缩级别设置为 0-9,其中 0 =无,1 =最佳速度,直到 9 =最佳压缩。仅针对 ZIP 文件实现。
tempCompressedFilePattern String 压缩期间归档日志文件的文件名的模式。

下面是一个配置示例,该配置使用具有基于时间和大小的触发策略的 RollingFileAppender,将在同一天(1-7)最多创建 7 个归档文件,并根据当前年份和月份存储在目录中,并且使用 gzip 压缩每个 Files:

<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="warn" name="MyApp" packages="">
  <Appenders>
    <RollingFile name="RollingFile" fileName="logs/app.log"
                 filePattern="logs/$${date:yyyy-MM}/app-%d{MM-dd-yyyy}-%i.log.gz">
      <PatternLayout>
        <Pattern>%d %p %c{1.} [%t] %m%n</Pattern>
      </PatternLayout>
      <Policies>
        <TimeBasedTriggeringPolicy />
        <SizeBasedTriggeringPolicy size="250 MB"/>
      </Policies>
    </RollingFile>
  </Appenders>
  <Loggers>
    <Root level="error">
      <AppenderRef ref="RollingFile"/>
    </Root>
  </Loggers>
</Configuration>

第二个示例显示了一个过渡策略,该策略将最多保留 20 个文件,然后再将其删除。

<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="warn" name="MyApp" packages="">
  <Appenders>
    <RollingFile name="RollingFile" fileName="logs/app.log"
                 filePattern="logs/$${date:yyyy-MM}/app-%d{MM-dd-yyyy}-%i.log.gz">
      <PatternLayout>
        <Pattern>%d %p %c{1.} [%t] %m%n</Pattern>
      </PatternLayout>
      <Policies>
        <TimeBasedTriggeringPolicy />
        <SizeBasedTriggeringPolicy size="250 MB"/>
      </Policies>
      <DefaultRolloverStrategy max="20"/>
    </RollingFile>
  </Appenders>
  <Loggers>
    <Root level="error">
      <AppenderRef ref="RollingFile"/>
    </Root>
  </Loggers>
</Configuration>

下面是一个配置示例,该配置使用具有基于时间和大小的触发策略的 RollingFileAppender,将在同一天(1-7)最多创建 7 个归档文件,并根据当前年份和月份存储在目录中,并且使用 gzip 压缩每个 Files,当小时可被 6 整除时,它将每 6 小时滚动一次:

<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="warn" name="MyApp" packages="">
  <Appenders>
    <RollingFile name="RollingFile" fileName="logs/app.log"
                 filePattern="logs/$${date:yyyy-MM}/app-%d{yyyy-MM-dd-HH}-%i.log.gz">
      <PatternLayout>
        <Pattern>%d %p %c{1.} [%t] %m%n</Pattern>
      </PatternLayout>
      <Policies>
        <TimeBasedTriggeringPolicy interval="6" modulate="true"/>
        <SizeBasedTriggeringPolicy size="250 MB"/>
      </Policies>
    </RollingFile>
  </Appenders>
  <Loggers>
    <Root level="error">
      <AppenderRef ref="RollingFile"/>
    </Root>
  </Loggers>
</Configuration>

此示例配置使用具有基于 cron 和基于大小的触发策略的 RollingFileAppender,并直接写入无限数量的存档文件。当文件大小限制为 250MB 时,cron 触发器每小时导致一次翻转:

<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="warn" name="MyApp" packages="">
  <Appenders>
    <RollingFile name="RollingFile" filePattern="logs/app-%d{yyyy-MM-dd-HH}-%i.log.gz">
      <PatternLayout>
        <Pattern>%d %p %c{1.} [%t] %m%n</Pattern>
      </PatternLayout>
      <Policies>
        <CronTriggeringPolicy schedule="0 0 * * * ?"/>
        <SizeBasedTriggeringPolicy size="250 MB"/>
      </Policies>
    </RollingFile>
  </Appenders>
  <Loggers>
    <Root level="error">
      <AppenderRef ref="RollingFile"/>
    </Root>
  </Loggers>
</Configuration>

此示例配置与先前的示例配置相同,但是将每小时保存的文件数限制为 10:

<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="warn" name="MyApp" packages="">
  <Appenders>
    <RollingFile name="RollingFile" filePattern="logs/app-%d{yyyy-MM-dd-HH}-%i.log.gz">
      <PatternLayout>
        <Pattern>%d %p %c{1.} [%t] %m%n</Pattern>
      </PatternLayout>
      <Policies>
        <CronTriggeringPolicy schedule="0 0 * * * ?"/>
        <SizeBasedTriggeringPolicy size="250 MB"/>
      </Policies>
      <DirectWriteRolloverStrategy maxFiles="10"/>
    </RollingFile>
  </Appenders>
  <Loggers>
    <Root level="error">
      <AppenderRef ref="RollingFile"/>
    </Root>
  </Loggers>
</Configuration>

日志归档保留策略:过渡时删除

Log4j-2.5 引入了 Delete(删除)操作,与 DefaultRolloverStrategy max 属性所提供的功能相比,Log4j-2.5 为用户提供了对在转换时删除哪些文件的更多控制。删除操作使用户可以配置一个或多个条件,以选择要相对于基本目录删除的文件。

请注意,可以删除任何文件,而不仅仅是删除日志文件,因此请谨慎使用此操作!使用 testMode 参数,您可以测试配置,而不会意外删除错误的文件。

Delete Parameters

Parameter Name Type Description
basePath String 需要。从此处开始扫描要删除的文件的基本路径。
maxDepth int 要访问的目录的最大级别数。值为 0 表示仅访问起始文件(基本路径本身),除非安全 Management 器拒绝。 Integer.MAX_VALUE 的值指示应访问所有级别。默认值为 1,表示仅指定基目录中的文件。
followLinks boolean 是否遵循符号链接。默认为 false。
testMode boolean 如果为 true,则不会删除文件,而是在 INFO 级别将一条消息打印到status logger。使用它进行空运行以测试配置是否按预期工作。默认为 false。
pathSorter PathSorter 一个实现PathSorter接口的插件,用于在选择要删除的文件之前对文件进行排序。默认设置是首先对最近修改的文件进行排序。
pathConditions PathCondition[] 如果未指定 ScriptCondition,则为必需。一个或多个 PathCondition 元素。


如果指定了多个条件,则它们都需要接受路径才能删除。条件可以嵌套,在这种情况下,仅当外部条件接受路径时才评估内部条件。如果没有嵌套条件,则可以按任何 Sequences 对其进行评估。
通过使用 IfAll,IfAny 和 IfNot 复合条件,条件也可以与逻辑运算符 AND,OR 和 NOT 组合。
用户可以创建自定义条件或使用内置条件:
IfFileName-接受路径(相对于基本路径)匹配regular expressionglob的文件。
IfLastModified-接受早于指定duration的文件。
IfAccumulatedFileCount-在文件树遍历过程中超过某个计数阈值后接受路径。
IfAccumulatedFileSize-在文件树遍历过程中超过累积的文件大小阈值之后接受路径。
IfAll-如果所有嵌套条件都接受路径(逻辑与),则接受路径。嵌套条件可以任何 Sequences 进行评估。
IfAny-如果其中一个嵌套条件接受路径(逻辑或),则接受路径。嵌套条件可以任何 Sequences 进行评估。
IfNot-如果嵌套条件不接受路径(逻辑非),则接受路径。
| scriptCondition | ScriptCondition |如果未指定 PathConditions,则为必需。指定脚本的 ScriptCondition 元素。
ScriptCondition 应该包含一个脚本,ScriptRef 或 ScriptFile元素,该元素指定要执行的逻辑。 (有关配置 ScriptFiles 和 ScriptRefs 的更多示例,另请参见ScriptFilter文档。)
向脚本传递了多个parameters,包括在基本路径下找到的路径列表(最大 maxDepth),并且必须返回包含要删除的路径的列表。

Parameter Name Type Description
glob String 如果未指定正则表达式则为必需。使用类似于正则表达式但带有simpler syntax的有限模式语言匹配相对路径(相对于基本路径)。
regex String 如果未指定 glob,则为必需。使用Pattern类定义的正则表达式匹配相对路径(相对于基本路径)。
nestedConditions PathCondition[] 一组可选的嵌套PathConditions。如果存在任何嵌套条件,则它们都需要在删除文件之前接受该文件。仅当外部条件接受文件时(如果路径名匹配),才评估嵌套条件。

Parameter Name Type Description
age String 需要。指定duration。该条件接受的文件早于指定的期限。
nestedConditions PathCondition[] 一组可选的嵌套PathConditions。如果存在任何嵌套条件,则它们都需要在删除文件之前接受该文件。仅当外部条件接受文件时(如果文件足够旧),才评估嵌套条件。

Parameter Name Type Description
exceeds int 需要。从中删除文件的阈值计数。
nestedConditions PathCondition[] 一组可选的嵌套PathConditions。如果存在任何嵌套条件,则它们都需要在删除文件之前接受该文件。仅当外部条件接受文件时(如果已超过阈值计数),才评估嵌套条件。

Parameter Name Type Description
exceeds String 需要。将从中删除文件的阈值累积文件大小。大小可以字节为单位,后缀为 KB,MB 或 GB,例如 20MB。
nestedConditions PathCondition[] 一组可选的嵌套PathConditions。如果存在任何嵌套条件,则它们都需要在删除文件之前接受该文件。仅当外部条件接受文件时(如果已超过阈值累积文件大小),才评估嵌套条件。

以下是使用 RollingFileAppender 的示例配置,其中 cron 触发策略配置为每天午夜触发。归档文件基于当前年份和月份存储在目录中。基本目录下与“ /app-。log.gz” glob 相匹配的所有文件,以及早于 60 天或更早的文件,都将在过渡时删除。

<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="warn" name="MyApp" packages="">
  <Properties>
    <Property name="baseDir">logs</Property>
  </Properties>
  <Appenders>
    <RollingFile name="RollingFile" fileName="${baseDir}/app.log"
          filePattern="${baseDir}/$${date:yyyy-MM}/app-%d{yyyy-MM-dd}.log.gz">
      <PatternLayout pattern="%d %p %c{1.} [%t] %m%n" />
      <CronTriggeringPolicy schedule="0 0 0 * * ?"/>
      <DefaultRolloverStrategy>
        <Delete basePath="${baseDir}" maxDepth="2">
          <IfFileName glob="*/app-*.log.gz" />
          <IfLastModified age="60d" />
        </Delete>
      </DefaultRolloverStrategy>
    </RollingFile>
  </Appenders>
  <Loggers>
    <Root level="error">
      <AppenderRef ref="RollingFile"/>
    </Root>
  </Loggers>
</Configuration>

以下是一个配置示例,该配置使用具有基于时间和大小的触发策略的 RollingFileAppender,将在同一天(1-100)上创建多达 100 个存档,这些存档基于当前年份和月份存储在目录中,并且使用 gzip 压缩每个归档文件,并将每小时滚动一次。在每次过渡期间,此配置都将删除与“ /app-。log.gz”匹配且早于 30 天的文件,但保留最新的 100 GB 或最新的 10 个文件(以先到者为准)。

<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="warn" name="MyApp" packages="">
  <Properties>
    <Property name="baseDir">logs</Property>
  </Properties>
  <Appenders>
    <RollingFile name="RollingFile" fileName="${baseDir}/app.log"
          filePattern="${baseDir}/$${date:yyyy-MM}/app-%d{yyyy-MM-dd-HH}-%i.log.gz">
      <PatternLayout pattern="%d %p %c{1.} [%t] %m%n" />
      <Policies>
        <TimeBasedTriggeringPolicy />
        <SizeBasedTriggeringPolicy size="250 MB"/>
      </Policies>
      <DefaultRolloverStrategy max="100">
        <!--
        Nested conditions: the inner condition is only evaluated on files
        for which the outer conditions are true.
        -->
        <Delete basePath="${baseDir}" maxDepth="2">
          <IfFileName glob="*/app-*.log.gz">
            <IfLastModified age="30d">
              <IfAny>
                <IfAccumulatedFileSize exceeds="100 GB" />
                <IfAccumulatedFileCount exceeds="10" />
              </IfAny>
            </IfLastModified>
          </IfFileName>
        </Delete>
      </DefaultRolloverStrategy>
    </RollingFile>
  </Appenders>
  <Loggers>
    <Root level="error">
      <AppenderRef ref="RollingFile"/>
    </Root>
  </Loggers>
</Configuration>

ScriptCondition Parameters

Parameter Name Type Description
script 脚本,ScriptFile 或 ScriptRef Script 元素,指定要执行的逻辑。向脚本传递了在基本路径下找到的路径列表,并且必须以 java.util.List< PathWithAttributes >的形式返回要删除的路径。另请参阅ScriptFilter文档,以获取有关如何配置 ScriptFiles 和 ScriptRefs 的示例。

Script Parameters

Parameter Name Type Description
basePath java.nio.file.Path “删除”操作从其开始扫描要删除的文件的目录。可以用来相对于 pathList 中的路径。
pathList java.util.List<PathWithAttributes> 在基本路径下找到的最大指定深度的路径列表,将最先修改的文件排在最前。该脚本可以自由修改并返回此列表。
statusLogger StatusLogger StatusLogger 可用于在脚本执行期间记录内部事件。
configuration Configuration 拥有此 ScriptCondition 的配置。
substitutor StrSubstitutor StrSubstitutor 用于替换查找变量。
? String 配置中声明的所有属性。

以下是使用 RollingFileAppender 的示例配置,其中 cron 触发策略配置为每天午夜触发。归档文件基于当前年份和月份存储在目录中。该脚本返回日期为 13 日(星期五)的基本目录下的滚存文件列表。 Delete 操作将删除脚本返回的所有文件。

<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="trace" name="MyApp" packages="">
  <Properties>
    <Property name="baseDir">logs</Property>
  </Properties>
  <Appenders>
    <RollingFile name="RollingFile" fileName="${baseDir}/app.log"
          filePattern="${baseDir}/$${date:yyyy-MM}/app-%d{yyyyMMdd}.log.gz">
      <PatternLayout pattern="%d %p %c{1.} [%t] %m%n" />
      <CronTriggeringPolicy schedule="0 0 0 * * ?"/>
      <DefaultRolloverStrategy>
        <Delete basePath="${baseDir}" maxDepth="2">
          <ScriptCondition>
            <Script name="superstitious" language="groovy"><![CDATA[
                import java.nio.file.*;

                def result = [];
                def pattern = ~/\d*\/app-(\d*)\.log\.gz/;

                pathList.each { pathWithAttributes ->
                  def relative = basePath.relativize pathWithAttributes.path
                  statusLogger.trace 'SCRIPT: relative path=' + relative + " (base=$basePath)";

                  // remove files dated Friday the 13th

                  def matcher = pattern.matcher(relative.toString());
                  if (matcher.find()) {
                    def dateString = matcher.group(1);
                    def calendar = Date.parse("yyyyMMdd", dateString).toCalendar();
                    def friday13th = calendar.get(Calendar.DAY_OF_MONTH) == 13 \
                                  && calendar.get(Calendar.DAY_OF_WEEK) == Calendar.FRIDAY;
                    if (friday13th) {
                      result.add pathWithAttributes;
                      statusLogger.trace 'SCRIPT: deleting path ' + pathWithAttributes;
                    }
                  }
                }
                statusLogger.trace 'SCRIPT: returning ' + result;
                result;
              ]] >
            </Script>
          </ScriptCondition>
        </Delete>
      </DefaultRolloverStrategy>
    </RollingFile>
  </Appenders>
  <Loggers>
    <Root level="error">
      <AppenderRef ref="RollingFile"/>
    </Root>
  </Loggers>
</Configuration>

日志存档文件属性查看策略:过渡时的自定义文件属性

Log4j-2.9 引入了 PosixViewAttribute 操作,该操作使用户可以更好地控制应应用的文件属性权限,所有者和组。 PosixViewAttribute 操作允许用户配置一个或多个条件,这些条件选择相对于基本目录的合格文件。

PosixViewAttribute Parameters

Parameter Name Type Description
basePath String 需要。从此处开始扫描文件以应用属性的基本路径。
maxDepth int 要访问的目录的最大级别数。值为 0 表示仅访问起始文件(基本路径本身),除非安全 Management 器拒绝。 Integer.MAX_VALUE 的值指示应访问所有级别。默认值为 1,表示仅指定基目录中的文件。
followLinks boolean 是否遵循符号链接。默认为 false。
pathConditions PathCondition[] see DeletePathCondition
filePermissions String POSIX 格式的文件属性权限在执行操作时适用。

基础文件系统应支持POSIX文件属性视图。
例如:rw -------或 rw-rw-rw-等...
fileOwner String 文件所有者,用于定义何时执行操作。
出于安全原因,更改文件的所有者可能受到限制,并且不允许操作 IOException 抛出。如果_POSIX_CHOWN_RESTRICTED对路径有效,则只有有效用户 ID 等于文件用户 ID 或具有适当特权的进程才可以更改文件的所有权。
基础文件系统应支持文件owner属性视图。
fileGroup String 文件组,用于定义何时执行操作。
基础文件系统应支持POSIX文件属性视图。

以下是使用 RollingFileAppender 并为当前和滚动日志文件定义不同 POSIX 文件属性视图的示例配置。

<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="trace" name="MyApp" packages="">
  <Properties>
    <Property name="baseDir">logs</Property>
  </Properties>
  <Appenders>
    <RollingFile name="RollingFile" fileName="${baseDir}/app.log"
          		 filePattern="${baseDir}/$${date:yyyy-MM}/app-%d{yyyyMMdd}.log.gz"
                 filePermissions="rw-------">
      <PatternLayout pattern="%d %p %c{1.} [%t] %m%n" />
      <CronTriggeringPolicy schedule="0 0 0 * * ?"/>
      <DefaultRolloverStrategy stopCustomActionsOnError="true">
        <PosixViewAttribute basePath="${baseDir}/$${date:yyyy-MM}" filePermissions="r--r--r--">
        	<IfFileName glob="*.gz" />
        </PosixViewAttribute>
      </DefaultRolloverStrategy>
    </RollingFile>
  </Appenders>

  <Loggers>
    <Root level="error">
      <AppenderRef ref="RollingFile"/>
    </Root>
  </Loggers>

</Configuration>

RollingRandomAccessFileAppender

RollingRandomAccessFileAppender 与标准RollingFileAppender相似,除了它始终被缓冲(无法关闭)并且在内部它使用 ByteBuffer RandomAccessFile 而不是 BufferedOutputStream。与在measurements中使用“ bufferedIO = true”的 RollingFileAppender 相比,性能提高了 20-200%。 RollingRandomAccessFileAppender 写入 fileName 参数中命名的 File,然后根据 TriggeringPolicy 和 RolloverPolicy 将文件翻转。与 RollingFileAppender 相似,RollingRandomAccessFileAppender 使用 RollingRandomAccessFileManager 实际执行文件 I/O 并执行翻转。虽然无法共享来自不同配置的 RollingRandomAccessFileAppender,但如果可以访问 Manager,则可以使用 RollingRandomAccessFileManagers。例如,如果 Log4j 位于两个容器都通用的 ClassLoader 中,则 Servlet 容器中的两个 Web 应用程序可以具有自己的配置,并可以安全地写入同一文件。

RollingRandomAccessFileAppender 需要TriggeringPolicyRolloverStrategy。触发策略确定是否应执行过渡,而 RolloverStrategy 定义应如何进行过渡。如果未配置 RolloverStrategy,则 RollingRandomAccessFileAppender 将使用DefaultRolloverStrategy。从 log4j-2.5 开始,可以在 DefaultRolloverStrategy 中将自定义删除动作配置为在翻转时运行。

RollingRandomAccessFileAppender 不支持文件锁定。

RollingRandomAccessFileAppender Parameters

Parameter Name Type Description
append boolean 如果为 true-默认值,记录将附加到文件末尾。设置为 false 时,将在写入新记录之前清除文件。
filter Filter 确定事件是否应由此 Appender 处理的过滤器。通过使用 CompositeFilter,可以使用多个过滤器。
fileName String 要写入的文件名。如果该文件或其任何父目录不存在,则将创建它们。
filePattern String 归档日志文件的文件名的模式。模式的格式应取决于所使用的 RolloverStrategu。 DefaultRolloverStrategy 将接受与SimpleDateFormat兼容的日期/时间模式和/或代表整数计数器的%i。整数计数器允许指定填充,例如%3i 用于将计数器空格填充到 3 位,或者(通常更有用)%03i 用于将计数器零填充到 3 位。该模式还支持在运行时进行插值,因此任何查询(例如DateLookup都可以包含在该模式中)。
immediateFlush boolean 设置为 true-默认值时,每次写操作后都会进行刷新。这将确保将数据写入磁盘,但可能会影响性能。


每次写入后刷新仅在将此追加器与同步 Logger 一起使用时才有用。即使将 InstantFlush 设置为 false,异步 Logger 和附加器也将在一批事件结束时自动刷新。这也保证了将数据写入磁盘但效率更高。
|| bufferSize |||缓冲区大小,默认为 262,144 字节(256 * 1024)。
| layout | Layout |用于格式化 LogEvent 的布局。如果未提供任何布局,则将使用默认样式布局“%m%n”。
| name | String |Appender 的名称。
| policy | TriggeringPolicy |用于确定是否应该发生过渡的策略。 |
| strategy | RolloverStrategy |用于确定存档文件的名称和位置的策略。 |
| ignoreExceptions | boolean |缺省值为 true,导致在追加事件时遇到的异常将在内部记录,然后被忽略。设置为 false 时,异常将传播到调用方。当将此 Appender 包装在FailoverAppender中时,必须将其设置为 false。
| filePermissions | String |文件属性权限(采用 POSIX 格式)在创建文件时应用。
基础文件系统应支持POSIX文件属性视图。
例如:rw -------或 rw-rw-rw-等... |
| fileOwner | String |文件所有者,用于定义何时创建文件。
出于安全原因,更改文件的所有者可能受到限制,并且不允许操作 IOException 抛出。如果_POSIX_CHOWN_RESTRICTED对路径有效,则只有有效用户 ID 等于文件用户 ID 或具有适当特权的进程才可以更改文件的所有权。
基础文件系统应支持文件owner属性视图。
| fileGroup | String |文件组,用于在创建文件时进行定义。
基础文件系统应支持POSIX文件属性视图。

Triggering Policies

See RollingFileAppender 触发策略.

Rollover Strategies

See RollingFileAppender 过渡策略.

下面是一个配置示例,该配置使用具有基于时间和大小的触发策略的 RollingRandomAccessFileAppender,将在同一天(1-7)创建最多 7 个归档文件,这些归档文件基于当前年份和月份存储在目录中,并且使用 gzip 压缩每个 Files:

<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="warn" name="MyApp" packages="">
  <Appenders>
    <RollingRandomAccessFile name="RollingRandomAccessFile" fileName="logs/app.log"
                 filePattern="logs/$${date:yyyy-MM}/app-%d{MM-dd-yyyy}-%i.log.gz">
      <PatternLayout>
        <Pattern>%d %p %c{1.} [%t] %m%n</Pattern>
      </PatternLayout>
      <Policies>
        <TimeBasedTriggeringPolicy />
        <SizeBasedTriggeringPolicy size="250 MB"/>
      </Policies>
    </RollingRandomAccessFile>
  </Appenders>
  <Loggers>
    <Root level="error">
      <AppenderRef ref="RollingRandomAccessFile"/>
    </Root>
  </Loggers>
</Configuration>

第二个示例显示了一个过渡策略,该策略将最多保留 20 个文件,然后再将其删除。

<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="warn" name="MyApp" packages="">
  <Appenders>
    <RollingRandomAccessFile name="RollingRandomAccessFile" fileName="logs/app.log"
                 filePattern="logs/$${date:yyyy-MM}/app-%d{MM-dd-yyyy}-%i.log.gz">
      <PatternLayout>
        <Pattern>%d %p %c{1.} [%t] %m%n</Pattern>
      </PatternLayout>
      <Policies>
        <TimeBasedTriggeringPolicy />
        <SizeBasedTriggeringPolicy size="250 MB"/>
      </Policies>
      <DefaultRolloverStrategy max="20"/>
    </RollingRandomAccessFile>
  </Appenders>
  <Loggers>
    <Root level="error">
      <AppenderRef ref="RollingRandomAccessFile"/>
    </Root>
  </Loggers>
</Configuration>

下面是一个配置示例,该配置使用具有基于时间和大小的触发策略的 RollingRandomAccessFileAppender,将在同一天(1-7)创建最多 7 个归档文件,这些归档文件基于当前年份和月份存储在目录中,并且使用 gzip 压缩每个 Files,当小时可被 6 整除时,它将每 6 小时滚动一次:

<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="warn" name="MyApp" packages="">
  <Appenders>
    <RollingRandomAccessFile name="RollingRandomAccessFile" fileName="logs/app.log"
                 filePattern="logs/$${date:yyyy-MM}/app-%d{yyyy-MM-dd-HH}-%i.log.gz">
      <PatternLayout>
        <Pattern>%d %p %c{1.} [%t] %m%n</Pattern>
      </PatternLayout>
      <Policies>
        <TimeBasedTriggeringPolicy interval="6" modulate="true"/>
        <SizeBasedTriggeringPolicy size="250 MB"/>
      </Policies>
    </RollingRandomAccessFile>
  </Appenders>
  <Loggers>
    <Root level="error">
      <AppenderRef ref="RollingRandomAccessFile"/>
    </Root>
  </Loggers>
</Configuration>

RoutingAppender

RoutingAppender 评估 LogEvents,然后将它们路由到下级 Appender。目标 Appender 可以是先前配置的 Appender,可以通过其名称引用,也可以根据需要动态创建 Appender。应该在路由引用的任何 Appender 之后对其进行配置,以使其能够正常关闭。

您还可以使用脚本配置 RoutingAppender:可以在启动附加程序时以及为日志事件选择路由时运行脚本。

RoutingAppender Parameters

Parameter Name Type Description
Filter Filter 确定事件是否应由此 Appender 处理的过滤器。通过使用 CompositeFilter,可以使用多个过滤器。
name String Appender的名字。
RewritePolicy RewritePolicy 将操纵 LogEvent 的 RewritePolicy。
Routes Routes 包含一个或多个 Route 声明,以标识选择 Appender 的标准。
Script Script 当 Log4j 启动 RoutingAppender 并返回 String Route 键以确定默认 Route 时,此脚本运行。


该脚本传递了以下变量:
* RoutingAppender 脚本参数*

|参数名称|类型描述

|配置|配置|活动配置。 |

| staticVariables |Map|此追加器实例的所有脚本调用之间共享的 Map。这是传递给 Route 脚本的同一 Map。 ||
| ignoreExceptions | boolean |缺省值为 true,导致在追加事件时遇到的异常将在内部记录,然后被忽略。设置为 false 时,异常将传播到调用方。当将此 Appender 包装在FailoverAppender中时,必须将其设置为 false。

在此示例中,脚本使“ ServiceWindows”路由成为 Windows 上的默认路由,成为所有其他 os 上的“ ServiceOther”。请注意,列表追加器是我们的测试追加器之一,可以使用任何追加器,它仅用作速记。

<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN" name="RoutingTest">
  <Appenders>
    <Routing name="Routing">
      <Script name="RoutingInit" language="JavaScript"><![CDATA[
        importPackage(java.lang);
        System.getProperty("os.name").search("Windows") > -1 ? "ServiceWindows" : "ServiceOther";]]>
      </Script>
      <Routes>
        <Route key="ServiceOther">
          <List name="List1" />
        </Route>
        <Route key="ServiceWindows">
          <List name="List2" />
        </Route>
      </Routes>
    </Routing>
  </Appenders>
  <Loggers>
    <Root level="error">
      <AppenderRef ref="Routing" />
    </Root>
  </Loggers>
</Configuration>

Routes

Routes 元素接受一个名为“ pattern”的属性。针对所有已注册的 Lookup 评估该模式,并将结果用于选择路径。每个路由都可以配置一个密钥。如果键与评估模式的结果匹配,则将选择该 Route。如果未在路由上指定任何键,则该路由为默认路由。默认只能配置一个路由。

Routes 元素可能包含 Script 子元素。如果指定,则为每个日志事件运行脚本,并返回要使用的字符串路由键。

您必须指定 pattern 属性或 Script 元素,但不能两者都指定。

每个 Route 都必须引用一个添加者。如果 Route 包含 ref 属性,则 Route 将引用配置中定义的 Appender。如果路由包含一个 Appender 定义,则将在 RoutingAppender 的上下文中创建一个 Appender,并且每次通过 Route 引用匹配的 Appender 名称时,都会重复使用该 Appender。

该脚本传递了以下变量:

Parameter Name Type Description
configuration Configuration 活动配置。
staticVariables Map 此追加器实例的所有脚本调用之间共享的 Map。这是传递给 Route 脚本的同一 Map。
logEvent LogEvent 日志事件。

在此示例中,脚本针对每个日志事件运行,并根据名为“ AUDIT”的标记的存在来选择路由。

<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN" name="RoutingTest">
  <Appenders>
    <Console name="STDOUT" target="SYSTEM_OUT" />
    <Flume name="AuditLogger" 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>
    <Routing name="Routing">
      <Routes>
        <Script name="RoutingInit" language="JavaScript"><![CDATA[
          if (logEvent.getMarker() != null && logEvent.getMarker().isInstanceOf("AUDIT")) {
                return "AUDIT";
            } else if (logEvent.getContextMap().containsKey("UserId")) {
                return logEvent.getContextMap().get("UserId");
            }
            return "STDOUT";]]>
        </Script>
        <Route>
          <RollingFile
              name="Rolling-${mdc:UserId}"
              fileName="${mdc:UserId}.log"
              filePattern="${mdc:UserId}.%i.log.gz">
            <PatternLayout>
              <pattern>%d %p %c{1.} [%t] %m%n</pattern>
            </PatternLayout>
            <SizeBasedTriggeringPolicy size="500" />
          </RollingFile>
        </Route>
        <Route ref="AuditLogger" key="AUDIT"/>
        <Route ref="STDOUT" key="STDOUT"/>
      </Routes>
      <IdlePurgePolicy timeToLive="15" timeUnit="minutes"/>
    </Routing>
  </Appenders>
  <Loggers>
    <Root level="error">
      <AppenderRef ref="Routing" />
    </Root>
  </Loggers>
</Configuration>

Purge Policy

可以使用 PurgePolicy 配置 RoutingAppender,其目的是停止和删除由 RoutingAppender 动态创建的休眠 Appender。 Log4j 当前提供 IdlePurgePolicy 作为唯一可用于清理 Appender 的 PurgePolicy。 IdlePurgePolicy 接受 2 个属性; timeToLive,它是 Appender 在不发送任何事件的情况下应生存的 timeUnit 数,以及 timeUnit(与 timeToLive 属性一起使用的 java.util.concurrent.TimeUnit 的 String 表示形式)。

下面是一个示例配置,该配置使用 RoutingAppender 将所有 Audit 事件路由到 FlumeAppender,而所有其他事件将被路由到 RollingFileAppender,该 RollingFileAppender 仅捕获特定的事件类型。请注意,根据需要在创建 RollingFileAppenders 时 sched 义了 AuditAppender。

<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="warn" name="MyApp" packages="">
  <Appenders>
    <Flume name="AuditLogger" 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>
    <Routing name="Routing">
      <Routes pattern="$${sd:type}">
        <Route>
          <RollingFile name="Rolling-${sd:type}" fileName="${sd:type}.log"
                       filePattern="${sd:type}.%i.log.gz">
            <PatternLayout>
              <pattern>%d %p %c{1.} [%t] %m%n</pattern>
            </PatternLayout>
            <SizeBasedTriggeringPolicy size="500" />
          </RollingFile>
        </Route>
        <Route ref="AuditLogger" key="Audit"/>
      </Routes>
      <IdlePurgePolicy timeToLive="15" timeUnit="minutes"/>
    </Routing>
  </Appenders>
  <Loggers>
    <Root level="error">
      <AppenderRef ref="Routing"/>
    </Root>
  </Loggers>
</Configuration>

SMTPAppender

当特定的日志事件发生时,通常是在错误或致命错误时,发送电子邮件。

此电子邮件中传递的日志事件的数量取决于 BufferSize 选项的值。 SMTPAppender 仅将最后的 BufferSize 日志记录事件保留在其循环缓冲区中。这将内存需求保持在合理的水平,同时仍提供有用的应用程序上下文。缓冲区中的所有事件都包含在电子邮件中。缓冲区将包含触发电子邮件的事件之前的 TRACE 到 WARN 级别的最新事件。

默认行为是在记录 ERROR 或更高严重性事件时触发发送电子邮件,并将其格式化为 HTML。可以通过在 Appender 上设置一个或多个过滤器来控制发送电子邮件的时间。与其他 Appender 一样,可以通过为 Appender 指定布局来控制格式。

SMTPAppender Parameters

Parameter Name Type Description
name String Appender的名字。
from String 发件人的电子邮件地址。
replyTo String 以逗号分隔的回复电子邮件地址列表。
to String 以逗号分隔的收件人电子邮件地址列表。
cc String CC 电子邮件地址的逗号分隔列表。
bcc String 密件抄送电子邮件地址列表,以逗号分隔。
subject String 电子邮件的主题。
bufferSize integer 要缓冲以包含在消息中的最大日志事件数。默认值为 512.
layout Layout 用于格式化 LogEvent 的 Layout。如果未提供布局,将使用HTML layout
filter Filter 确定事件是否应由此 Appender 处理的过滤器。通过使用 CompositeFilter,可以使用多个过滤器。
smtpDebug boolean 设置为 true 时,将在 STDOUT 上启用会话调试。默认为 false。
smtpHost String 要发送到的 SMTP 主机名。此参数是必需的。
smtpPassword String 对 SMTP 服务器进行身份验证所需的密码。
smtpPort integer 要发送到的 SMTP 端口。
smtpProtocol String SMTP 传输协议(例如“ smtps”,默认为“ smtp”)。
smtpUsername String 针对 SMTP 服务器进行身份验证所需的用户名。
ignoreExceptions boolean 默认值为 true,导致在追加事件时遇到的异常会在内部记录下来,然后被忽略。设置为 false 时,异常将传播到调用方。当将此 Appender 封装在FailoverAppender中时,必须将其设置为 false。
SSL SslConfiguration 包含 KeyStore 和 TrustStore 的配置。参见SSL
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="warn" name="MyApp" packages="">
  <Appenders>
    <SMTP name="Mail" subject="Error Log" to="errors@logging.apache.org" from="test@logging.apache.org"
          smtpHost="localhost" smtpPort="25" bufferSize="50">
    </SMTP>
  </Appenders>
  <Loggers>
    <Root level="error">
      <AppenderRef ref="Mail"/>
    </Root>
  </Loggers>
</Configuration>

ScriptAppenderSelector

构建配置后,ScriptAppenderSelector 附加程序会调用 Script 来计算附加程序名称。然后,Log4j 使用 ScriptAppenderSelector 的名称创建在 AppenderSet 下列出的名称的附加程序之一。配置后,Log4j 将忽略 ScriptAppenderSelector。 Log4j 仅从配置树中构建一个选定的附加程序,而忽略其他 AppenderSet 子节点。

在下面的示例中,脚本返回名称“ List2”。附加程序名称记录在 ScriptAppenderSelector 的名称下,而不是所选附加程序的名称(在此示例中为“ SelectIt”)。

<Configuration status="WARN" name="ScriptAppenderSelectorExample">
  <Appenders>
    <ScriptAppenderSelector name="SelectIt">
      <Script language="JavaScript"><![CDATA[
        importPackage(java.lang);
        System.getProperty("os.name").search("Windows") > -1 ? "MyCustomWindowsAppender" : "MySyslogAppender";]]>
      </Script>
      <AppenderSet>
        <MyCustomWindowsAppender name="MyAppender" ... />
        <SyslogAppender name="MySyslog" ... />
      </AppenderSet>
    </ScriptAppenderSelector>
  </Appenders>
  <Loggers>
    <Root level="error">
      <AppenderRef ref="SelectIt" />
    </Root>
  </Loggers>
</Configuration>

SocketAppender

SocketAppender 是一个 OutputStreamAppender,它将其输出写入由主机和端口指定的远程目标。数据可以通过 TCP 或 UDP 发送,并且可以任何格式发送。您可以选择与SSL进行安全通信。请注意,TCP 和 SSL 变体以流的形式写入套接字,并且不期望来自目标目的地的响应。由于 TCP 协议的限制,这意味着当目标服务器关闭其连接时,某些日志事件可能会 continue 显示成功,直到引发关闭的连接异常,从而导致这些事件丢失。如果需要保证交付,则必须使用需要确认的协议。

SocketAppender Parameters

Parameter Name Type Description
name String Appender的名字。
host String 正在侦听日志事件的系统的名称或地址。此参数是必需的。如果主机名解析为多个 IP 地址,则当连接断开时,TCP 和 SSL 变体将故障转移到下一个 IP 地址。
port integer 主机上正在侦听日志事件的端口。必须指定此参数。
protocol String “ TCP”(默认),“ SSL”或“ UDP”。
SSL SslConfiguration 包含 KeyStore 和 TrustStore 的配置。参见SSL
filter Filter 确定事件是否应由此 Appender 处理的过滤器。通过使用 CompositeFilter,可以使用多个过滤器。
immediateFail boolean 设置为 true 时,日志事件将不 await 尝试重新连接,并且如果套接字不可用,日志事件将立即失败。
immediateFlush boolean 设置为 true-默认值时,每次写操作后都会进行刷新。这将确保将数据写入磁盘,但可能会影响性能。
bufferedIO boolean 为 true 时-默认情况下,事件将写入缓冲区,并且在缓冲区已满或写入记录(如果设置了 InstantFlush)时,数据将写入套接字。
bufferSize int 当 bufferedIO 为 true 时,这是缓冲区大小,默认值为 8192 字节。
layout Layout 用于格式化 LogEvent 的 Layout。必需,没有默认值。从 2.9 开始新增,在以前的版本中,默认为 SerializedLayout。
reconnectionDelayMillis integer 如果设置为大于 0 的值,则在发生错误后,SocketManager 将在 await 指定的毫秒数后尝试重新连接到服务器。如果重新连接失败,则将引发异常(如果将 ignoreExceptions 设置为 false,则应用程序可以捕获该异常)。
connectTimeoutMillis integer 连接超时(以毫秒为单位)。默认值为 0(无限超时,例如 Socket.connect()方法)。
ignoreExceptions boolean 默认值为 true,导致在追加事件时遇到的异常会在内部记录下来,然后被忽略。设置为 false 时,异常将传播到调用方。当将此 Appender 封装在FailoverAppender中时,必须将其设置为 false。

这是不安全的 TCP 配置:

<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="warn" name="MyApp" packages="">
  <Appenders>
    <Socket name="socket" host="localhost" port="9500">
      <JsonLayout properties="true"/>
    </Socket>
  </Appenders>
  <Loggers>
    <Root level="error">
      <AppenderRef ref="socket"/>
    </Root>
  </Loggers>
</Configuration>

这是一个安全的SSL配置:

<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="warn" name="MyApp" packages="">
  <Appenders>
    <Socket name="socket" host="localhost" port="9500">
      <JsonLayout properties="true"/>
      <SSL>
        <KeyStore   location="log4j2-keystore.jks" passwordEnvironmentVariable="KEYSTORE_PASSWORD"/>
        <TrustStore location="truststore.jks"      passwordFile="${sys:user.home}/truststore.pwd"/>
      </SSL>
    </Socket>
  </Appenders>
  <Loggers>
    <Root level="error">
      <AppenderRef ref="socket"/>
    </Root>
  </Loggers>
</Configuration>

SSL Configuration

可以将多个附加程序配置为使用普通网络连接或安全套接字层(SSL)连接。本节介绍了可用于 SSL 配置的参数。

Parameter Name Type Description
protocol String SSL(如果省略)。另请参见Standard names
KeyStore KeyStore 包含您的私钥和证书,并确定要发送到远程主机的身份验证凭据。
TrustStore TrustStore 包含远程 Transaction 对手的 CA 证书。确定是否应该信任远程身份验证凭据(以及连接)。
verifyHostName boolean 切换是否执行主机名验证。默认为 false。

KeyStore

密钥库旨在包含您的私钥和证书,并确定要发送到远程主机的身份验证凭据。

密钥库配置参数

Parameter Name Type Description
location String 密钥库文件的路径。
password char[] 用于访问密钥库的纯文本密码。不能与 passwordEnvironmentVariable 或 passwordFile 结合使用。
passwordEnvironmentVariable String 包含密码的环境变量的名称。不能与 password 或 passwordFile 结合使用。
passwordFile String 存放密码的文件的路径。不能与 password 或 passwordEnvironmentVariable 结合使用。
type String 可选的 KeyStore 类型,例如 JKS,PKCS12,PKCS11,BKS,Windows-MY/Windows-ROOT,KeychainStore 等。默认值为 JKS。另请参见Standard types
keyManagerFactoryAlgorithm String 可选的 KeyManagerFactory 算法。默认值为 SunX509.另请参见Standard algorithms

TrustStore

信任存储区旨在包含当远程方出示证书时您愿意信任的 CA 证书。确定是否应该信任远程身份验证凭据(以及连接)。

在某些情况下,它们可以是一个存储库,并且可以是同一存储库,尽管使用不同的存储库(尤其是基于文件的存储库)通常是更好的做法。

Parameter Name Type Description
location String 密钥库文件的路径。
password char[] 用于访问密钥库的纯文本密码。不能与 passwordEnvironmentVariable 或 passwordFile 结合使用。
passwordEnvironmentVariable String 包含密码的环境变量的名称。不能与 password 或 passwordFile 结合使用。
passwordFile String 存放密码的文件的路径。不能与 password 或 passwordEnvironmentVariable 结合使用。
type String 可选的 KeyStore 类型,例如 JKS,PKCS12,PKCS11,BKS,Windows-MY/Windows-ROOT,KeychainStore 等。默认值为 JKS。另请参见Standard types
trustManagerFactoryAlgorithm String 可选的 TrustManagerFactory 算法。默认值为 SunX509.另请参见Standard algorithms

Example

...
      <SSL>
        <KeyStore   location="log4j2-keystore.jks" passwordEnvironmentVariable="KEYSTORE_PASSWORD"/>
        <TrustStore location="truststore.jks"      passwordFile="${sys:user.home}/truststore.pwd"/>
      </SSL>
  ...

SyslogAppender

SyslogAppender 是一个 SocketAppender,它将其输出以符合 BSD Syslog 格式或 RFC 5424 格式的格式写入到主机和端口指定的远程目标。数据可以通过 TCP 或 UDP 发送。

SyslogAppender Parameters

Parameter Name Type Description
advertise boolean 指示是否应发布附加程序。
appName String 在 RFC 5424 syslogLogging 用作 APP-NAME 的值。
charset String 将系统日志字符串转换为字节数组时使用的字符集。字符串必须是有效的Charset。如果未指定,将使用默认系统 Charset。
connectTimeoutMillis integer 连接超时(以毫秒为单位)。默认值为 0(无限超时,例如 Socket.connect()方法)。
enterpriseNumber integer RFC 5424中所述的 IANA 企业编号
filter Filter 确定事件是否应由此 Appender 处理的过滤器。通过使用 CompositeFilter,可以使用多个过滤器。
facility String 该工具用于尝试对消息进行分类。工具选项必须设置为“ KERN”,“ USER”,“ MAIL”,“ DAEMON”,“ AUTH”,“ SYSLOG”,“ LPR”,“ NEWS”,“ UUCP”,“ CRON”,“ AUTHPRIV”,“ FTP”,“ NTP”,“ AUDIT”,“ ALERT”,“ CLOCK”,“ LOCAL0”,“ LOCAL1”,“ LOCAL2”,“ LOCAL3”,“ LOCAL4”,“ LOCAL5”,“ LOCAL6”或“ LOCAL7”。这些值可以指定为大写或小写字符。
format String 如果设置为“ RFC5424”,则将按照 RFC 5424 格式化数据。否则,将其格式化为 BSD Syslog 记录。请注意,尽管 BSD Syslog 记录必须为 1024 字节或更短,但 SyslogLayout 不会截断它们。 RFC5424Layout 也不截断记录,因为接收者必须接受最大 2048 字节的记录,并且可能接受更长的记录。
host String 正在侦听日志事件的系统的名称或地址。此参数是必需的。
id String 根据 RFC 5424 进行格式化时要使用的默认结构化数据 ID。如果 LogEvent 包含 StructuredDataMessage,则将使用消息中的 ID 代替此值。
ignoreExceptions boolean 默认值为 true,导致在追加事件时遇到的异常会在内部记录下来,然后被忽略。设置为 false 时,异常将传播到调用方。当将此 Appender 封装在FailoverAppender中时,必须将其设置为 false。
immediateFail boolean 设置为 true 时,日志事件将不 await 尝试重新连接,并且如果套接字不可用,日志事件将立即失败。
immediateFlush boolean 设置为 true-默认值时,每次写操作后都会进行刷新。这将确保将数据写入磁盘,但可能会影响性能。
includeMDC boolean 指示是否将 ThreadContextMap 中的数据包含在 RFC 5424 SyslogLogging。默认为 true。
Layout Layout 覆盖格式设置的自定义布局。
loggerFields 键值对列表 允许将任意 PatternLayout 模式包含在指定的 ThreadContext 字段中;没有指定默认值。要使用,请包含> LoggerFields< nested element, containing one or more > KeyValuePair< elements. Each > KeyValuePair <必须具有一个 key 属性(用于指定将在 MDC 结构化数据元素中标识字段的密钥名称)和一个 value 属性(用于指定 PatternLayout 模式)用作值。
mdcExcludes String 逗号分隔的 mdc 键列表,应从 LogEvent 中排除。这与 mdcIncludes 属性互斥。此属性仅适用于 RFC 5424 syslog 记录。
mdcIncludes String 用逗号分隔的 mdc 密钥列表,应包含在 FlumeEvent 中。在列表中未找到的 MDC 中的任何键都将被排除。此选项与 mdcExcludes 属性互斥。此属性仅适用于 RFC 5424 syslog 记录。
mdcRequired String MDC 中必须存在的逗号分隔的 mdc 密钥列表。如果没有密钥,则将引发 LoggingException。此属性仅适用于 RFC 5424 syslog 记录。
mdcPrefix String 为了与事件属性区分开,应该在每个 MDC 关键字之前添加一个字符串。默认字符串是“ mdc:”。此属性仅适用于 RFC 5424 syslog 记录。
messageId String 在 RFC 5424 系统日志记录的 MSGID 字段中使用的默认值。
name String Appender的名字。
newLine boolean 如果为 true,则会在系统日志记录的末尾添加换行符。默认为 false。
port integer 主机上正在侦听日志事件的端口。必须指定此参数。
protocol String “ TCP”或“ UDP”。此参数是必需的。
SSL SslConfiguration 包含 KeyStore 和 TrustStore 的配置。参见SSL
reconnectionDelayMillis integer 如果设置为大于 0 的值,则在发生错误后,SocketManager 将在 await 指定的毫秒数后尝试重新连接到服务器。如果重新连接失败,则将引发异常(如果将 ignoreExceptions 设置为 false,则应用程序可以捕获该异常)。

samplessyslogAppender 配置,配置了两个 SyslogAppender,一个使用 BSD 格式,一个使用 RFC 5424.

<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="warn" name="MyApp" packages="">
  <Appenders>
    <Syslog name="bsd" host="localhost" port="514" protocol="TCP"/>
    <Syslog name="RFC5424" format="RFC5424" host="localhost" port="8514"
            protocol="TCP" appName="MyApp" includeMDC="true"
            facility="LOCAL0" enterpriseNumber="18060" newLine="true"
            messageId="Audit" id="App"/>
  </Appenders>
  <Loggers>
    <Logger name="com.mycorp" level="error">
      <AppenderRef ref="RFC5424"/>
    </Logger>
    <Root level="error">
      <AppenderRef ref="bsd"/>
    </Root>
  </Loggers>
</Configuration>

对于SSL,此附加程序将其输出通过 SSL 以符合 BSD Syslog 格式或 RFC 5424 格式的格式写入主机和端口指定的远程目标。

<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="warn" name="MyApp" packages="">
  <Appenders>
    <TLSSyslog name="bsd" host="localhost" port="6514">
      <SSL>
        <KeyStore   location="log4j2-keystore.jks" passwordEnvironmentVariable="KEYSTORE_PASSWORD"/>
        <TrustStore location="truststore.jks"      passwordFile="${sys:user.home}/truststore.pwd"/>
      </SSL>
    </TLSSyslog>
  </Appenders>
  <Loggers>
    <Root level="error">
      <AppenderRef ref="bsd"/>
    </Root>
  </Loggers>
</Configuration>

ZeroMQ/JeroMQ Appender

ZeroMQ 附加程序使用JeroMQ库将日志事件发送到一个或多个 ZeroMQ 端点。

这是一个简单的 JeroMQ 配置:

<?xml version="1.0" encoding="UTF-8"?>
<Configuration name="JeroMQAppenderTest" status="TRACE">
  <Appenders>
    <JeroMQ name="JeroMQAppender">
      <Property name="endpoint">tcp://*:5556</Property>
      <Property name="endpoint">ipc://info-topic</Property>
    </JeroMQ>
  </Appenders>
  <Loggers>
    <Root level="info">
      <AppenderRef ref="JeroMQAppender"/>
    </Root>
  </Loggers>
</Configuration>

下表描述了所有选项。有关详细信息,请查阅 JeroMQ 和 ZeroMQ 文档。

JeroMQ Parameters

Parameter Name Type Description
name String Appender的名字。需要。
Layout layout 用于格式化 LogEvent 的 Layout。如果未提供任何布局,则将使用默认图案布局“%m%n”。
Filters Filter Appender 的过滤器。
Properties Property[] 一个或多个属性元素,称为终结点。
ignoreExceptions boolean 如果为 true,将记录并抑制异常。如果错误,将记录错误,然后将其传递给应用程序。
affinity long ZMQ_AFFINITY 选项。预设为 0.
backlog long ZMQ_BACKLOG 选项。默认为 100.
delayAttachOnConnect boolean ZMQ_DELAY_ATTACH_ON_CONNECT 选项。默认为 false。
identity byte[] ZMQ_IDENTITY 选项。默认为无。
ipv4Only boolean ZMQ_IPV4ONLY 选项。默认为 true。
linger long ZMQ_LINGER 选项。默认为-1.
maxMsgSize long ZMQ_MAXMSGSIZE 选项。默认为-1.
rcvHwm long ZMQ_RCVHWM 选项。预设为 1000.
receiveBufferSize long ZMQ_RCVBUF 选项。预设为 0.
receiveTimeOut int ZMQ_RCVTIMEO 选项。默认为-1.
reconnectIVL long ZMQ_RECONNECT_IVL 选项。默认为 100.
reconnectIVLMax long ZMQ_RECONNECT_IVL_MAX 选项。预设为 0.
sendBufferSize long ZMQ_SNDBUF 选项。预设为 0.
sendTimeOut int ZMQ_SNDTIMEO 选项。默认为-1.
sndHwm long ZMQ_SNDHWM 选项。预设为 1000.
tcpKeepAlive int ZMQ_TCP_KEEPALIVE 选项。默认为-1.
tcpKeepAliveCount long ZMQ_TCP_KEEPALIVE_CNT 选项。默认为-1.
tcpKeepAliveIdle long ZMQ_TCP_KEEPALIVE_IDLE 选项。默认为-1.
tcpKeepAliveInterval long ZMQ_TCP_KEEPALIVE_INTVL 选项。默认为-1.
xpubVerbose boolean ZMQ_XPUB_VERBOSE 选项。默认为 false。
首页