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 NameTypeDescription
AppenderRefString要异步调用的 Appender 的名称。可以配置多个 AppenderRef 元素。
blockingboolean如果为 true,则追加程序将 await,直到队列中有空闲插槽。如果为 false,则在队列已满的情况下将事件写入错误附加程序。默认值为 true。
shutdownTimeoutintegerAppender 在关闭时应 await 多少毫秒来刷新队列中的未完成日志事件。默认值为零,表示永远 await。
bufferSizeinteger指定可以排队的最大事件数。默认值为 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 NameDescription
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 NameTypeDescription
batchedboolean是否使用批处理语句将日志消息写入 Cassandra。默认情况下,这是错误的。
batchTypeBatchStatement.Type使用批处理写入时使用的批处理类型。默认情况下,这是 LOGGED。
bufferSizeint写入前要缓冲或批处理的日志消息数。默认情况下,不进行任何缓冲。
clusterNameString要连接的 Cassandra 集群的名称。
columnsColumnMapping[]列 Map 配置列表。每列必须指定一个列名。每列都可以具有由其完全限定的类名指定的转换类型。默认情况下,转换类型为字符串。如果配置的类型与ReadOnlyStringMap/ThreadContextMapThreadContextStack分配兼容,则该列将分别用 MDC 或 NDC 填充。如果配置的类型与 java.util.Date 分配兼容,则日志时间戳记将转换为该配置的日期类型。如果给定了 Literals 属性,则将在 INSERT 查询中按原样使用其值,而不会进行任何转义。否则,指定的布局或图案将转换为配置的类型并存储在该列中。
contactPointsSocketAddress[]要连接的 Cassandra 节点的主机和端口的列表。这些必须是有效的主机名或 IP 地址。默认情况下,如果未为主机指定端口或将其设置为 0,则将使用默认的 Cassandra 端口 9042.默认情况下,将使用 localhost:9042.
filterFilter确定事件是否应由此 Appender 处理的过滤器。通过使用 CompositeFilter,可以使用多个过滤器。
ignoreExceptionsboolean默认值为 true,导致在追加事件时遇到的异常会在内部记录下来,然后被忽略。设置为 false 时,异常将传播到调用方。当将此 Appender 封装在FailoverAppender中时,必须将其设置为 false。
keyspaceString包含将写入日志消息的表的键空间的名称。
nameStringAppender的名字。
passwordString用于连接 Cassandra 的密码(以及用户名)。
tableString要向其中写入日志消息的表的名称。
useClockForTimestampGeneratorboolean是否将配置的 org.apache.logging.log4j.core.util.Clock 用作TimestampGenerator。默认情况下,这是错误的。
usernameString用于连接到 Cassandra 的用户名。默认情况下,不使用用户名或密码。
useTlsboolean是否使用 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 NameTypeDescription
filterFilter确定事件是否应由此 Appender 处理的过滤器。通过使用 CompositeFilter,可以使用多个过滤器。
layoutLayout用于格式化 LogEvent 的 Layout。如果未提供任何布局,则将使用默认图案布局“%m%n”。
followboolean标识附加程序是否通过配置后进行的 System.setOut 或 System.setErr 兑现 System.out 或 System.err 的重新分配。请注意,在 Windows 上,follow 属性不能与 Jansi 一起使用。不能直接使用。
directboolean直接写入 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 进行了测试。
nameStringAppender的名字。
ignoreExceptionsboolean默认值为 true,导致在追加事件时遇到的异常会在内部记录下来,然后被忽略。设置为 false 时,异常将传播到调用方。当将此 Appender 封装在FailoverAppender中时,必须将其设置为 false。
targetString“ 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 NameTypeDescription
filterFilter确定事件是否应由此 Appender 处理的过滤器。通过使用 CompositeFilter,可以使用多个过滤器。
primaryString要使用的主要 Appender 的名称。
failoversString[]要使用的次要 Appender 的名称。
nameStringAppender的名字。
retryIntervalSecondsinteger重试主 Appender 前应该经过的秒数。默认值为 60.
ignoreExceptionsboolean默认值为 true,导致在追加事件时遇到的异常会在内部记录下来,然后被忽略。设置为 false 时,异常将传播到调用方。
targetString“ 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 NameTypeDescription
appendboolean如果为 true-默认值,记录将附加到文件末尾。设置为 false 时,将在写入新记录之前清除文件。
bufferedIOboolean如果为 true-默认值,则记录将被写入缓冲区,并且当缓冲区已满或(如果设置了 InstantFlush 时)记录被写入时,数据将被写入磁盘。文件锁定不能与 bufferedIO 一起使用。性能测试表明,即使启用了 InstantFlush,使用缓冲 I/O 也会显着提高性能。
bufferSizeint当 bufferedIO 为 true 时,这是缓冲区大小,默认值为 8192 字节。
createOnDemandboolean附加器按需创建文件。仅当日志事件通过所有过滤器并将其路由到此附加程序时,附加程序才创建文件。默认为 false。
filterFilter确定事件是否应由此 Appender 处理的过滤器。通过使用 CompositeFilter,可以使用多个过滤器。
fileNameString要写入的文件名。如果该文件或其任何父目录不存在,则将创建它们。
immediateFlushboolean设置为 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 支持三种操作模式。

  • 它可以充当远程 FlumeClient 端,该 Client 端通过 Avro 将 Flume 事件发送到配置了 Avro Source 的 Flume Agent。

  • 它可以充当嵌入式 Flume 代理,Flume 事件直接传递到 Flume 中进行处理。

  • 它可以将事件持久保存到本地 BerkeleyDB 数据存储中,然后将事件异步发送到 Flume,类似于嵌入式 Flume Agent,但没有大多数 Flume 依赖项。

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

FlumeAppender Parameters

