log4j2的Appender基础介绍

一、Appenders 概述

Appenders 负责将日志事件(LogEvents)发送到其目标位置。每个 Appender 必须实现 Appender 接口,大多数 Appender 会扩展 AbstractAppender,它增加了生命周期(Lifecycle)和可过滤(Filterable)支持。生命周期允许组件在配置完成后完成初始化,并在关闭时进行清理。可过滤性允许组件附加过滤器,在事件处理过程中对事件进行评估。

Appenders 通常只负责将事件数据写入目标位置,在大多数情况下,它们将事件的格式化责任委托给布局(layout)。一些 Appender 会包装其他 Appender,以便可以修改日志事件、处理 Appender 中的故障、基于高级过滤条件将事件路由到从属 Appender 或提供类似的功能,但不直接格式化事件以供查看。

Appenders 总是有一个名称,以便可以从日志记录器(Loggers)中引用它们。

二、各种 Appender 类型介绍

1. AsyncAppender

  • 功能:接受对其他 Appender 的引用,并在单独的线程上异步地将日志事件写入这些 Appender。注意,在写入这些 Appender 时发生的异常将对应用程序隐藏。
  • 配置参数
    • AppenderRef:要异步调用的 Appender 的名称,可以配置多个。
    • blocking:如果为 true,当队列已满时,Appender 将等待直到有空闲位置。如果为 false,当队列已满时,事件将被写入错误 Appender(如果配置了)。默认是 true
    • shutdownTimeout:在关闭时,Appender 应等待多长时间(以毫秒为单位)来刷新队列中的未完成日志事件。默认是 0,表示永远等待。
    • bufferSize:指定可以排队的最大事件数。默认是 1024。注意,当使用中断器风格的阻塞队列时,这个缓冲区大小必须是 2 的幂。
    • errorRef:如果由于 Appender 中的错误或队列已满而无法调用任何 Appender 时,要调用的 Appender 的名称。如果未指定,则错误将被忽略。
    • filter:过滤器,用于确定事件是否应由此 Appender 处理。可以使用 CompositeFilter 使用多个过滤器。
    • name:Appender 的名称。
    • ignoreExceptions:默认是 true,导致在附加事件时遇到的异常被内部记录并然后被忽略。当设置为 false 时,异常将被传播给调用者。在将此 Appender 包装在 FailoverAppender 中时,必须将此设置为 false
    • includeLocation提取位置是一个昂贵的操作(它可以使日志记录速度慢 5 - 20 倍)。为了提高性能,默认情况下,在将日志事件添加到队列时不包括位置。可以通过设置 includeLocation="true" 来更改此设置。
    • BlockingQueueFactory:此元素覆盖要使用的 BlockingQueue 的类型。
  • 系统属性:有一些系统属性可以在底层 Appender 无法跟上日志记录速率且队列已满时维持应用程序的吞吐量。例如 log4j2.AsyncQueueFullPolicy 和 log4j2.DiscardThreshold
  • 自定义阻塞队列:从 Log4j 2.7 开始,可以使用 BlockingQueueFactory 插件指定自定义的 BlockingQueue 或 TransferQueue 的实现。
  • 代码示例
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="warn" name="MyApp">
  <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>

2. CassandraAppender

