请使用 Spring AMQP 4.0.2(最新稳定版本)!spring-doc.cadn.net.cn

日志子系统 AMQP Appender

该框架为一些流行的日志子系统提供了日志追加器:spring-doc.cadn.net.cn

Appender 是通过使用日志子系统中可用的常规机制进行配置的,有关其可用属性请参见以下各节。spring-doc.cadn.net.cn

常用属性

以下属性适用于所有追加器:spring-doc.cadn.net.cn

<p>表 1. 常用附加器属性</p>
属性 默认 描述
 exchangeName
 logs

要发布日志事件的交易所名称。spring-doc.cadn.net.cn

 exchangeType
 topic

要发布日志事件的交换类型——仅当记录器声明了交换时才需要。请参见 declareExchangespring-doc.cadn.net.cn

 routingKeyPattern
 %c.%p

日志子系统模式格式,用于生成路由键。spring-doc.cadn.net.cn

 applicationId

应用 ID —— 如果模式包含 %X{applicationId},则添加到路由键中。spring-doc.cadn.net.cn

 senderPoolSize
 2

用于发布日志事件的线程数量。spring-doc.cadn.net.cn

 maxSenderRetries
 30

当 broker 不可用或其他错误发生时,消息发送应尝试发送多少次? 重试方式如下:N ^ log(N),其中 N 是重试次数。spring-doc.cadn.net.cn

 addresses

以逗号分隔的经纪人地址列表,格式如下:host:port[,host:port]* 会覆盖 hostportspring-doc.cadn.net.cn

 host
 localhost

RabbitMQ 主机,用于连接。spring-doc.cadn.net.cn

 port
 5672

RabbitMQ 连接端口。spring-doc.cadn.net.cn

 virtualHost
 /

RabbitMQ 虚拟主机,用于连接。spring-doc.cadn.net.cn

 username
 guest

RabbitMQ 用户,用于连接时使用。spring-doc.cadn.net.cn

 password
 guest

RabbitMQ 用户密码。spring-doc.cadn.net.cn

 useSsl
 false

是否为 RabbitMQ 连接使用 SSL。
参见 RabbitConnectionFactoryBean 和 配置 SSLspring-doc.cadn.net.cn

 verifyHostname
 true

为 TLS 连接启用服务器主机名验证。请参阅 RabbitConnectionFactoryBean 和 配置 SSLspring-doc.cadn.net.cn

 sslAlgorithm
 null

要使用的SSL算法。spring-doc.cadn.net.cn

 sslPropertiesLocation
 null

SSL 属性文件的位置。spring-doc.cadn.net.cn

 keyStore
 null

密钥库的位置。spring-doc.cadn.net.cn

 keyStorePassphrase
 null

密钥库的密码。spring-doc.cadn.net.cn

 keyStoreType
 JKS

密钥库类型。spring-doc.cadn.net.cn

 trustStore
 null

信任库的位置。spring-doc.cadn.net.cn

 trustStorePassphrase
 null

信任库的密码。spring-doc.cadn.net.cn

 trustStoreType
 JKS

信任库类型。spring-doc.cadn.net.cn

 saslConfig
 null (RabbitMQ client default applies)

The saslConfig - see the javadoc for RabbitUtils.stringToSaslConfig for valid values.spring-doc.cadn.net.cn

 contentType
 text/plain

content-type 日志消息的属性。spring-doc.cadn.net.cn

 contentEncoding

content-encoding 日志消息的属性。spring-doc.cadn.net.cn

 declareExchange
 false

在该追加器启动时,是否声明已配置的交换机。
参见 durableautoDeletespring-doc.cadn.net.cn

 durable
 true

declareExchangetrue 时,持久标志被设置为此值。spring-doc.cadn.net.cn

 autoDelete
 false

declareExchangetrue 时,自动删除标志被设置为此值。spring-doc.cadn.net.cn

 charset
 null

在将 String 转换为 byte[] 时所使用的字符集。
默认值:null(使用系统默认字符集)。
如果当前平台不支持该字符集,则回退使用系统字符集。spring-doc.cadn.net.cn

 deliveryMode
 PERSISTENT

PERSISTENTNON_PERSISTENT 用于确定 RabbitMQ 是否应持久化消息。spring-doc.cadn.net.cn

 generateId
 false