Parameter NameTypeDescription
agentsAgent[]日志事件应发送到的一组代理。如果指定了多个代理,则第一个代理将成为主要代理,如果主要代理失败,则将按指定为次要代理的 Sequences 使用后续代理。每个代理定义都提供代理主机和端口。代理规范和属性是互斥的。如果两者都配置,将导致错误。
agentRetriesinteger代理失败后应重试代理的次数。当指定 type =“ persistent”时,此参数将被忽略(代理尝试一次,然后再失败)。
batchSizeinteger指定应作为批次发送的事件数。默认值为 1.此参数仅适用于 Flume Appender。
compressboolean设置为 true 时,邮件正文将使用 gzip 压缩
connectTimeoutMillisintegerFlume 将在超时之前 await 的毫秒数。
dataDirStringFlume 提前写入日志应写入的目录。仅当 Embedded 设置为 true 且使用 Agent 元素而不是 Property 元素时才有效。
filterFilter确定事件是否应由此 Appender 处理的过滤器。通过使用 CompositeFilter,可以使用多个过滤器。
eventPrefixString为了区别于 MDC 属性,在每个事件属性之前附加字符串。默认值为空字符串。
flumeEventFactoryFlumeEventFactory从 Log4j 事件生成 Flume 事件的工厂。默认工厂是 FlumeAvroAppender 本身。
layoutLayout用于格式化 LogEvent 的 Layout。如果未指定布局,则将使用 RFC5424Layout。
lockTimeoutRetriesinteger写入 Berkeley DB 时发生 LockConflictException 时重试的次数。预设值为 5.
maxDelayMillisinteger发布批处理之前 awaitbatchSize 事件的最大毫秒数。
mdcExcludesString用逗号分隔的 mdc 密钥列表,应从 FlumeEvent 中排除。这与 mdcIncludes 属性互斥。
mdcIncludesString用逗号分隔的 mdc 密钥列表,应包含在 FlumeEvent 中。在列表中未找到的 MDC 中的任何键都将被排除。此选项与 mdcExcludes 属性互斥。
mdcRequiredStringMDC 中必须存在的逗号分隔的 mdc 密钥列表。如果没有密钥,则将引发 LoggingException。
mdcPrefixString为了与事件属性区分开,应该在每个 MDC 关键字之前添加一个字符串。默认字符串是“ mdc:”。
nameStringAppender的名字。
propertiesProperty[]一个或多个用于配置 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 NameTypeDescription
nameString需要。Appender的名字。
ignoreExceptionsboolean默认值为 true,导致在追加事件时遇到的异常会在内部记录下来,然后被忽略。设置为 false 时,异常将传播到调用方。当将此 Appender 封装在FailoverAppender中时,必须将其设置为 false。
filterFilter确定事件是否应由此 Appender 处理的过滤器。通过使用 CompositeFilter,可以使用多个过滤器。
bufferSizeint如果大于 0 的整数,这将导致附加程序缓冲日志事件并在缓冲区达到此大小时刷新。
connectionSourceConnectionSource需要。应从中检索数据库连接的连接源。
tableNameString需要。要向其中插入日志事件的数据库表的名称。
columnConfigsColumnConfig[]必需(和/或 columnMappings)。有关应将事件数据日志记录的列的信息以及如何插入该数据的信息。这由多个\ 元素表示。
columnMappingsColumnMapping[]必需(和/或 columnConfigs)。列 Map 配置列表。每列必须指定一个列名。每列都可以具有由其完全限定的类名指定的转换类型。默认情况下,转换类型为字符串。如果配置的类型与ReadOnlyStringMap/ThreadContextMapThreadContextStack分配兼容,则该列将分别用 MDC 或 NDC 填充(这是数据库特定的,他们如何处理插入 Map 或 List 值)。如果配置的类型与 java.util.Date 分配兼容,则日志时间戳记将转换为该配置的日期类型。如果配置的类型与 java.sql.Clob 或 java.sql.NClob 兼容,则格式化事件将分别设置为 Clob 或 NClob(类似于传统的 ColumnConfig 插件)。如果给定了 Literals 属性,则将在 INSERT 查询中按原样使用其值,而不会进行任何转义。否则,指定的布局或图案将转换为配置的类型并存储在该列中。
immediateFailbooleanfalse设置为 true 时,日志事件将不 await 尝试重新连接,如果 JDBC 资源不可用,日志事件将立即失败。 2.11.2 的新功能
reconnectIntervalMillislong5000如果设置为大于 0 的值,则在发生错误后,JDBCDatabaseManager 将在 await 指定的毫秒数后尝试重新连接到数据库。如果重新连接失败,则将引发异常(如果将 ignoreExceptions 设置为 false,则应用程序可以捕获该异常)。 2.11.2 中的新功能。

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

DataSource Parameters

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

ConnectionFactory Parameters

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

DriverManager Parameters

Parameter NameTypeDescription
connectionStringString需要。驱动程序特定的 JDBC 连接字符串。
userNameString数据库用户名。您不能同时指定属性和用户名或密码。
passwordString数据库密码。您不能同时指定属性和用户名或密码。
driverClassNameStringJDBC 驱动程序类名称。某些旧的 JDBC 驱动程序只能通过按类名显式加载它们来发现。
propertiesProperty[]属性列表。您不能同时指定属性和用户名或密码。

  • PoolingDriver 参数(Apache Commons DBCP)*
Parameter NameTypeDescription
DriverManager parametersDriverManager parameters此连接源从 DriverManager 连接源继承所有参数。
poolNameString用于池化 JDBC 连接的池名称。默认为 example。如果要在其他地方使用池化连接,则可以使用 JDBC 连接字符串前缀 jdbc:apache:commons:dbcp:后跟池名称。例如:jdbc:apache:commons:dbcp:example。
PoolableConnectionFactoryPoolableConnectionFactory element定义一个 PoolableConnectionFactory。

  • PoolableConnectionFactory 参数(Apache Commons DBCP)*