扫描二维码关注公众号,回复: 17526694 查看本文章
  • 功能:将输出写入到 Apache Cassandra 数据库。必须提前配置键空间(keyspace)和表,并且该表的列在配置文件中进行映射。
  • 配置参数
    • batched:是否使用批处理语句将日志消息写入 Cassandra。默认是 false
    • batchType:使用批处理写入时的批处理类型。默认是 LOGGED
    • bufferSize:在写入之前要缓冲或批处理的日志消息数量。默认不进行缓冲。
    • clusterName:要连接的 Cassandra 集群的名称。
    • columns:列映射配置列表。每个列必须指定列名,可以指定转换类型,如果配置的类型与 ReadOnlyStringMap / ThreadContextMap 或 ThreadContextStack 兼容,则该列将分别用 MDC 或 NDC 填充。如果配置的类型与 java.util.Date 兼容,则日志时间戳将转换为该配置的日期类型。如果给出了 literal 属性,则其值将在 INSERT 查询中按原样使用,无需转义。否则,指定的布局或模式将转换为配置的类型并存储在该列中。
    • contactPoints:Cassandra 节点的主机和端口列表。这些必须是有效的主机名或 IP 地址。默认情况下,如果未为主机指定端口或设置为 0,则将使用默认的 Cassandra 端口 9042。默认使用 localhost:9042
    • filter:过滤器。
    • ignoreExceptions:默认是 true,导致在附加事件时遇到的异常被内部记录并然后被忽略。当设置为 false 时,异常将被传播给调用者。在将此 Appender 包装在 FailoverAppender 中时,必须将此设置为 false
    • keyspace:包含要写入日志消息的表的键空间的名称。
    • name:Appender 的名称。
    • password:用于连接 Cassandra 的密码(与用户名一起使用)。
    • table:要写入日志消息的表的名称。
    • useClockForTimestampGenerator:是否使用配置的 org.apache.logging.log4j.core.util.Clock 作为时间戳生成器。默认是 false
    • username:用于连接 Cassandra 的用户名。默认情况下,不使用用户名和密码。
    • useTls:是否使用 TLS/SSL 连接到 Cassandra。默认是 false
  • 代码示例
<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>

3. ConsoleAppender

  • 功能:如预期的那样,将输出写入到 System.out 或 System.err,默认目标是 System.out。必须提供布局(Layout)来格式化日志事件。
  • 配置参数
    • filter:过滤器。
    • layout:用于格式化日志事件的布局。如果未提供布局,则使用默认的模式布局 %m%n
    • follow:标识 Appender 是否在配置后通过 System.setOut 或 System.setErr 重新分配 System.out 或 System.err 时进行响应。注意,在 Windows 上使用 Jansi 时不能使用 follow 属性。不能与 direct 一起使用。
    • direct直接写入 java.io.FileDescriptor,绕过 java.lang.System.out/.err。当输出重定向到文件或其他进程时,可以提高高达 10 倍的性能。在 Windows 上使用 Jansi 时不能使用。不能与 follow 一起使用。输出将不尊重 java.lang.System.setOut()/.setErr(),并且在多线程应用程序中可能与其他输出到 java.lang.System.out/.err 的输出交织在一起。从 2.6.2 版本开始新增。请注意,这是一个新添加的功能,目前仅在 Linux 和 Windows 上的 Oracle JVM 上进行了测试
    • name:Appender 的名称。
    • ignoreExceptions:默认是 true,导致在附加事件时遇到的异常被内部记录并然后被忽略。当设置为 false 时,异常将被传播给调用者。在将此 Appender 包装在 FailoverAppender 中时,必须将此设置为 false
    • target:可以是 "SYSTEM_OUT" 或 "SYSTEM_ERR"。默认是 "SYSTEM_OUT"
  • 代码示例
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="warn" name="MyApp">
  <Appenders>
    <Console name="STDOUT" target="SYSTEM_OUT">
      <PatternLayout pattern="%m%n"/>
    </Console>
  </Appenders>
  <Loggers>
    <Root level="error">
      <AppenderRef ref="STDOUT"/>
    </Root>
  </Loggers>
</Configuration>

4. FailoverAppender

  • 功能:包装一组 Appender。如果主 Appender 失败,则将按顺序尝试辅助 Appender,直到一个成功或没有更多的辅助 Appender 可供尝试。
  • 配置参数
    • filter:过滤器。
    • primary:主 Appender 的名称。
    • failovers:辅助 Appender 的名称列表。
    • name:Appender 的名称。
    • retryIntervalSeconds:在重试主 Appender 之前应经过的秒数。默认是 60。
    • ignoreExceptions:默认是 true,导致在附加事件时遇到的异常被内部记录并然后被忽略。当设置为 false 时,异常将被传播给调用者。
    • target:可以是 "SYSTEM_OUT" 或 "SYSTEM_ERR"。默认是 "SYSTEM_ERR"
  • 代码示例
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="warn" name="MyApp">
  <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>

