|
请使用 Spring AMQP 4.0.2(最新稳定版本)! |
日志子系统 AMQP Appender
该框架为一些流行的日志子系统提供了日志追加器:
-
logback(自 Spring AMQP 版本 1.4 起)
-
log4j2(自 Spring AMQP 1.6 版本起)
Appender 是通过使用日志子系统中可用的常规机制进行配置的,有关其可用属性请参见以下各节。
常用属性
以下属性适用于所有追加器:
| 属性 | 默认 | 描述 |
|---|---|---|
exchangeName |
logs |
要发布日志事件的交易所名称。 |
exchangeType |
topic |
要发布日志事件的交换类型——仅当记录器声明了交换时才需要。请参见 |
routingKeyPattern |
%c.%p |
日志子系统模式格式,用于生成路由键。 |
applicationId |
应用 ID —— 如果模式包含 |
|
senderPoolSize |
2 |
用于发布日志事件的线程数量。 |
maxSenderRetries |
30 |
当 broker 不可用或其他错误发生时,消息发送应尝试发送多少次?
重试方式如下: |
addresses |
以逗号分隔的经纪人地址列表,格式如下: |
|
host |
localhost |
RabbitMQ 主机,用于连接。 |
port |
5672 |
RabbitMQ 连接端口。 |
virtualHost |
/ |
RabbitMQ 虚拟主机,用于连接。 |
username |
guest |
RabbitMQ 用户,用于连接时使用。 |
password |
guest |
RabbitMQ 用户密码。 |
useSsl |
false |
是否为 RabbitMQ 连接使用 SSL。 |
verifyHostname |
true |
为 TLS 连接启用服务器主机名验证。请参阅 |
sslAlgorithm |
null |
要使用的SSL算法。 |
sslPropertiesLocation |
null |
SSL 属性文件的位置。 |
keyStore |
null |
密钥库的位置。 |
keyStorePassphrase |
null |
密钥库的密码。 |
keyStoreType |
JKS |
密钥库类型。 |
trustStore |
null |
信任库的位置。 |
trustStorePassphrase |
null |
信任库的密码。 |
trustStoreType |
JKS |
信任库类型。 |
saslConfig |
null (RabbitMQ client default applies) |
The |
contentType |
text/plain |
|
contentEncoding |
|
|
declareExchange |
false |
在该追加器启动时,是否声明已配置的交换机。 |
durable |
true |
当 |
autoDelete |
false |
当 |
charset |
null |
在将 |
deliveryMode |
PERSISTENT |
|
generateId |
false |
用于确定 |
clientConnectionProperties |
null |
A comma-delimited list of |
addMdcAsHeaders |
true |
MDC 属性始终被添加到 RabbitMQ 消息头中,直到引入此属性为止。这可能导致大 MDC 时出现问题,因为 RabbitMQ 对所有消息头的缓冲区大小有限,且该缓冲区相当小。此属性的引入旨在避免在 MDC 较大时出现此类问题。默认情况下,为保持向后兼容性,该值设置为 |
Log4j 2 Appender
以下示例展示了如何配置 Log4j 2 记录器:
<Appenders>
...
<RabbitMQ name="rabbitmq"
addresses="foo:5672,bar:5672" user="guest" password="guest" virtualHost="/"
exchange="log4j2" exchangeType="topic" declareExchange="true" durable="true" autoDelete="false"
applicationId="myAppId" routingKeyPattern="%X{applicationId}.%c.%p"
contentType="text/plain" contentEncoding="UTF-8" generateId="true" deliveryMode="NON_PERSISTENT"
charset="UTF-8"
senderPoolSize="3" maxSenderRetries="5"
addMdcAsHeaders="false">
</RabbitMQ>
</Appenders>
|
从版本 1.6.10 和 1.7.3 开始,默认情况下,log4j2 过滤器将消息发布到 RabbitMQ 的线程为调用线程。这是因为 Log4j 2 默认不创建线程安全的事件。如果代理服务器不可用,将使用 |
Logback Appender
以下示例展示了如何配置 logback 追加器:
<appender name="AMQP" class="org.springframework.amqp.rabbit.logback.AmqpAppender">
<layout>
<pattern><![CDATA[ %d %p %t [%c] - <%m>%n ]]></pattern>
</layout>
<addresses>foo:5672,bar:5672</addresses>
<abbreviation>36</abbreviation>
<includeCallerData>false</includeCallerData>
<applicationId>myApplication</applicationId>
<routingKeyPattern>%property{applicationId}.%c.%p</routingKeyPattern>
<generateId>true</generateId>
<charset>UTF-8</charset>
<durable>false</durable>
<deliveryMode>NON_PERSISTENT</deliveryMode>
<declareExchange>true</declareExchange>
<addMdcAsHeaders>false</addMdcAsHeaders>
</appender>
从版本 1.7.1 开始,Logback AmqpAppender 提供了一个 includeCallerData 选项,默认情况下为 false。提取调用者数据可能相当耗时,因为日志事件必须创建一个异常对象并检查它以确定调用位置。因此,默认情况下,当事件被添加到事件队列时,不会提取与该事件关联的调用者数据。您可以通过将 includeCallerData 属性设置为 true 来配置附加器,以包含调用者数据。
从版本 2.0.0 开始,Logback AmqpAppender 支持带有 Logback 编码器 的 encoder 选项。 encoder 和 layout 选项相互排斥。
自定义消息
默认情况下,AMQP Appender 会填充以下消息属性:
-
deliveryMode -
内容类型
-
contentEncoding,如果已配置 -
messageId,如果配置了generateId -
timestamp条日志事件 -
appId, 如果配置了 applicationId
此外,它们还会在请求头中填充以下值:
-
categoryName条日志事件 -
日志事件的级别
-
thread: 日志事件发生的线程名称 -
日志事件调用堆栈跟踪的位置
-
所有 MDC 属性的副本(除非将
addMdcAsHeaders设置为false)
每个追加器都可以被子类化,从而允许您在发布前修改消息。以下示例展示了如何自定义日志消息:
public class MyEnhancedAppender extends AmqpAppender {
@Override
public Message postProcessMessageBeforeSend(Message message, Event event) {
message.getMessageProperties().setHeader("foo", "bar");
return message;
}
}
从 2.2.4 版本开始,log4j2 AmqpAppender 可以通过 @PluginBuilderFactory 进行扩展,同时扩展也包括 AmqpAppender.Builder。
@Plugin(name = "MyEnhancedAppender", category = "Core", elementType = "appender", printObject = true)
public class MyEnhancedAppender extends AmqpAppender {
public MyEnhancedAppender(String name, Filter filter, Layout<? extends Serializable> layout,
boolean ignoreExceptions, AmqpManager manager, BlockingQueue<Event> eventQueue, String foo, String bar) {
super(name, filter, layout, ignoreExceptions, manager, eventQueue);
@Override
public Message postProcessMessageBeforeSend(Message message, Event event) {
message.getMessageProperties().setHeader("foo", "bar");
return message;
}
@PluginBuilderFactory
public static Builder newBuilder() {
return new Builder();
}
protected static class Builder extends AmqpAppender.Builder {
@Override
protected AmqpAppender buildInstance(String name, Filter filter, Layout<? extends Serializable> layout,
boolean ignoreExceptions, AmqpManager manager, BlockingQueue<Event> eventQueue) {
return new MyEnhancedAppender(name, filter, layout, ignoreExceptions, manager, eventQueue);
}
}
}
自定义客户端属性
您可以通过添加字符串属性或更复杂的属性来添加自定义客户端属性。
简单字符串属性
每个追加器都支持向RabbitMQ连接添加客户端属性。
<font face="黑体"> 本示例演示如何为logback添加自定义客户端属性:</font>
<appender name="AMQP" ...>
...
<clientConnectionProperties>thing1:thing2,cat:hat</clientConnectionProperties>
...
</appender>
<Appenders>
...
<RabbitMQ name="rabbitmq"
...
clientConnectionProperties="thing1:thing2,cat:hat"
...
</RabbitMQ>
</Appenders>
属性是用逗号分隔的键值对列表。
密钥和值不能包含逗号或冒号。
(这些属性在查看连接时出现在RabbitMQ管理UI上。)
用于Logback的高级技术
你可继承Logback的appender。 这样可以在连接建立前修改客户端连接属性。 下面展示了如何操作:
public class MyEnhancedAppender extends AmqpAppender {
private String thing1;
@Override
protected void updateConnectionClientProperties(Map<String, Object> clientProperties) {
clientProperties.put("thing1", this.thing1);
}
public void setThing1(String thing1) {
this.thing1 = thing1;
}
}
然后,您可以向logback.xml添加<thing1>thing2</thing1>。
对于前面示例中所示的String属性,可以使用前面的技术。
子类允许添加更丰富的属性(例如,添加Map或数值属性)。
提供自定义队列实现
该 AmqpAppenders 使用 BlockingQueue 异步地将日志事件发布到 RabbitMQ。
默认情况下,使用 LinkedBlockingQueue。
不过,你可以提供任何类型的自定义 BlockingQueue 实现。
此示例展示了如何为Logback执行此操作:
public class MyEnhancedAppender extends AmqpAppender {
@Override
protected BlockingQueue<Event> createEventQueue() {
return new ArrayBlockingQueue();
}
}
Log4j 2 appender支持使用BlockingQueueFactory,如下面的例子所示:
<Appenders>
...
<RabbitMQ name="rabbitmq"
bufferSize="10" ... >
<ArrayBlockingQueue/>
</RabbitMQ>
</Appenders>