Parameter NameTypeDescription
autoCommitOnReturnbooleanSee Apache Commons DBCP PoolableConnectionFactory。
cacheStatebooleanSee Apache Commons DBCP PoolableConnectionFactory。
ConnectionInitSqlsStringsSee Apache Commons DBCP PoolableConnectionFactory。
defaultAutoCommitbooleanSee Apache Commons DBCP PoolableConnectionFactory。
defaultCatalogStringSee Apache Commons DBCP PoolableConnectionFactory。
defaultQueryTimeoutSecondsintegerSee Apache Commons DBCP PoolableConnectionFactory。
defaultReadOnlybooleanSee Apache Commons DBCP PoolableConnectionFactory。
defaultTransactionIsolationintegerSee Apache Commons DBCP PoolableConnectionFactory。
disconnectionSqlCodesStringsSee Apache Commons DBCP PoolableConnectionFactory。
fastFailValidationbooleanSee Apache Commons DBCP PoolableConnectionFactory。
maxConnLifetimeMillislongSee Apache Commons DBCP PoolableConnectionFactory。
maxOpenPreparedStatementsintegerSee Apache Commons DBCP PoolableConnectionFactory。
poolStatementsbooleanSee Apache Commons DBCP PoolableConnectionFactory。
rollbackOnReturnbooleanSee Apache Commons DBCP PoolableConnectionFactory。
validationQueryStringSee Apache Commons DBCP PoolableConnectionFactory。
validationQueryTimeoutSecondsintegerSee Apache Commons DBCP PoolableConnectionFactory。

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

Column Parameters

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

以下是 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 与新的\ 配置元素一起使用。

  • JMS Appender 参数*
Parameter NameTypeDefaultDescription
factoryBindingNameStringRequired要在提供ConnectionFactory的上下文中找到的名称。这也可以是 ConnectionFactory 的任何子接口。
factoryNameStringRequired用来定义INITIAL_CONTEXT_FACTORY中定义的初始上下文工厂的标准类名。如果指定了没有提供者 URL 的 factoryName,将记录一条警告消息,因为这很可能会引起问题。
filterFilternull确定事件是否应由此 Appender 处理的过滤器。通过使用 CompositeFilter,可以使用多个过滤器。
layoutLayoutRequired用于格式化 LogEvent 的 Layout。从 2.9 开始新增,在以前的版本中,默认为 SerializedLayout。
nameStringRequiredAppender的名字。
passwordStringnull用于创建 JMS 连接的密码。
providerURLStringRequiredPROVIDER_URL定义使用的提供者的 URL。
destinationBindingNameStringRequired用于查找Destination的名称。这可以是 Queue 或 Topic,因此,属性名称 queueBindingName 和 topicBindingName 是别名,以保持与 Log4j 2.0 JMS 追加程序的兼容性。
securityPrincipalNameStringnullSECURITY_PRINCIPAL指定的委托人的身份名称。如果指定的 securityPrincipalName 没有 securityCredentials,则会记录一条警告消息,因为这很可能会引起问题。
securityCredentialsStringnullSECURITY_CREDENTIALS指定的主体的安全凭证。
ignoreExceptionsbooleantrue为 true 时,将在内部记录附加事件时捕获的异常,然后将其忽略。当错误异常传播到调用方时。当将此 Appender 封装在FailoverAppender中时,必须将其设置为 false。
immediateFailbooleanfalse设置为 true 时,日志事件将不 await 尝试重新连接,如果 JMS 资源不可用,则日志事件将立即失败。 2.9 中的新功能。
reconnectIntervalMillislong5000如果设置为大于 0 的值,则在发生错误后,JMSManager 将在 await 指定的毫秒数后尝试重新连接到代理。如果重新连接失败,则将引发异常(如果将 ignoreExceptions 设置为 false,则应用程序可以捕获该异常)。 2.9 中的新功能。
urlPkgPrefixesStringnull用冒号分隔的工厂类的类名称的包前缀列表,它将创建由URL_PKG_PREFIXES定义的 URL 上下文工厂。
userNameStringnull用于创建 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 NameTypeDescription
nameString需要。Appender的名字。
ignoreExceptionsboolean默认值为 true,导致在追加事件时遇到的异常会在内部记录下来,然后被忽略。设置为 false 时,异常将传播到调用方。当将此 Appender 封装在FailoverAppender中时,必须将其设置为 false。
filterFilter确定事件是否应由此 Appender 处理的过滤器。通过使用 CompositeFilter,可以使用多个过滤器。
bufferSizeint如果大于 0 的整数,这将导致附加程序缓冲日志事件并在缓冲区达到此大小时刷新。
entityClassNameString需要。具体的 LogEventWrapperEntity 实现的完全限定名称,该实现具有 JPA 注解将其 Map 到数据库表。
persistenceUnitNameString需要。应用于持久日志事件的 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 NameTypeDescription
nameStringAppender的名字。
filterFilter确定事件是否应由此 Appender 处理的过滤器。通过使用 CompositeFilter,可以使用多个过滤器。
layoutLayout用于格式化 LogEvent 的 Layout。
SslSslConfiguration包含用于 https 的 KeyStore 和 TrustStore 的配置。可选,如果未指定,则使用 Java 运行时默认值。见SSL
verifyHostnameboolean是否根据证书验证服务器主机名。仅对 https 有效。可选,默认为 true
urlstring要使用的 URL。 URL 方案必须为“ http”或“ https”。
methodstring要使用的 HTTP 方法。可选,默认为“ POST”。
connectTimeoutMillisinteger连接超时(以毫秒为单位)。可选,默认值为 0(无限超时)。
readTimeoutMillisinteger套接字读取超时(以毫秒为单位)。可选,默认值为 0(无限超时)。
headersProperty[]要使用的其他 HTTPHeaders。这些值支持lookups
ignoreExceptionsboolean默认值为 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 NameTypeDescription
topicString要使用的 Kafka 主题。需要。
keyString随每条消息一起发送给 Kafka 的密钥。可选值,默认为 null。可以包含任何Lookups)。
filterFilter确定事件是否应由此 Appender 处理的过滤器。通过使用 CompositeFilter,可以使用多个过滤器。
layoutLayout用于格式化 LogEvent 的 Layout。必需,没有默认值。自 2.9 起新增,在以前的版本\ 中为默认值。
nameStringAppender的名字。需要。
ignoreExceptionsboolean默认值为 true,导致在追加事件时遇到的异常会在内部记录下来,然后被忽略。设置为 false 时,异常将传播到调用方。当将此 Appender 封装在FailoverAppender中时,必须将其设置为 false。
syncSendboolean默认值为 true,导致发送阻塞,直到 Kafka 服务器确认记录为止。设置为 false 时,将立即发送返回消息,从而降低了 await 时间并显着提高了吞吐量。自 2.8 以来的新功能。请注意,这是新增功能,并且尚未经过广泛测试。发送给 Kafka 的任何失败都将作为错误报告给 StatusLogger,并且日志事件将被丢弃(ignoreExceptions 参数将无效)。日志事件可能会无序到达 Kafka 服务器。
propertiesProperty[]您可以在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 NameTypeDescription
appendboolean如果为 true-默认值,记录将附加到文件末尾。设置为 false 时,将在写入新记录之前清除文件。
fileNameString要写入的文件名。如果该文件或其任何父目录不存在,则将创建它们。
filtersFilter确定事件是否应由此 Appender 处理的过滤器。通过使用 CompositeFilter,可以使用多个过滤器。
immediateFlushboolean设置为 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 NameTypeDescription
nameString需要。Appender的名字。
ignoreExceptionsboolean默认值为 true,导致在追加事件时遇到的异常会在内部记录下来,然后被忽略。设置为 false 时,异常将传播到调用方。当将此 Appender 封装在FailoverAppender中时,必须将其设置为 false。
filterFilter确定事件是否应由此 Appender 处理的过滤器。通过使用 CompositeFilter,可以使用多个过滤器。
bufferSizeint如果大于 0 的整数,这将导致附加程序缓冲日志事件并在缓冲区达到此大小时刷新。
NoSqlProviderNoSQLProvider<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-mongodb2 定义与 MongoDB 驱动程序版本 2 匹配的配置元素MongoDb2

  • log4j-mongodb3 定义与 MongoDB 驱动程序版本 3 匹配的配置元素MongoDb3

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

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

