log4j2配置详解之Appender

  |   1 评论   |   631 浏览

介绍

appender主要负责将日志事件传递到目的地。每个Appender都必须实现Appender接口。如果你想要支持生命周期、过滤器等功能,那么可以实现AbstractAppender类。

下面介绍一下有哪些appender。

AsyncAppender

异步输出日志,默认使用 java.util.concurrent.ArrayBlockingQueue 来实现的,不需要其他的外部库,这个配置在多线程的情况下需要小心,可能会出现锁竞争,如果在多线程下,可以使用Disruptor库(一个无锁的线程间通信库,而不是队列,从而产生更高的吞吐量和更低的延迟),可以使用<asyncRoot>或者<asyncLogger>来进行配置。
AsyncAppender的参数:

参数名 类型 描述
AppenderRef String 需要加入异步输出的appender,可以配置多个元素。
blocking boolean 如果是true,输出将等待直到队列中有空的slot;如果设置为false,当队列满的时候,将用error appender来输出日志,默认值为true。
shutdownTimeout integer 在关闭时,Appender应该等待多少毫秒来刷新队列中未完成的日志事件。默认值是0,意味着永远等待。
bufferSize integer 指定可以排队处理的最大事件数量。默认是1024。注意:如果使用了disruptor的BlockingQueue,那么必须设置为2的幂等。
errorRef String 指定错误输出,如果没有配置,那么会忽略错误。
filter Filter 配置拦截器,如果配置多个,可以使用 Filters标签。
name String appender的名称
ignoreExceptions boolean 默认是true,错误将被忽略,如果设置为false,异常被传递给调用者。在用FailoverAppender包装这个Appender时,必须将其设置为false。
includeLocation boolean 输出文件路径,性能会下降5-20倍,默认是关闭的。
BlockingQueueFactory BlockingQueueFactory 指定需要使用的BlockingQueue。包括:ArrayBlockingQueue、DisruptorBlockingQueue、JCToolsBlockingQueue、LinkedTransferQueue

示例:

<Async name="Async" bufferSize="262144">
  <AppenderRef ref="List"/>
  <LinkedTransferQueue/>
</Async>

CassandraAppender

输出日志到Apache Cassandra数据库。
示例:

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

表结构

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

输出日志到控制台,标签里必须配置Layout。

ConsoleAppender参数:

参数名 类型 描述
filter Filter 配置拦截器,如果配置多个,可以使用 Filters标签。
name String appender的名称
ignoreExceptions boolean            默认是true,错误将被忽略,如果设置为false,异常被传递给调用者。在用FailoverAppender包装这个Appender时,必须将其设置为false。
layout Layout 对日志事件格式化,如果没有提供布局,将使用“%m%n”的默认布局。
target String       可以使用"SYSTEM_OUT" 或者 “SYSTEM_ERR”,默认是"SYSTEM_OUT"

示例:

<Console name="STDOUT" target="SYSTEM_OUT">
  <PatternLayout pattern="%m%n"/>
</Console>

FailoverAppender

appender的包装,优先执行配置了primary的appender,如果失败,按顺序执行配置了failovers的appender,直到执行成功为止。
FailoverAppender参数:

参数名 类型 描述
filter Filter 配置拦截器,如果配置多个,可以使用 Filters标签。
name String appender的名称
ignoreExceptions boolean 默认是true,错误将被忽略,如果设置为false,异常被传递给调用者。在用FailoverAppender包装这个Appender时,必须将其设置为false。
target String 可以使用"SYSTEM_OUT" 或者 “SYSTEM_ERR”,默认是"SYSTEM_OUT"
primary String 设置为主appender
failovers String[]            设置辅助appender
retryIntervalSeconds integer 默认是60秒。多少秒之后对主appender进行重试。

示例:

<Failover name="Failover" primary="RollingFile">
  <Failovers>
	<AppenderRef ref="Console"/>
  </Failovers>
</Failover>

FileAppender

输出日志文件。实际是使用FileManager(实现OutputStreamManager)去生成文件。
FileAppender参数:

参数名 类型 描述
filter Filter 配置拦截器,如果配置多个,可以使用 Filters标签。
name String appender的名称
ignoreExceptions boolean 默认是true,错误将被忽略,如果设置为false,异常被传递给调用者。在用FailoverAppender包装这个Appender时,必须将其设置为false。
append boolean 默认为true,追加到文件后面,设置为false,新日志被写之前会清掉原来的内容。
bufferedIO boolean 默认为true,记录将被写入缓冲区,数据将在缓冲区写满时写入磁盘,如果设置了immediateFlush,则在写入记录时写入磁盘。性能测试表明,使用缓冲I/O可以显著提高性能,即使启用了immediateFlush。
bufferSize int 缓存区大小,默认为8192 字节。
createOnDemand boolean 按需创建文件,只有当日志事件通过所有过滤器并路由到这个appender时,appender才会创建文件。默认值为false。
fileName String 需要写入的文件名,如果文件或者目录不存在,那么将创建该文件或者目录。
immediateFlush boolean                默认为true,每次写入都会刷新。这将确保数据被写入磁盘,但是会影响一定的性能。异步日志记录器和appender将在一批事件结束时自动刷新,即使immediateFlush设置为false。这也保证了数据被写入磁盘,但是效率更高。
layout Layout 对日志事件格式化,如果没有提供布局,将使用“%m%n”的默认布局。
locking boolean 默认是false,设置为true,表示多个虚拟机或者多个应用去写同一个文件时,会加锁。这会影响性能。
filePermissions String 创建文件时应用POSIX格式的文件属性权限。基础文件系统应支持POSIX文件属性视图。例子:rw——或者rw-rw-rw-
fileOwner String 创建文件时定义文件所有者。
fileGroup String 创建文件时定义的文件组。