5. FileAppender

  • 功能:是一个 OutputStreamAppender,它将写入到在 fileName 参数中指定的文件。使用 FileManager(扩展 OutputStreamManager)来实际执行文件 I/O。虽然来自不同配置的 FileAppender 不能共享,但 FileManagers 可以在管理器可访问的情况下共享。
  • 配置参数
    • append:当为 true(默认)时,记录将追加到文件末尾。当设置为 false 时,在写入新记录之前,文件将被清空。
    • bufferedIO:当为 true(默认)时,记录将被写入缓冲区,并且当缓冲区已满或(如果 immediateFlush 设置为 true)在写入记录时,数据将被写入磁盘。性能测试表明,使用缓冲 I/O 可以显著提高性能,即使启用了立即刷新
    • bufferSize:当 bufferedIO 为 true 时,这是缓冲区大小,默认是 8192 字节。
    • createOnDemand:Appender 在需要时创建文件。只有当日志事件通过所有过滤器并被路由到此 Appender 时,Appender 才会创建文件。默认是 false
    • filter:过滤器。
    • fileName:要写入的文件的名称。如果文件或其任何父目录不存在,它们将被创建。
    • immediateFlush:当设置为 true(默认)时,每次写入后将进行刷新。这将保证数据传递给操作系统进行写入;但它不保证数据实际上被写入物理设备(如磁盘驱动器)。如果此标志设置为 false,并且日志记录活动稀疏,则数据最终到达操作系统可能会有无限期的延迟,因为它被保存在缓冲区中。这可能会导致意外的效果,例如在写入日志后,日志不会立即出现在文件的尾部输出中。对于同步日志记录器和 Appender,每次写入后刷新是有用的。异步日志记录器和 Appender 将在一批事件结束时自动刷新,即使 immediateFlush 设置为 false。这也保证了数据传递给操作系统,但更高效。
    • layout:用于格式化日志事件的布局。如果未提供布局,则使用默认的模式布局 %m%n
    • locking:当设置为 true 时,I/O 操作仅在持有文件锁时发生,允许在多个 JVM 中甚至可能在多个主机上的 FileAppender 同时写入同一文件。这将显著影响性能,因此应谨慎使用。此外,在许多系统上,文件锁是“建议性的”,这意味着其他应用程序可以在不获取锁的情况下对文件执行操作。默认值是 false
    • name:Appender 的名称。
    • ignoreExceptions:默认是 true,导致在附加事件时遇到的异常被内部记录并然后被忽略。当设置为 false 时,异常将被传播给调用者。在将此 Appender 包装在 FailoverAppender 中时,必须将此设置为 false
    • filePermissions:以 POSIX 格式指定的文件属性权限,在创建文件时应用。底层文件系统必须支持 POSIX 文件属性视图。例如:rw------- 或 rw-rw-rw- 等。
    • fileOwner:在创建文件时定义的文件所有者。更改文件所有者可能出于安全原因受到限制,并抛出 Operation not permitted IOException。只有具有有效用户 ID 等于文件的用户 ID 或具有适当权限的进程才能在 _POSIX_CHOWN_RESTRICTED 对路径生效时更改文件的所有权。底层文件系统必须支持文件所有者属性视图。
    • fileGroup:在创建文件时定义的文件组。底层文件系统必须支持 POSIX 文件属性视图。
  • 代码示例
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="warn" name="MyApp">
  <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>