适用于 MongoDB 2 的 NoSQLAppender

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

  • MongoDB2 提供程序参数*
Parameter NameTypeDescription
collectionNameString需要。要插入事件的 MongoDB 集合的名称。
writeConcernConstantField默认情况下,MongoDB 提供程序使用 com.mongodb.WriteConcern.ACKNOWLEDGED 指令插入记录。使用此可选属性可以指定 ACKNOWLEDGED 以外的常量的名称。
writeConcernConstantClassClass如果指定 writeConcernConstant,则可以使用此属性指定 com.mongodb.WriteConcern 以外的其他类来查找常量(以创建自己的自定义指令)。
factoryClassNameClass要提供与 MongoDB 数据库的连接,可以使用此属性和 factoryMethodName 来指定用于获取连接的类和静态方法。该方法必须返回 com.mongodb.DB 或 com.mongodb.MongoClient。如果数据库未通过身份验证,则还必须指定用户名和密码。如果使用工厂方法提供连接,则不得指定 databaseName,服务器或端口属性。
factoryMethodNameMethod请参阅有关属性 factoryClassName 的文档。
databaseNameString如果未指定用于提供 MongoDB 连接的 factoryClassName 和 factoryMethodName,则必须使用此属性指定 MongoDB 数据库名称。您还必须指定用户名和密码。您还可以选择指定服务器(默认为 localhost)和端口(默认为默认的 MongoDB 端口)。
serverString请参阅有关属性 databaseName 的文档。
portint请参阅有关属性 databaseName 的文档。
usernameString请参阅有关属性 databaseName 和 factoryClassName 的文档。
passwordString请参阅有关属性 databaseName 和 factoryClassName 的文档。
cappedboolean启用对capped collections的支持
collectionSizeint指定启用封顶的集合的大小(以字节为单位)。最小大小为 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 数据库。

  • MongoDB3 提供程序参数*
Parameter NameTypeDescription
collectionNameString需要。要插入事件的 MongoDB 集合的名称。
writeConcernConstantField默认情况下,MongoDB 提供程序使用 com.mongodb.WriteConcern.ACKNOWLEDGED 指令插入记录。使用此可选属性可以指定 ACKNOWLEDGED 以外的常量的名称。
writeConcernConstantClassClass如果指定 writeConcernConstant,则可以使用此属性指定 com.mongodb.WriteConcern 以外的其他类来查找常量(以创建自己的自定义指令)。
factoryClassNameClass要提供与 MongoDB 数据库的连接,可以使用此属性和 factoryMethodName 来指定用于获取连接的类和静态方法。该方法必须返回 com.mongodb.client.MongoDatabase 或 com.mongodb.MongoClient。如果 com.mongodb.client.MongoDatabase 未通过身份验证,则还必须指定用户名和密码。如果使用工厂方法提供连接,则不得指定 databaseName,服务器或端口属性。
factoryMethodNameMethod请参阅有关属性 factoryClassName 的文档。
databaseNameString如果未指定用于提供 MongoDB 连接的 factoryClassName 和 factoryMethodName,则必须使用此属性指定 MongoDB 数据库名称。您还必须指定用户名和密码。您还可以选择指定服务器(默认为 localhost)和端口(默认为默认的 MongoDB 端口)。
serverString请参阅有关属性 databaseName 的文档。
portint请参阅有关属性 databaseName 的文档。
usernameString请参阅有关属性 databaseName 和 factoryClassName 的文档。
passwordString请参阅有关属性 databaseName 和 factoryClassName 的文档。
cappedboolean启用对capped collections的支持
collectionSizeint指定启用封顶的集合的大小(以字节为单位)。最小大小为 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 数据库。

  • CouchDB 提供程序参数*
