我正在使用spring集成来从代理移动消息。
我在xml文件中定义了几个通道,以便将来自RabbitMQ X中队列的消息传输到RabbitMQ Y中的另一个队列。
遵循一个频道的配置:
<beans
xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:int-amqp="http://www.springframework.org/schema/integration/amqp"
xmlns:int="http://www.springframework.org/schema/integration"
xmlns:rabbit="http://www.springframework.org/schema/rabbit"
xmlns:util="http://www.springframework.org/schema/util"
xsi:schemaLocation="http://www.springframework.org/schema/integration/amqp http://www.springframework.org/schema/integration/amqp/spring-integration-amqp-4.3.xsd
http://www.springframework.org/schema/integration http://www.springframework.org/schema/integration/spring-integration-4.3.xsd
http://www.springframework.org/schema/rabbit http://www.springframework.org/schema/rabbit/spring-rabbit-1.7.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.3.xsd">
<int:logging-channel-adapter id="myChannelLog" level="warn" logger-name="catLogChannel1" />
<int:channel id="myChannel" >
<int:interceptors>
<int:wire-tap channel="myChannelLog" />
</int:interceptors>
</int:channel>
<rabbit:connection-factory id="connectionFactory" username="guest" password="guest" addresses="XX.XX.XX.XX:5672" cache-mode="CONNECTION" connection-cache-size="50" virtual-host="/"/>
<int-amqp:inbound-channel-adapter id="inboundChannelAdapter1" channel="myChannel" queue-names="myqueue" connection-factory="connectionFactory" auto-startup="true" channel-transacted="true" />
<rabbit:connection-factory id="connectionFactoryRmqDest" username="guest1111" password="guest" addresses="YY.YY.YY.YY:5672" cache-mode="CONNECTION" connection-cache-size="50" virtual-host="/"/>
<rabbit:template id="rabbitTemplateRmqDest" connection-factory="connectionFactoryRmqDest"/>
<int-amqp:outbound-channel-adapter id="outboundChannelAdapter1" routing-key="keyMyQueue" channel="myChannel" exchange-name="direct.exchange" amqp-template="rabbitTemplateRmqDest" default-delivery-mode="PERSISTENT" />
</beans>
在此示例中,我使用了用户&#34; guest1111&#34;在出站通道适配器上模拟目标上的错误。如果我的目标borker关闭,那么我想知道哪个频道有错误重启经纪人......
我想在日志文件中写入通道上的所有错误,以隔离哪个通道有问题(每个通道都有一个日志文件)
这是我的log4j.properties
# Root logger option
log4j.rootLogger=warn, logFileError
log4j.appender.logFileError=org.apache.log4j.RollingFileAppender
log4j.appender.logFileError.File=c:/tmp/logs/logFileError.log
log4j.appender.logFileError.MaxFileSize=2MB
log4j.appender.logFileError.MaxBackupIndex=10
log4j.appender.logFileError.layout=org.apache.log4j.PatternLayout
log4j.appender.logFileError.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %M%n
# Redirect log messages to a log file
log4j.category.catLogChannel1=warn, logFileChannel1
log4j.appender.logFileChannel1=org.apache.log4j.RollingFileAppender
log4j.appender.logFileChannel1.File=c:/tmp/logs/logChannel1.log
log4j.appender.logFileChannel1.MaxFileSize=2MB
log4j.appender.logFileChannel1.MaxBackupIndex=10
log4j.appender.logFileChannel1.layout=org.apache.log4j.PatternLayout
log4j.appender.logFileChannel1.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %M%n
# Redirect log messages to a log file
log4j.category.catLogChannel2=warn, logFileChannel2
log4j.appender.logFileChannel2=org.apache.log4j.RollingFileAppender
log4j.appender.logFileChannel2.File=c:/tmp/logs/logChannel2.log
log4j.appender.logFileChannel2.MaxFileSize=2MB
log4j.appender.logFileChannel2.MaxBackupIndex=10
log4j.appender.logFileChannel2.layout=org.apache.log4j.PatternLayout
log4j.appender.logFileChannel2.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %M%n
通过这种配置,我有:
堆栈跟踪在logFileError.log =&gt;中进行行
2018-01-04 15:06:21 WARN catLogChannel1:197 - handleMessageInternal
2018-01-04 15:06:21 WARN ConditionalRejectingErrorHandler:73 - handleError
org.springframework.amqp.rabbit.listener.exception.ListenerExecutionFailedException: Listener threw exception
at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.wrapToListenerExecutionFailedExceptionIfNeeded(AbstractMessageListenerContainer.java:941)
at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.doInvokeListener(AbstractMessageListenerContainer.java:851)
at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.invokeListener(AbstractMessageListenerContainer.java:771)
at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer.access$001(SimpleMessageListenerContainer.java:102)
at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer$1.invokeListener(SimpleMessageListenerContainer.java:198)
at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer.invokeListener(SimpleMessageListenerContainer.java:1311)
at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.executeListener(AbstractMessageListenerContainer.java:752)
at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer.doReceiveAndExecute(SimpleMessageListenerContainer.java:1254)
at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer.receiveAndExecute(SimpleMessageListenerContainer.java:1224)
at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer.access$1600(SimpleMessageListenerContainer.java:102)
at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer$AsyncMessageProcessingConsumer.run(SimpleMessageListenerContainer.java:1470)
at java.lang.Thread.run(Thread.java:745)
Caused by: org.springframework.messaging.MessageHandlingException: error occurred in message handler [org.springframework.integration.amqp.outbound.AmqpOutboundEndpoint#0]; nested exception is org.springframework.amqp.AmqpAuthenticationException: com.rabbitmq.client.AuthenticationFailureException: ACCESS_REFUSED - Login was refused using authentication mechanism PLAIN. For details see the broker logfile., failedMessage=GenericMessage [payload=byte[9], headers={amqp_receivedDeliveryMode=NON_PERSISTENT, amqp_receivedRoutingKey=myqueue, amqp_deliveryTag=1, amqp_consumerQueue=myqueue, amqp_redelivered=false, id=c08e2912-ebfe-c7c7-555a-de12694ae9a3, amqp_consumerTag=amq.ctag-33csWFlgiMh7YB8Bud-3Og, timestamp=1515074781652}]
at org.springframework.integration.handler.AbstractMessageHandler.handleMessage(AbstractMessageHandler.java:139)
at org.springframework.integration.dispatcher.AbstractDispatcher.tryOptimizedDispatch(AbstractDispatcher.java:116)
at org.springframework.integration.dispatcher.UnicastingDispatcher.doDispatch(UnicastingDispatcher.java:148)
at org.springframework.integration.dispatcher.UnicastingDispatcher.dispatch(UnicastingDispatcher.java:121)
at org.springframework.integration.channel.AbstractSubscribableChannel.doSend(AbstractSubscribableChannel.java:89)
at org.springframework.integration.channel.AbstractMessageChannel.send(AbstractMessageChannel.java:425)
at org.springframework.integration.channel.AbstractMessageChannel.send(AbstractMessageChannel.java:375)
at org.springframework.messaging.core.GenericMessagingTemplate.doSend(GenericMessagingTemplate.java:115)
at org.springframework.messaging.core.GenericMessagingTemplate.doSend(GenericMessagingTemplate.java:45)
at org.springframework.messaging.core.AbstractMessageSendingTemplate.send(AbstractMessageSendingTemplate.java:105)
at org.springframework.integration.endpoint.MessageProducerSupport.sendMessage(MessageProducerSupport.java:188)
at org.springframework.integration.amqp.inbound.AmqpInboundChannelAdapter.access$1100(AmqpInboundChannelAdapter.java:56)
at org.springframework.integration.amqp.inbound.AmqpInboundChannelAdapter$Listener.processMessage(AmqpInboundChannelAdapter.java:246)
at org.springframework.integration.amqp.inbound.AmqpInboundChannelAdapter$Listener.onMessage(AmqpInboundChannelAdapter.java:203)
at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.doInvokeListener(AbstractMessageListenerContainer.java:848)
... 10 more
Caused by: org.springframework.amqp.AmqpAuthenticationException: com.rabbitmq.client.AuthenticationFailureException: ACCESS_REFUSED - Login was refused using authentication mechanism PLAIN. For details see the broker logfile.
at org.springframework.amqp.rabbit.support.RabbitExceptionTranslator.convertRabbitAccessException(RabbitExceptionTranslator.java:65)
at org.springframework.amqp.rabbit.connection.AbstractConnectionFactory.createBareConnection(AbstractConnectionFactory.java:368)
at org.springframework.amqp.rabbit.connection.CachingConnectionFactory.createConnection(CachingConnectionFactory.java:603)
at org.springframework.amqp.rabbit.core.RabbitTemplate.doExecute(RabbitTemplate.java:1430)
at org.springframework.amqp.rabbit.core.RabbitTemplate.execute(RabbitTemplate.java:1411)
at org.springframework.amqp.rabbit.core.RabbitTemplate.send(RabbitTemplate.java:712)
at org.springframework.integration.amqp.outbound.AmqpOutboundEndpoint.send(AmqpOutboundEndpoint.java:134)
at org.springframework.integration.amqp.outbound.AmqpOutboundEndpoint.handleRequestMessage(AmqpOutboundEndpoint.java:122)
at org.springframework.integration.handler.AbstractReplyProducingMessageHandler.handleMessageInternal(AbstractReplyProducingMessageHandler.java:109)
at org.springframework.integration.handler.AbstractMessageHandler.handleMessage(AbstractMessageHandler.java:127)
... 24 more
Caused by: com.rabbitmq.client.AuthenticationFailureException: ACCESS_REFUSED - Login was refused using authentication mechanism PLAIN. For details see the broker logfile.
at com.rabbitmq.client.impl.AMQConnection.start(AMQConnection.java:342)
at com.rabbitmq.client.ConnectionFactory.newConnection(ConnectionFactory.java:909)
at com.rabbitmq.client.ConnectionFactory.newConnection(ConnectionFactory.java:859)
at com.rabbitmq.client.ConnectionFactory.newConnection(ConnectionFactory.java:799)
at org.springframework.amqp.rabbit.connection.AbstractConnectionFactory.createBareConnection(AbstractConnectionFactory.java:352)
... 32 more
2018-01-04 15:06:21 WARN catLogChannel1:197 - handleMessageInternal
2018-01-04 15:06:22 WARN ConditionalRejectingErrorHandler:73 - handleError
在我的特定日志文件中,我有以下消息:
2018-01-04 15:06:21 WARN catLogChannel1:197 - handleMessageInternal
2018-01-04 15:06:21 WARN catLogChannel1:197 - handleMessageInternal
2018-01-04 15:06:22 WARN catLogChannel1:197 - handleMessageInternal
2018-01-04 15:06:22 WARN catLogChannel1:197 - handleMessageInternal
2018-01-04 15:06:22 WARN catLogChannel1:197 - handleMessageInternal
2018-01-04 15:06:22 WARN catLogChannel1:197 - handleMessageInternal
2018-01-04 15:06:22 WARN catLogChannel1:197 - handleMessageInternal
2018-01-04 15:06:23 WARN catLogChannel1:197 - handleMessageInternal
2018-01-04 15:06:23 WARN catLogChannel1:197 - handleMessageInternal
2018-01-04 15:06:23 WARN catLogChannel1:197 - handleMessageInternal
如何在我的特定日志文件中显示堆栈跟踪而不是消息&#34; handleMessageInternal&#34;?或者堆栈跟踪原因上的更明确的消息?
于10/01/2018编辑
我使用spring集成来管理两个代理之间的桥接,以便从多个队列中传输消息(本示例中为2)。这非常有效,但我在同一个xml文件中声明了两个通道如下:
<int:channel id="firstChannel" ></int:channel>
<rabbit:connection-factory id="connectionFactory" username="guest" password="guest" addresses="XX.XX.XX.XX:5672" cache-mode="CONNECTION" connection-cache-size="50" virtual-host="/"/>
<int-amqp:inbound-channel-adapter channel="firstChannel" id="inboundChannelAdapter1" queue-names="myqueue" connection-factory="connectionFactory" auto-startup="true" channel-transacted="true" error-channel="errorChannel" />
<rabbit:connection-factory id="connectionFactoryRmqDest" username="guestsss" password="guest" addresses="YY.YY.YY.YY:5672" cache-mode="CONNECTION" connection-cache-size="50" virtual-host="/"/>
<rabbit:template id="rabbitTemplateRmqDest" connection-factory="connectionFactoryRmqDest"/>
<int-amqp:outbound-channel-adapter channel="firstChannel" id="outboundChannelAdapter1" routing-key="keyMyQueue" exchange-name="direct.exchange" amqp-template="rabbitTemplateRmqDest" default-delivery-mode="PERSISTENT" return-channel="errorChannel"/>
<int:channel id="secondChannel" ></int:channel>
<rabbit:connection-factory id="connectionFactory2" username="guest" password="guest" addresses="XX.XX.XX.XX:5672" cache-mode="CONNECTION" connection-cache-size="50" virtual-host="/"/>
<int-amqp:inbound-channel-adapter channel="secondChannel" id="inboundChannelAdapter2" queue-names="myqueue2" connection-factory="connectionFactory" auto-startup="true" channel-transacted="true" error-channel="errorChannel2" />
<rabbit:connection-factory id="connectionFactoryRmqDest2" username="guest" password="guest" addresses="YY.YY.YY.YY:5672" cache-mode="CONNECTION" connection-cache-size="50" virtual-host="/"/>
<rabbit:template id="rabbitTemplateRmqDest2" connection-factory="connectionFactoryRmqDest2"/>
<int-amqp:outbound-channel-adapter channel="secondChannel" id="outboundChannelAdapter2" routing-key="keyMyQueue" exchange-name="direct.exchange" amqp-template="rabbitTemplateRmqDest2" default-delivery-mode="PERSISTENT" />
稍后我将使用线控来调试两个频道上的消息,每个频道的消息都记录在一个单独的日志文件中。
首先,我想在单独的日志文件中记录通道的问题。
如何捕获每个频道抛出的异常?如果出站通道发生错误(错误的auth,队列已删除....)或通道上的入站&#34; secondChannel&#34;我想跟踪专用于特定频道的日志中的错误(secondChannel.log)?
对于这个样本,我希望:
- firstChannel.log
- secondChannel.log
......
这个功能可以吗?
答案 0 :(得分:0)
你的问题不是很清楚;最好显示整个日志消息,而不是像那样截断它。
如果您只想记录原因,请使用expression="payload.cause"
代替log-full-message="false"
。
修改强>
这正是我所期待的......
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:int="http://www.springframework.org/schema/integration"
xmlns:int-amqp="http://www.springframework.org/schema/integration/amqp"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/integration http://www.springframework.org/schema/integration/spring-integration.xsd
http://www.springframework.org/schema/integration/amqp http://www.springframework.org/schema/integration/amqp/spring-integration-amqp.xsd">
<int-amqp:inbound-channel-adapter channel="one" error-channel="error1" queue-names="one" />
<int:service-activator input-channel="one" expression="1 / 0" />
<int:channel id="error1" />
<int:logging-channel-adapter channel="error1" logger-name="log1" />
<int-amqp:inbound-channel-adapter channel="two" error-channel="error2" queue-names="two" />
<int:service-activator input-channel="two" expression="1 / 0" />
<int:channel id="error2" />
<int:logging-channel-adapter channel="error2" logger-name="log2" />
</beans>
频道one
上的错误转到log1
,two
上的错误转到log2
。
testLog1.log:
09:52:47.900 [(inner bean)#b7838a9-1] INFO log1 - org.springframework.messaging.MessageHandlingException: Expression evaluation failed: 1 / 0; nested exception is java.lang.ArithmeticException: / by zero, failedMessage=GenericMessage [payload=byte[6], headers={amqp_receivedDeliveryMode=NON_PERSISTENT, amqp_receivedRoutingKey=one, amqp_deliveryTag=1, amqp_consumerQueue=one, amqp_redelivered=false, id=b659ac0e-0d7f-63d6-4081-331d4d9df423, amqp_consumerTag=amq.ctag-CWkI-XVj4vKupHWSGjWtgA, timestamp=1516287167896}]
...
Caused by: java.lang.ArithmeticException: / by zero
和testLog2.log中的相同内容
此测试使用了logback,但日志框架没有任何区别。
<configuration>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<!-- encoders are assigned the type
ch.qos.logback.classic.encoder.PatternLayoutEncoder by default -->
<encoder>
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
</encoder>
</appender>
<appender name="FILE1" class="ch.qos.logback.core.FileAppender">
<file>testFile1.log</file>
<append>true</append>
<encoder>
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
</encoder>
</appender>
<appender name="FILE2" class="ch.qos.logback.core.FileAppender">
<file>testFile2.log</file>
<append>true</append>
<encoder>
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
</encoder>
</appender>
<root level="warn">
<appender-ref ref="STDOUT" />
</root>
<logger name="org.springframework" level="WARN" />
<logger name="org.springframework.integration" level="ERROR" />
<logger name="org.springframework.amqp" level="WARN" />
<logger name="log1" level="INFO">
<appender-ref ref="FILE1" />
</logger>
<logger name="log2" level="INFO">
<appender-ref ref="FILE2" />
</logger>
</configuration>
如果这不是您想要做的,我建议您开始一个更清晰的新问题,以及展示您要解决的问题的完整工作示例。