Logging Subsystem AMQP Appenders
该框架为一些流行的日志子系统提供日志记录追加程序:
-
logback(自 Spring AMQP 的 1.4 版本起)
-
log4j2(自 Spring AMQP 1.6 版起)
可以通过使用日志子系统的正常机制来配置追加程序,可用的属性在以下章节中指定。
Common properties
所有追加程序都提供以下属性:
Property | Default | Description |
---|---|---|
exchangeName |
logs |
要发布日志事件的兑换名称。 |
exchangeType |
topic |
将日志事件发布到的交换机类型 - 仅在追加器声明交换机时需要。请参见`declareExchange`。 |
routingKeyPattern |
%c.%p |
用于生成路由密钥的日志子系统模式格式。 |
applicationId |
应用程序 ID - 如果模式包含 |
|
senderPoolSize |
2 |
用于发布日志事件的线程数。 |
maxSenderRetries |
30 |
如果代理不可用或出现其他错误,重试发送消息的次数。重试按照以下方式延迟: |
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 |
Location of the keystore. |
keyStorePassphrase |
null |
Passphrase for the keystore. |
keyStoreType |
JKS |
The keystore type. |
trustStore |
null |
Location of the truststore. |
trustStorePassphrase |
null |
Passphrase for the truststore. |
trustStoreType |
JKS |
The truststore type. |
saslConfig |
null(应用 RabbitMQ 客户端默认设置) |
|
contentType |
text/plain |
日志消息的 |
contentEncoding |
日志消息的 |
|
declareExchange |
false |
在该追加器启动后,是否声明配置的 exchange。请另见 |
durable |
true |
当 |
autoDelete |
false |
当 |
charset |
null |
将 `String`转换为 `byte[]`时使用的字符集。默认值:null(使用系统默认字符集)。如果当前平台不支持此字符集,我们将回退到使用系统字符集。 |
deliveryMode |
PERSISTENT |
|
generateId |
false |
用于确定 |
clientConnectionProperties |
null |
以逗号分隔的 |
addMdcAsHeaders |
true |
直到引入这个属性,MDC 属性始终被添加到 RabbitMQ 消息头中。由于 RabbitMQ 为所有标头限制了缓冲区大小,并且该缓冲区非常小,这可能导致较大的 MDC 出现问题。引入这个属性是为了避免在大型 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 默认情况下不创建线程安全的事件。如果代理已关闭,maxSenderRetries
用于重试,在重试之间没有延迟。如果您希望恢复在单独线程 (senderPoolSize
) 上发布消息的以前行为,您可以将 async
属性设置为 true
。但是,您还需要将 Log4j 2 配置为使用 DefaultLogEventFactory
而不是 ReusableLogEventFactory
。一种方法是设置系统属性 -Dlog4j2.enable.threadlocals=false
。如果您在使用 ReusableLogEventFactory
进行异步发布,由于串扰,事件极有可能损坏。
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
使用 encoder
选项来支持 Logback encoders。encoder
和 layout
选项是互斥的。
Customizing the Messages
默认情况下,AMQP 追加程序填充以下消息属性:
-
deliveryMode
-
contentType
-
contentEncoding
, if configured -
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);
}
}
}
Customizing the Client Properties
您可以通过添加字符串属性或更复杂属性来添加自定义客户端属性。
Simple String Properties
每个追加程序都支持向 RabbitMQ 连接添加客户端属性。
以下示例展示了如何为 logback 添加一个自定义客户端属性:
<appender name="AMQP" ...>
...
<clientConnectionProperties>thing1:thing2,cat:hat</clientConnectionProperties>
...
</appender>
<Appenders>
...
<RabbitMQ name="rabbitmq"
...
clientConnectionProperties="thing1:thing2,cat:hat"
...
</RabbitMQ>
</Appenders>
这些属性是一个由 key:value
对组成的逗号分隔列表。键和值不能包含逗号或冒号。
在查看连接时,这些属性会显示在 RabbitMQ 管理员界面上。
Advanced Technique for Logback
您可以对 Logback 追加程序进行子类化。这样做可以让您在建立连接之前修改客户端连接属性。以下示例展示了如何执行此操作:
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;
}
}
然后,您可以将 <thing1>thing2</thing1>
添加到 logback.xml。
对于如上例所示的 String 属性,可以使用前面的技术。子类允许添加更丰富的属性(例如添加 Map
或数字属性)。
Providing a Custom Queue Implementation
AmqpAppenders
使用 BlockingQueue
异步将日志事件发布到 RabbitMQ。默认情况下,使用了 LinkedBlockingQueue
。但是,您可以提供任何类型的自定义 BlockingQueue
实现。
以下示例展示了 Logback 的使用方法:
public class MyEnhancedAppender extends AmqpAppender {
@Override
protected BlockingQueue<Event> createEventQueue() {
return new ArrayBlockingQueue();
}
}
Log4j 2 编写器支持使用 BlockingQueueFactory
,如下例所示:
<Appenders>
...
<RabbitMQ name="rabbitmq"
bufferSize="10" ... >
<ArrayBlockingQueue/>
</RabbitMQ>
</Appenders>