Parameter NameTypeDescription
factoryClassNameClass要提供与 CouchDB 数据库的连接,可以使用此属性和 factoryMethodName 来指定从中获取连接的类和静态方法。该方法必须返回 org.lightcouch.CouchDbClient 或 org.lightcouch.CouchDbProperties。如果使用工厂方法提供连接,则不得指定 databaseName,协议,服务器,端口,用户名或密码属性。
factoryMethodNameMethod请参阅有关属性 factoryClassName 的文档。
databaseNameString如果未指定用于提供 CouchDB 连接的 factoryClassName 和 factoryMethodName,则必须使用此属性指定 CouchDB 数据库名称。您还必须指定用户名和密码。您还可以选择指定协议(默认为 http),服务器(默认为 localhost)和端口(http 的默认值为 80,https 的默认值为 443)。
protocolString必须为“ http”或“ https”。请参阅有关属性 databaseName 的文档。
serverString请参阅有关属性 databaseName 的文档。
portint请参阅有关属性 databaseName 的文档。
usernameString请参阅有关属性 databaseName 的文档。
passwordString请参阅有关属性 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 NameTypeDescription
appendboolean如果为 true-默认值,记录将附加到文件末尾。设置为 false 时,将在写入新记录之前清除文件。
fileNameString要写入的文件名。如果该文件或其任何父目录不存在,则将创建它们。
filtersFilter确定事件是否应由此 Appender 处理的过滤器。通过使用 CompositeFilter,可以使用多个过滤器。
immediateFlushboolean设置为 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 NameTypeDescription
AppenderRefString在操纵 LogEvent 之后要调用的 Appender 的名称。可以配置多个 AppenderRef 元素。
filterFilter确定事件是否应由此 Appender 处理的过滤器。通过使用 CompositeFilter,可以使用多个过滤器。
nameStringAppender的名字。
rewritePolicyRewritePolicy将操纵 LogEvent 的 RewritePolicy。
ignoreExceptionsboolean默认值为 true,导致在追加事件时遇到的异常会在内部记录下来,然后被忽略。设置为 false 时,异常将传播到调用方。当将此 Appender 封装在FailoverAppender中时,必须将其设置为 false。

RewritePolicy

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

MapRewritePolicy

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

Parameter NameTypeDescription
modeString“添加”或“更新”
keyValuePairKeyValuePair[]键及其值的数组。

以下配置显示了一个 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 NameTypeDescription
propertiesProperty[]用于定义要添加到 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 NameTypeDescription
loggerString记录程序名称用作测试每个事件的记录程序名称的前缀。
LevelPairKeyValuePair[]键及其值的数组,每个键是一个源级别,每个值是一个目标级别。

以下配置显示了一个 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 NameTypeDescription
appendboolean如果为 true-默认值,记录将附加到文件末尾。设置为 false 时,将在写入新记录之前清除文件。
bufferedIOboolean如果为 true-默认值,则记录将被写入缓冲区,并且当缓冲区已满或(如果设置了 InstantFlush 时)记录被写入时,数据将被写入磁盘。文件锁定不能与 bufferedIO 一起使用。性能测试表明,即使启用了 InstantFlush,使用缓冲 I/O 也会显着提高性能。
bufferSizeint当 bufferedIO 为 true 时,这是缓冲区大小,默认值为 8192 字节。
createOnDemandboolean附加器按需创建文件。仅当日志事件通过所有过滤器并将其路由到此附加程序时,附加程序才创建文件。默认为 false。
filterFilter确定事件是否应由此 Appender 处理的过滤器。通过使用 CompositeFilter,可以使用多个过滤器。
fileNameString要写入的文件名。如果该文件或其任何父目录不存在,则将创建它们。
filePatternString归档日志文件的文件名的模式。模式的格式取决于所使用的 RolloverPolicy。 DefaultRolloverPolicy 将接受与SimpleDateFormat兼容的日期/时间模式和/或接受表示整数计数器的%i。该模式还支持在运行时进行插值,因此任何 Lookup(例如DateLookup)都可以包含在该模式中。
immediateFlushboolean设置为 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 NameTypeDescription
scheduleStringcron 表达式。该表达式与 Quartz 调度程序中允许的表达式相同。有关表达式的完整说明,请参见CronExpression
evaluateOnStartupboolean启动时,将根据文件的最后修改时间戳评估 cron 表达式。如果 cron 表达式指示应该在该时间和当前时间之间发生过渡,则文件将立即被过渡。
OnStartup 触发策略

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

OnStartupTriggeringPolicy Parameters

Parameter NameTypeDescription
minSizelong文件必须翻转的最小大小。大小为零将导致翻转,无论文件大小如何。默认值为 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 NameTypeDescription
intervalinteger基于日期模式中最具体的时间单位应进行翻转的频率。例如,对于一个日期模式,其中以小时为最具体的项目,并且每 4 个小时将发生 4 次翻转。预设值为 1.
modulateboolean指示是否应调整时间间隔以使下一次翻转发生在时间间隔边界上。例如,如果项目是小时,当前小时是 3 am,间隔是 4,则第一次滚动将在 4 am 发生,然后下一个滚动将在 8 am,中午,4pm 等发生。
maxRandomDelayinteger指示随机延迟过渡的最大秒数。默认情况下,该值为 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
0foo.log-所有日志记录都将转到初始文件。
1foo.logfoo-1.log在第一次翻转期间,foo.log 重命名为 foo-1.log。一个新的 foo.log 文件被创建并开始被写入。
2foo.logfoo-2.log, foo-1.log在第二次翻转期间,foo.log 重命名为 foo-2.log。一个新的 foo.log 文件被创建并开始被写入。
3foo.logfoo-3.log,foo-2.log,foo-1.log在第三次翻转期间,foo.log 重命名为 foo-3.log。一个新的 foo.log 文件被创建并开始被写入。
4foo.logfoo-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
0foo.log-所有日志记录都将转到初始文件。
1foo.logfoo-1.log在第一次翻转期间,foo.log 重命名为 foo-1.log。一个新的 foo.log 文件被创建并开始被写入。
2foo.logfoo-1.log, foo-2.log在第二次翻转期间,将 foo-1.log 重命名为 foo-2.log,并将 foo.log 重命名为 foo-1.log。一个新的 foo.log 文件被创建并开始被写入。
3foo.logfoo-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 文件被创建并开始被写入。
4foo.logfoo-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 NameTypeDescription
fileIndexString如果设置为“ max”(默认值),则索引较高的文件将比索引较小的文件更新。如果设置为“ min”,则文件重命名和计数器将遵循上述“固定窗口”策略。
mininteger计数器的最小值。预设值为 1.
maxinteger计数器的最大值。达到此值后,较旧的归档文件将在以后的转换中被删除。预设值为 7.
compressionLevelinteger将压缩级别设置为 0-9,其中 0 =无,1 =最佳速度,直到 9 =最佳压缩。仅针对 ZIP 文件实现。
tempCompressedFilePatternString压缩期间归档日志文件的文件名的模式。