6. FlumeAppender

  • 功能:这是一个在单独的 jar 中提供的可选组件。Apache Flume 是一个分布式、可靠且可用的系统,用于从许多不同的源高效地收集、聚合和移动大量日志数据到集中式数据存储。FlumeAppender 接受日志事件并将它们作为序列化的 Avro 事件发送到 Flume 代理以供消费。
  • 操作模式
    • 作为远程 Flume 客户端,通过 Avro 将 Flume 事件发送到配置有 Avro 源的 Flume 代理。
    • 作为嵌入式 Flume 代理,Flume 事件直接传递到 Flume 进行处理。
    • 将事件持久化到本地 BerkeleyDB 数据存储,然后异步地将事件发送到 Flume,类似于嵌入式 Flume 代理,但没有大多数 Flume 依赖项。
  • 配置参数
    • agents:要将日志事件发送到的代理数组。如果指定了多个代理,第一个代理将是主代理,后续代理将在主代理失败时按指定顺序用作辅助代理。每个代理定义提供代理的主机和端口。指定 agents 和 properties 是互斥的。如果两者都配置,将导致错误。
    • agentRetries:在失败到辅助代理之前,代理应重试的次数。当 type="persistent" 指定时,此参数将被忽略(代理在失败到下一个之前只尝试一次)。
    • batchSize:应作为一批发送的事件数量。默认是 1。此参数仅适用于 FlumeAppender
    • compress:当设置为 true 时,消息体将使用 gzip 压缩。
    • connectTimeoutMillis:Flume 等待连接超时的毫秒数。
    • dataDir:当 embedded 设置为 true 且使用 Agent 元素而不是 Property 元素时,Flume 预写日志应写入的目录。
    • filter:过滤器。
    • eventPrefix:要添加到每个事件属性前面的字符串,以便与 MDC 属性区分开来。默认是空字符串。
    • flumeEventFactory:从 Log4j 事件生成 Flume 事件的工厂。默认工厂是 FlumeAvroAppender 本身。
    • layout:用于格式化日志事件的布局。如果未指定布局,则使用 RFC5424Layout
    • lockTimeoutRetries:在写入 Berkeley DB 时发生 LockConflictException 时重试的次数。默认是 5。
    • maxDelayMillis:在发布批处理之前等待 batchSize 个事件的最大毫秒数。
    • mdcExcludes:以逗号分隔的 MDC 键列表,应从 FlumeEvent 中排除。这与 mdcIncludes 属性互斥。
    • mdcIncludes:以逗号分隔的 MDC 键列表,应包含在 FlumeEvent 中。MDC 中不在列表中的任何键将被排除。此选项与 mdcExcludes 属性互斥。
    • mdcRequired:以逗号分隔的 MDC 键列表,必须存在于 MDC 中。如果一个键不存在,将抛出 LoggingException
    • mdcPrefix:应添加到每个 MDC 键前面的字符串,以便与事件属性区分开来。默认字符串是 "mdc:"
    • name:Appender 的名称。
    • properties:用于配置 Flume 代理的一个或多个 Property 元素。属性必须在没有代理名称的情况下进行配置(应用程序名称用作此目的),并且不能配置源。可以使用 "sources.log4j-source.interceptors" 为源指定拦截器。允许所有其他 Flume 配置属性。同时指定 Agent 和 Property 元素将导致错误。
    • requestTimeoutMillis:Flume 等待请求超时的毫秒数。
    • ignoreExceptions:默认是 true,导致在附加事件时遇到的异常被内部记录并然后被忽略。当设置为 false 时,异常将被传播给调用者。在将此 Appender 包装在 FailoverAppender 中时,必须将此设置为 false
    • type:可以是 "Avro""Embedded" 或 "Persistent",以指示所需的 Appender 变体。
  • 代码示例
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="warn" name="MyApp">
  <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>

7. JDBCAppender

  • 功能:使用标准 JDBC 将日志事件写入关系数据库表。可以配置为使用 JNDI DataSource 或自定义工厂方法获取 JDBC 连接。
  • 配置参数
    • name:Appender 的名称,必填。
    • ignoreExceptions:默认是 true,导致在附加事件时遇到的异常被内部记录并然后被忽略。当设置为 false 时,异常将被传播给调用者。在将此 Appender 包装在 FailoverAppender 中时,必须将此设置为 false
    • filter:过滤器。
    • bufferSize:缓冲大小。
    • connectionSource:连接源。
    • tableName:表名。
    • columnConfigs:列配置。
    • columnMappings:列映射。
    • immediateFail:资源不可用时是否立即失败。
    • reconnectIntervalMillis:重试连接的时间间隔。
  • 连接源配置
    • <DataSource>:使用 JNDI。
    • <ConnectionFactory>:指向类方法对提供连接。
    • <DriverManager>:快速但无连接池的方式。否则,日志记录性能将受到极大影响
    • <PoolingDriver>:使用 Apache 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>

猜你喜欢

转载自blog.csdn.net/shumeizwb/article/details/141085715