用于确定 messageId 属性是否被设置为唯一值。spring-doc.cadn.net.cn

 clientConnectionProperties
 null

A comma-delimited list of key:value pairs for custom client properties to the RabbitMQ connection.spring-doc.cadn.net.cn

 addMdcAsHeaders
 true

MDC 属性始终被添加到 RabbitMQ 消息头中,直到引入此属性为止。这可能导致大 MDC 时出现问题,因为 RabbitMQ 对所有消息头的缓冲区大小有限,且该缓冲区相当小。此属性的引入旨在避免在 MDC 较大时出现此类问题。默认情况下,为保持向后兼容性,该值设置为 truefalse 表示禁用将 MDC 序列化到消息头中。
请注意,JsonLayout 默认将 MDC 添加到消息中。spring-doc.cadn.net.cn

Log4j 2 Appender

以下示例展示了如何配置 Log4j 2 记录器:spring-doc.cadn.net.cn

<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 进行异步发布,则由于跨线程通信(cross-talk)导致事件极有可能被损坏。spring-doc.cadn.net.cn

Logback Appender

以下示例展示了如何配置 logback 追加器:spring-doc.cadn.net.cn

<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 来配置附加器,以包含调用者数据。spring-doc.cadn.net.cn

从版本 2.0.0 开始,Logback AmqpAppender 支持带有 Logback 编码器encoder 选项。 encoderlayout 选项相互排斥。spring-doc.cadn.net.cn

自定义消息

默认情况下,AMQP Appender 会填充以下消息属性:spring-doc.cadn.net.cn

此外,它们还会在请求头中填充以下值:spring-doc.cadn.net.cn

每个追加器都可以被子类化,从而允许您在发布前修改消息。以下示例展示了如何自定义日志消息:spring-doc.cadn.net.cn

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.Builderspring-doc.cadn.net.cn

@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);
		}
	}

}

自定义客户端属性

您可以通过添加字符串属性或更复杂的属性来添加自定义客户端属性。spring-doc.cadn.net.cn

简单字符串属性

每个追加器都支持向RabbitMQ连接添加客户端属性。spring-doc.cadn.net.cn

<font face="黑体"> 本示例演示如何为logback添加自定义客户端属性:</font>spring-doc.cadn.net.cn

<appender name="AMQP" ...>
    ...
    <clientConnectionProperties>thing1:thing2,cat:hat</clientConnectionProperties>
    ...
</appender>
Log4j2
<Appenders>
    ...
    <RabbitMQ name="rabbitmq"
        ...
        clientConnectionProperties="thing1:thing2,cat:hat"
        ...
    </RabbitMQ>
</Appenders>

属性是用逗号分隔的键值对列表。spring-doc.cadn.net.cn

spring-doc.cadn.net.cn

密钥和值不能包含逗号或冒号。spring-doc.cadn.net.cn

spring-doc.cadn.net.cn

(这些属性在查看连接时出现在RabbitMQ管理UI上。)spring-doc.cadn.net.cn

用于Logback的高级技术

你可继承Logback的appender。 这样可以在连接建立前修改客户端连接属性。 下面展示了如何操作:spring-doc.cadn.net.cn

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>spring-doc.cadn.net.cn

对于前面示例中所示的String属性,可以使用前面的技术。spring-doc.cadn.net.cn

spring-doc.cadn.net.cn

子类允许添加更丰富的属性(例如,添加Map或数值属性)。spring-doc.cadn.net.cn

spring-doc.cadn.net.cn

提供自定义队列实现

AmqpAppenders 使用 BlockingQueue 异步地将日志事件发布到 RabbitMQ。 默认情况下,使用 LinkedBlockingQueue。 不过,你可以提供任何类型的自定义 BlockingQueue 实现。spring-doc.cadn.net.cn

此示例展示了如何为Logback执行此操作:spring-doc.cadn.net.cn

public class MyEnhancedAppender extends AmqpAppender {

    @Override
    protected BlockingQueue<Event> createEventQueue() {
        return new ArrayBlockingQueue();
    }

}

Log4j 2 appender支持使用BlockingQueueFactory,如下面的例子所示:spring-doc.cadn.net.cn

<Appenders>
    ...
    <RabbitMQ name="rabbitmq"
              bufferSize="10" ... >
        <ArrayBlockingQueue/>
    </RabbitMQ>
</Appenders>