DirectWrite 过渡策略

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

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

DirectWriteRolloverStrategy Parameters

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

下面是一个配置示例,该配置使用具有基于时间和大小的触发策略的 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 NameTypeDescription
basePathString需要。从此处开始扫描要删除的文件的基本路径。
maxDepthint要访问的目录的最大级别数。值为 0 表示仅访问起始文件(基本路径本身),除非安全 Management 器拒绝。 Integer.MAX_VALUE 的值指示应访问所有级别。默认值为 1,表示仅指定基目录中的文件。
followLinksboolean是否遵循符号链接。默认为 false。
testModeboolean如果为 true,则不会删除文件,而是在 INFO 级别将一条消息打印到status logger。使用它进行空运行以测试配置是否按预期工作。默认为 false。
pathSorterPathSorter一个实现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),并且必须返回包含要删除的路径的列表。

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

  • IfLastModified 条件参数*
Parameter NameTypeDescription
ageString需要。指定duration。该条件接受的文件早于指定的期限。
nestedConditionsPathCondition[]一组可选的嵌套PathConditions。如果存在任何嵌套条件,则它们都需要在删除文件之前接受该文件。仅当外部条件接受文件时(如果文件足够旧),才评估嵌套条件。

  • IfAccumulatedFileCount 条件参数*
Parameter NameTypeDescription
exceedsint需要。从中删除文件的阈值计数。
nestedConditionsPathCondition[]一组可选的嵌套PathConditions。如果存在任何嵌套条件,则它们都需要在删除文件之前接受该文件。仅当外部条件接受文件时(如果已超过阈值计数),才评估嵌套条件。

  • IfAccumulatedFileSize 条件参数*
Parameter NameTypeDescription
exceedsString需要。将从中删除文件的阈值累积文件大小。大小可以字节为单位,后缀为 KB,MB 或 GB,例如 20MB。
nestedConditionsPathCondition[]一组可选的嵌套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 NameTypeDescription
script脚本,ScriptFile 或 ScriptRefScript 元素,指定要执行的逻辑。向脚本传递了在基本路径下找到的路径列表,并且必须以 java.util.List< PathWithAttributes >的形式返回要删除的路径。另请参阅ScriptFilter文档,以获取有关如何配置 ScriptFiles 和 ScriptRefs 的示例。

Script Parameters

Parameter NameTypeDescription
basePathjava.nio.file.Path“删除”操作从其开始扫描要删除的文件的目录。可以用来相对于 pathList 中的路径。
pathListjava.util.List<PathWithAttributes>在基本路径下找到的最大指定深度的路径列表,将最先修改的文件排在最前。该脚本可以自由修改并返回此列表。
statusLoggerStatusLoggerStatusLogger 可用于在脚本执行期间记录内部事件。
configurationConfiguration拥有此 ScriptCondition 的配置。
substitutorStrSubstitutorStrSubstitutor 用于替换查找变量。
?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 NameTypeDescription
basePathString需要。从此处开始扫描文件以应用属性的基本路径。
maxDepthint要访问的目录的最大级别数。值为 0 表示仅访问起始文件(基本路径本身),除非安全 Management 器拒绝。 Integer.MAX_VALUE 的值指示应访问所有级别。默认值为 1,表示仅指定基目录中的文件。
followLinksboolean是否遵循符号链接。默认为 false。
pathConditionsPathCondition[]see DeletePathCondition
filePermissionsStringPOSIX 格式的文件属性权限在执行操作时适用。

基础文件系统应支持POSIX文件属性视图。
例如:rw -------或 rw-rw-rw-等...
fileOwnerString文件所有者,用于定义何时执行操作。
出于安全原因,更改文件的所有者可能受到限制,并且不允许操作 IOException 抛出。如果_POSIX_CHOWN_RESTRICTED对路径有效,则只有有效用户 ID 等于文件用户 ID 或具有适当特权的进程才可以更改文件的所有权。
基础文件系统应支持文件owner属性视图。
fileGroupString文件组,用于定义何时执行操作。
基础文件系统应支持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 NameTypeDescription
appendboolean如果为 true-默认值,记录将附加到文件末尾。设置为 false 时,将在写入新记录之前清除文件。
filterFilter确定事件是否应由此 Appender 处理的过滤器。通过使用 CompositeFilter,可以使用多个过滤器。
fileNameString要写入的文件名。如果该文件或其任何父目录不存在,则将创建它们。
filePatternString归档日志文件的文件名的模式。模式的格式应取决于所使用的 RolloverStrategu。 DefaultRolloverStrategy 将接受与SimpleDateFormat兼容的日期/时间模式和/或代表整数计数器的%i。整数计数器允许指定填充,例如%3i 用于将计数器空格填充到 3 位,或者(通常更有用)%03i 用于将计数器零填充到 3 位。该模式还支持在运行时进行插值,因此任何查询(例如DateLookup都可以包含在该模式中)。
immediateFlushboolean设置为 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 NameTypeDescription
FilterFilter确定事件是否应由此 Appender 处理的过滤器。通过使用 CompositeFilter,可以使用多个过滤器。
nameStringAppender的名字。
RewritePolicyRewritePolicy将操纵 LogEvent 的 RewritePolicy。
RoutesRoutes包含一个或多个 Route 声明,以标识选择 Appender 的标准。
ScriptScript当 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。