示例:

<File name="MyFile" fileName="logs/app.log">
  <PatternLayout>
	<Pattern>%d %p %c{1.} [%t] %m%n</Pattern>
  </PatternLayout>
</File>

FlumeAppender

把日志传输到Apache Flume(Flume是一种分布式的、可靠的、可用的服务,用于有效地收集、聚合和移动大量日志数据)系统里,进行日志展示。
示例:

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

JDBCAppender

使用标准JDBC将日志事件写入关系数据库表。
示例:

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

JMS Appender

发送日志到JMS服务。
示例:

<JMS name="jmsQueue" destinationBindingName="MyQueue"
         factoryBindingName="MyQueueConnectionFactory">
  <JsonLayout properties="true"/>
</JMS>

JPAAppender

使用JPA把日志输出到数据库。
示例:

<JPA name="databaseAppender" persistenceUnitName="loggingPersistenceUnit"
         entityClassName="com.example.logging.JpaLogEntity" />

HttpAppender

通过Http发送日志。
示例:

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

KafkaAppender

把日志发送到kafka里。
示例:

<Kafka name="Kafka" topic="log-test">
  <PatternLayout pattern="%date %message"/>
	<Property name="bootstrap.servers">localhost:9092</Property>
</Kafka>

MemoryMappedFileAppender

MemoryMappedFileAppender将指定文件的一部分映射到内存中,并将日志事件写到该内存中,这依赖于操作系统的虚拟内存管理器将更改同步到存储设备。使用内存可以提供I/O性能。
示例:

<MemoryMappedFile name="MyFile" fileName="logs/app.log">
  <PatternLayout>
	<Pattern>%d %p %c{1.} [%t] %m%n</Pattern>
  </PatternLayout>
</MemoryMappedFile>

NoSQLAppender

输出日志到Nosql数据库中。
示例:
集成MongoDb

<NoSql name="databaseAppender">
  <MongoDb2 databaseName="applicationDb" collectionName="applicationLog" server="mongo.example.org"
		   username="loggingUser" password="abc123" />
</NoSql>
<NoSql name="databaseAppender">
  <MongoDb3 databaseName="applicationDb" collectionName="applicationLog" server="mongo.example.org"
		   username="loggingUser" password="abc123" />
</NoSql>

集成Apache CouchDB

<NoSql name="databaseAppender">
  <CouchDb databaseName="applicationDb" protocol="https" server="couch.example.org"
		   username="loggingUser" password="abc123" />
</NoSql>

RandomAccessFileAppender

跟FileAppender类似,但是他总是被缓存。在内部他使用ByteBuffer + RandomAccessFile来代替BufferedOutputStream。性能比配置了bufferedIO的FileAppender高出20-200%。
示例:

<RandomAccessFile name="MyFile" fileName="logs/app.log">
  <PatternLayout>
	<Pattern>%d %p %c{1.} [%t] %m%n</Pattern>
  </PatternLayout>
</RandomAccessFile>

RewriteAppender

RewriteAppender允许在LogEvent被另一个Appender处理之前对其进行操作。他可以屏蔽敏感信息,如密码;或将信息注入每个事件。RewriteAppender必须配置RewritePolicy。RewriteAppender应该在任何appender引用之后配置,以允许它正确地关闭。
示例:

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

RollingFileAppender

RollingFileAppender是一个OutputStreamAppender,它写入文件名参数中指定的文件,并根据TriggeringPolicy和RolloverPolicy将文件进行切分。RollingFileAppender使用RollingFileManager(它扩展了OutputStreamManager)来实际执行文件I/O并执行切分。
示例:

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

RollingRandomAccessFileAppender

与RollingFileAppender类似,只是他总是使用缓存,内部使用ByteBuffer + RandomAccessFile来代替BufferedOutputStream。性能有很大的提升。
示例:

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

RoutingAppender

经过计算决定要使用哪个Appender。目标Appender可以是以前配置的Appender,可以通过其名称引用它,也可以根据需要动态创建Appender。
示例:

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

SMTPAppender

日志以邮件的形式进行输出,通常是对错误或者异常进行发送。示例
示例:

<SMTP name="Mail" subject="Error Log" to="errors@logging.apache.org" from="test@logging.apache.org"
	  smtpHost="localhost" smtpPort="25" bufferSize="50">
</SMTP>

SocketAppender

通过host和port来输出日志。可以通过TCP或者UDP来发送。
示例:

<Socket name="socket" host="localhost" port="9500">
  <JsonLayout properties="true"/>
</Socket>

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

SyslogAppender

跟SocketAppender类似,但是他是以BSD Syslog格式或RFC 5424格式输出。
示例:

<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"/>

ZeroMQ/JeroMQ Appender

把日志输出到JeroMQ里。
示例:

<JeroMQ name="JeroMQAppender">
  <Property name="endpoint">tcp://*:5556</Property>
  <Property name="endpoint">ipc://info-topic</Property>
</JeroMQ>

也可以关注我的公众号:程序之声

关注公众号,领取更多资源

本文为博主原创文章,未经博主允许不得转载。

评论

发表评论