该脚本传递了以下变量:

  • RoutingAppender 路由脚本参数*
Parameter NameTypeDescription
configurationConfiguration活动配置。
staticVariablesMap此追加器实例的所有脚本调用之间共享的 Map。这是传递给 Route 脚本的同一 Map。
logEventLogEvent日志事件。

在此示例中,脚本针对每个日志事件运行,并根据名为“ 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 NameTypeDescription
nameStringAppender的名字。
fromString发件人的电子邮件地址。
replyToString以逗号分隔的回复电子邮件地址列表。
toString以逗号分隔的收件人电子邮件地址列表。
ccStringCC 电子邮件地址的逗号分隔列表。
bccString密件抄送电子邮件地址列表,以逗号分隔。
subjectString电子邮件的主题。
bufferSizeinteger要缓冲以包含在消息中的最大日志事件数。默认值为 512.
layoutLayout用于格式化 LogEvent 的 Layout。如果未提供布局,将使用HTML layout
filterFilter确定事件是否应由此 Appender 处理的过滤器。通过使用 CompositeFilter,可以使用多个过滤器。
smtpDebugboolean设置为 true 时,将在 STDOUT 上启用会话调试。默认为 false。
smtpHostString要发送到的 SMTP 主机名。此参数是必需的。
smtpPasswordString对 SMTP 服务器进行身份验证所需的密码。
smtpPortinteger要发送到的 SMTP 端口。
smtpProtocolStringSMTP 传输协议(例如“ smtps”,默认为“ smtp”)。
smtpUsernameString针对 SMTP 服务器进行身份验证所需的用户名。
ignoreExceptionsboolean默认值为 true,导致在追加事件时遇到的异常会在内部记录下来,然后被忽略。设置为 false 时,异常将传播到调用方。当将此 Appender 封装在FailoverAppender中时,必须将其设置为 false。
SSLSslConfiguration包含 KeyStore 和 TrustStore 的配置。参见SSL
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="warn" name="MyApp" packages="">
  <Appenders>
    <SMTP name="Mail" subject="Error Log" to="[email protected]" from="[email protected]"
          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 NameTypeDescription
nameStringAppender的名字。
hostString正在侦听日志事件的系统的名称或地址。此参数是必需的。如果主机名解析为多个 IP 地址,则当连接断开时,TCP 和 SSL 变体将故障转移到下一个 IP 地址。
portinteger主机上正在侦听日志事件的端口。必须指定此参数。
protocolString“ TCP”(默认),“ SSL”或“ UDP”。
SSLSslConfiguration包含 KeyStore 和 TrustStore 的配置。参见SSL
filterFilter确定事件是否应由此 Appender 处理的过滤器。通过使用 CompositeFilter,可以使用多个过滤器。
immediateFailboolean设置为 true 时,日志事件将不 await 尝试重新连接,并且如果套接字不可用,日志事件将立即失败。
immediateFlushboolean设置为 true-默认值时,每次写操作后都会进行刷新。这将确保将数据写入磁盘,但可能会影响性能。
bufferedIOboolean为 true 时-默认情况下,事件将写入缓冲区,并且在缓冲区已满或写入记录(如果设置了 InstantFlush)时,数据将写入套接字。
bufferSizeint当 bufferedIO 为 true 时,这是缓冲区大小,默认值为 8192 字节。
layoutLayout用于格式化 LogEvent 的 Layout。必需,没有默认值。从 2.9 开始新增,在以前的版本中,默认为 SerializedLayout。
reconnectionDelayMillisinteger如果设置为大于 0 的值,则在发生错误后,SocketManager 将在 await 指定的毫秒数后尝试重新连接到服务器。如果重新连接失败,则将引发异常(如果将 ignoreExceptions 设置为 false,则应用程序可以捕获该异常)。
connectTimeoutMillisinteger连接超时(以毫秒为单位)。默认值为 0(无限超时,例如 Socket.connect()方法)。
ignoreExceptionsboolean默认值为 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 配置的参数。

  • SSL 配置参数*
Parameter NameTypeDescription
protocolStringSSL(如果省略)。另请参见Standard names
KeyStoreKeyStore包含您的私钥和证书,并确定要发送到远程主机的身份验证凭据。
TrustStoreTrustStore包含远程 Transaction 对手的 CA 证书。确定是否应该信任远程身份验证凭据(以及连接)。
verifyHostNameboolean切换是否执行主机名验证。默认为 false。

KeyStore

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

密钥库配置参数

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

TrustStore

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

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

  • TrustStore 配置参数*
Parameter NameTypeDescription
locationString密钥库文件的路径。
passwordchar[]用于访问密钥库的纯文本密码。不能与 passwordEnvironmentVariable 或 passwordFile 结合使用。
passwordEnvironmentVariableString包含密码的环境变量的名称。不能与 password 或 passwordFile 结合使用。
passwordFileString存放密码的文件的路径。不能与 password 或 passwordEnvironmentVariable 结合使用。
typeString可选的 KeyStore 类型,例如 JKS,PKCS12,PKCS11,BKS,Windows-MY/Windows-ROOT,KeychainStore 等。默认值为 JKS。另请参见Standard types
trustManagerFactoryAlgorithmString可选的 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 NameTypeDescription
advertiseboolean指示是否应发布附加程序。
appNameString在 RFC 5424 syslogLogging 用作 APP-NAME 的值。
charsetString将系统日志字符串转换为字节数组时使用的字符集。字符串必须是有效的Charset。如果未指定,将使用默认系统 Charset。
connectTimeoutMillisinteger连接超时(以毫秒为单位)。默认值为 0(无限超时,例如 Socket.connect()方法)。
enterpriseNumberintegerRFC 5424中所述的 IANA 企业编号
filterFilter确定事件是否应由此 Appender 处理的过滤器。通过使用 CompositeFilter,可以使用多个过滤器。
facilityString该工具用于尝试对消息进行分类。工具选项必须设置为“ KERN”,“ USER”,“ MAIL”,“ DAEMON”,“ AUTH”,“ SYSLOG”,“ LPR”,“ NEWS”,“ UUCP”,“ CRON”,“ AUTHPRIV”,“ FTP”,“ NTP”,“ AUDIT”,“ ALERT”,“ CLOCK”,“ LOCAL0”,“ LOCAL1”,“ LOCAL2”,“ LOCAL3”,“ LOCAL4”,“ LOCAL5”,“ LOCAL6”或“ LOCAL7”。这些值可以指定为大写或小写字符。
formatString如果设置为“ RFC5424”,则将按照 RFC 5424 格式化数据。否则,将其格式化为 BSD Syslog 记录。请注意,尽管 BSD Syslog 记录必须为 1024 字节或更短,但 SyslogLayout 不会截断它们。 RFC5424Layout 也不截断记录,因为接收者必须接受最大 2048 字节的记录,并且可能接受更长的记录。
hostString正在侦听日志事件的系统的名称或地址。此参数是必需的。
idString根据 RFC 5424 进行格式化时要使用的默认结构化数据 ID。如果 LogEvent 包含 StructuredDataMessage,则将使用消息中的 ID 代替此值。
ignoreExceptionsboolean默认值为 true,导致在追加事件时遇到的异常会在内部记录下来,然后被忽略。设置为 false 时,异常将传播到调用方。当将此 Appender 封装在FailoverAppender中时,必须将其设置为 false。
immediateFailboolean设置为 true 时,日志事件将不 await 尝试重新连接,并且如果套接字不可用,日志事件将立即失败。
immediateFlushboolean设置为 true-默认值时,每次写操作后都会进行刷新。这将确保将数据写入磁盘,但可能会影响性能。
includeMDCboolean指示是否将 ThreadContextMap 中的数据包含在 RFC 5424 SyslogLogging。默认为 true。
LayoutLayout覆盖格式设置的自定义布局。
loggerFields键值对列表允许将任意 PatternLayout 模式包含在指定的 ThreadContext 字段中;没有指定默认值。要使用,请包含> LoggerFields< nested element, containing one or more > KeyValuePair< elements. Each > KeyValuePair <必须具有一个 key 属性(用于指定将在 MDC 结构化数据元素中标识字段的密钥名称)和一个 value 属性(用于指定 PatternLayout 模式)用作值。
mdcExcludesString逗号分隔的 mdc 键列表,应从 LogEvent 中排除。这与 mdcIncludes 属性互斥。此属性仅适用于 RFC 5424 syslog 记录。
mdcIncludesString用逗号分隔的 mdc 密钥列表,应包含在 FlumeEvent 中。在列表中未找到的 MDC 中的任何键都将被排除。此选项与 mdcExcludes 属性互斥。此属性仅适用于 RFC 5424 syslog 记录。
mdcRequiredStringMDC 中必须存在的逗号分隔的 mdc 密钥列表。如果没有密钥,则将引发 LoggingException。此属性仅适用于 RFC 5424 syslog 记录。
mdcPrefixString为了与事件属性区分开,应该在每个 MDC 关键字之前添加一个字符串。默认字符串是“ mdc:”。此属性仅适用于 RFC 5424 syslog 记录。
messageIdString在 RFC 5424 系统日志记录的 MSGID 字段中使用的默认值。
nameStringAppender的名字。
newLineboolean如果为 true,则会在系统日志记录的末尾添加换行符。默认为 false。
portinteger主机上正在侦听日志事件的端口。必须指定此参数。
protocolString“ TCP”或“ UDP”。此参数是必需的。
SSLSslConfiguration包含 KeyStore 和 TrustStore 的配置。参见SSL
reconnectionDelayMillisinteger如果设置为大于 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 NameTypeDescription
nameStringAppender的名字。需要。
Layoutlayout用于格式化 LogEvent 的 Layout。如果未提供任何布局,则将使用默认图案布局“%m%n”。
FiltersFilterAppender 的过滤器。
PropertiesProperty[]一个或多个属性元素,称为终结点。
ignoreExceptionsboolean如果为 true,将记录并抑制异常。如果错误,将记录错误,然后将其传递给应用程序。
affinitylongZMQ_AFFINITY 选项。预设为 0.
backloglongZMQ_BACKLOG 选项。默认为 100.
delayAttachOnConnectbooleanZMQ_DELAY_ATTACH_ON_CONNECT 选项。默认为 false。
identitybyte[]ZMQ_IDENTITY 选项。默认为无。
ipv4OnlybooleanZMQ_IPV4ONLY 选项。默认为 true。
lingerlongZMQ_LINGER 选项。默认为-1.
maxMsgSizelongZMQ_MAXMSGSIZE 选项。默认为-1.
rcvHwmlongZMQ_RCVHWM 选项。预设为 1000.
receiveBufferSizelongZMQ_RCVBUF 选项。预设为 0.
receiveTimeOutintZMQ_RCVTIMEO 选项。默认为-1.
reconnectIVLlongZMQ_RECONNECT_IVL 选项。默认为 100.
reconnectIVLMaxlongZMQ_RECONNECT_IVL_MAX 选项。预设为 0.
sendBufferSizelongZMQ_SNDBUF 选项。预设为 0.
sendTimeOutintZMQ_SNDTIMEO 选项。默认为-1.
sndHwmlongZMQ_SNDHWM 选项。预设为 1000.
tcpKeepAliveintZMQ_TCP_KEEPALIVE 选项。默认为-1.
tcpKeepAliveCountlongZMQ_TCP_KEEPALIVE_CNT 选项。默认为-1.
tcpKeepAliveIdlelongZMQ_TCP_KEEPALIVE_IDLE 选项。默认为-1.
tcpKeepAliveIntervallongZMQ_TCP_KEEPALIVE_INTVL 选项。默认为-1.
xpubVerbosebooleanZMQ_XPUB_VERBOSE 选项。默认为 false。