14.4 配置ActiveMQ日志
14.4 Configuring ActiveMQ logging
14.4 配置ActiveMQ日志
?
So far we’ve seen how you can monitor ActiveMQ either programmatically or using
tools such as JConsole. But there’s one more way you can peek at the broker status,
and that’s through its internal logging mechanism. When you experience problems
with the broker’s behavior, the first and most common place to begin looking for a
potential cause of the problem is the data/activemq.log file. In this section you’ll
learn how you can adjust the logging to suit your needs and how it can help you in
detecting potential broker problems.
?
到目前为止,我们已经可以通过编程或者使用诸如JConsole之类的工具来监控ActiveMQ了.同样,
还有另外一种方式来监控代理状态,即使用时代理的内部日志机制.当你遇到代理问题,排查问题
原因的起点同时也是最常用到的文件就是data/activemq.log日志文件.本节中,你讲看到如何调整
日志以便符合需求并且会看到如何借用日志来侦测潜在的代理问题.
?
In this section we’ll see how we can adapt ActiveMQ logging for brokers and clients.
We’ll also introduce a logging interceptor that can be used to track messages between
brokers and clients. Let’s start with the broker-related logging discussion.
?
本节中,我们就爱那个看到如何调整ActiveMQ代理和客户端的日志.我们将介绍使用日志拦截器来
追踪代理和客户端之间的消息.下面,我们从代理相关的日志开始讨论.
?
14.4.1 Broker logging
14..4.1 代理日志
?
ActiveMQ ?uses ?the ?Apache Commons ?Logging ?API ?(http://mng.bz/xdQM) for ?its
internal logging purposes. ?So if you ?embed ActiveMQ in ?your Java application,
it’ll fit whatever ?logging mechanisms you ?already use. The ?standalone binary
distribution of ActiveMQ uses ?Apache Log4J (http://mng.bz/940F) library ?as its
logging ?facility. ?The ?ActiveMQ ?logging configuration ?can ?be ?found ?in the
conf/log4j.properties file. By default, it ?defines two log appenders: one ?that
prints to ?standard output, ?and another ?that prints ?to the ?data/activemq.log
file. The following listing shows the standard Log4J logger configuration.
?
ActiveMQ使用Apache Commons ?Logging ?API ?(http://mng.bz/xdQM)作为其内部日志工具.
因此,如果在你的Java程序中嵌入ActiveMQ,ActiveMQ可以适应你用到的任意日志机制.独立
二进制格式分发的ActiveMQ使用Log4J(http://mng.bz/940F)库作为其日志工具.ActiveMQ的
日志配置文件爱你是conf/log4j.properties.默认情况下,该配置文件中定义了两个日志
appender:一个打印到标准输出,另一个打印到data/activemq.log文件爱你.下面的代码片段
显示了标准的Log4J日志配置.
?
Listing 14.12 Default logger configuration
log4j.rootLogger=INFO, stdout, out
log4j.logger.org.apache.activemq.spring=WARN
log4j.logger.org.springframework=WARN
log4j.logger.org.apache.xbean.spring=WARN
?
As you can see in listing 14.12, by default ActiveMQ will only print messages with a log
level of INFO or above, which should be enough for you to monitor its usual behavior.
In case you detect a problem with your application and want to enable more detailed
debugging, you should change the level for the root logger to DEBUG. Just be aware
that the DEBUG logging level will output considerably more logging information, so
you’ll probably want to narrow debug messages to a particular Java package. To do
this, you should leave the root logger at the INFO level and add a line that enables
debug logging for the desired class or package. For example, to enable trace-level
logging for the TCP transport, add the following configuration to the conf/
log4j.properties file:
?
如代码清单14.12所示,默认时,ActiveMQ仅打印等级为INFO或者更高的日志,这在监控代理日常行为
时足够用了.在排查应用程序问题而需要更多调试细节信息时,你应该修改root logger的等级为DEBUG.
需要注意的是,DEBUG等级的日志将多打印出相关可观数量的信息,因此你可能需要设置特殊的Java包能
打印DEBUG信息,以便精简调试信息.我i次,你应当配置root logger的日志等级为INFO,并添加一行配置
以便为特殊的类或包启用DEBUG等级的日志.例如,
?
log4j.logger.org.apache.activemq.transport.tcp=TRACE
?
After making this change in the conf/log4j.properties file and restarting ActiveMQ,
you’ll begin to see the following log output:
?
在conf/log4j.properties文件中做了上述修改之后,重启ActiveMQ,你将看到下面的日志输出:
?
TRACE TcpTransport
- TCP consumer thread for tcp:///127.0.0.1:49383 starting
DEBUG TcpTransport
- Stopping transport tcp:///127.0.0.1:49383
TRACE TcpTransport
- TCP consumer thread for tcp:///127.0.0.1:49392 starting
DEBUG TcpTransport
- Stopping transport tcp:///127.0.0.1:49392
?
In ?addition ? to ?starting/stopping ? ActiveMQ ?after ? changing ?the ? logging
configuration, one common question is how to change the logging configuration at
runtime. This is a reasonable request, ?since you may not want to ?stop ActiveMQ
to change the logging configuration. ?Luckily, you can use the ?JMX capabilities
in ActiveMQ along with JConsole to achieve this. Just make the necessary changes
to the conf/log4j.properties file and ?save them. Then open JConsole ?and select
the ? Broker ? MBean ? as ? shown ? in ? figure ? 14.15. ? Locate ? the ? button
reloadLog4jProperties on the ?Broker MBean’s Operations ?tab. Click the ?button
named reloadLog4jProperties and the conf/log4j.properties file will be ?reloaded
and your changes will be applied. ?In addition to logging from the ?broker side,
logging is also available on the client side.
?
除了在修改日志配置文件后重启代理,一个厂家爱你的问题是如何在运行时修改日志配置文件.
这是一个很合理的要求,因为你可能不打算在修改日志配置文件后重启ActiveMQ.幸运的是,你可以
使用ActiveMQ的JMX功能通过JConsole来完成.conf/log4j.properties文件做了必要修改之后保存.
然后打开JConsole然后选择如图14.15所示的代理的MBean,从操作节点找到reloadLog4jProperties
按钮,点击该按钮后,conf/log4j.properties文件会被重新加载,该文件的修改即会生效.除了代理端
可以记录日志之外,客户端也可以记日志.
?
14.4.2 Client logging
14.4.2 客户端日志
?
Logging ?on ?the broker ?side ?is definitely ?necessary, ?but how ?do ?you debug
problems on the client side in your Java applications? The ActiveMQ Java ?client
APIs use the same logging approach as the broker, so you can use the same ?style
of Log4J configuration file in your client application as well. In this ?section
we’ll show you a few tips on how you can customize client-side logging and ?see
more ? information ?about ? what’s ?going ? on ?inside ? the ?client-to-broker
communication.
?
代理端日志无疑是很有必要的,但是在客户端你自己的Java程序中如何调试问题呢?ActiveMQ
的Java客户端API使用了和代理端一样的日志系统,因此你可以在客户端程序中使用相同风格
的Log4J配置文件.本节中,我们将展示一些自定义客户端日志方面的技巧,以便了解更多客户端
和代理通讯时的内部信息.
?
For starters, a Log4J ?configuration file must be ?made available to the ?client
-side application. The ?following listing shows ?an example Log4J ?configuration
file that will be used in this section.
?
首先,客户端程序必须要配置一个Log4J配置文件.下面代码清单是本节中使用的Log4J示例配置
文件:
?
Listing 14.13 Client logging
log4j.rootLogger=INFO, out, stdout
log4j.logger.org.apache.activemq.spring=WARN
log4j.logger.org.springframework=WARN
log4j.logger.org.apache.xbean.spring=WARN
log4j.logger.org.apache.activemq.transport.failover.FailoverTransport=DEBUG
log4j.logger.org.apache.activemq.transport.TransportLogger=DEBUG
?
As you can see, the standard INFO level is being used for the root logger. Additional
configuration has been added (marked in bold) to monitor the failover transport and
TCP communication.
?
如你所示,root logger使用了标准的INFO等级.添加的额外的配置信息用于监控失效转移协议和
TCP通信(粗体部分).
?
Now, let’s run our stock portfolio publisher example, but with some additional
properties that will allow us to use logging settings previously defined.
?
下面,让我们运行stock portfolio publisher,运行时需要一些额外属性,以便可以使用前面定义的
日志配置文件.
?
$ mvn exec:java \
-Dlog4j.configuration=file:\
src/main/resources/org/apache/activemq/book/ch14/log4j.properties \
-Dexec.mainClass=org.apache.activemq.book.ch14.advisory.Publisher \
-Dexec.args="failover:(tcp://localhost:61616?trace=true) CSCO ORCL"
?
mvn exec:java ^
-Dlog4j.configuration=file:^
src/main/resources/org/apache/activemq/book/ch14/log4j.properties ^
-Dexec.mainClass=org.apache.activemq.book.ch14.advisory.Publisher ^
-Dexec.args="failover:(tcp://localhost:61616?trace=true) CSCO ORCL"
?
The log4j.configuration system property is used to specify the location of the Log4J
configuration file. Also note that the trace parameter has been set to true via the
transport connection URI. Along with setting the TransportLogger level to DEBUG, this
will allow all the commands exchanged between the client and the broker to be easily
viewed.
?
log4j.configuration系统属性用于指定Log4J文件的位置.另外,需要注意的是,在传输连接器'
的RUI中trace参数值被设置为true了.设置TransportLogger的等级为DEBUG,使得所有客户端
和代理之间信息交互的命令都能很容易的查看到.
?
Let’s say an application is started while the broker is down. What will be seen in the
log output are messages like the following:
?
假设应用程序启动之后代理停止运行了,此时日志将会输入如下信息:
?
2009-03-19 15:47:56,699 [ublisher.main()] DEBUG FailoverTransport
- Reconnect was triggered but transport is not started yet.
Wait for start to connect the transport.
2009-03-19 15:47:56,829 [ublisher.main()] DEBUG FailoverTransport
- Started.
2009-03-19 15:47:56,829 [ublisher.main()] DEBUG FailoverTransport
- Waking up reconnect task
2009-03-19 15:47:56,830 [ActiveMQ Task ] DEBUG FailoverTransport
- Attempting connect to: tcp://localhost:61616?trace=true
2009-03-19 15:47:56,903 [ActiveMQ Task ] DEBUG FailoverTransport
- Connect fail to: tcp://localhost:61616?trace=true, reason:
java.net.ConnectException: Connection refused
2009-03-19 15:47:56,903 [ActiveMQ Task ] DEBUG FailoverTransport
- Waiting 10 ms before attempting connection.
2009-03-19 15:47:56,913 [ActiveMQ Task ] DEBUG FailoverTransport
- Attempting connect to: tcp://localhost:61616?trace=true
2009-03-19 15:47:56,914 [ActiveMQ Task ] DEBUG FailoverTransport
- Connect fail to: tcp://localhost:61616?trace=true, reason:
java.net.ConnectException: Connection refused
2009-03-19 15:47:56,915 [ActiveMQ Task ] DEBUG FailoverTransport
- Waiting 20 ms before attempting connection.
2009-03-19 15:47:56,935 [ActiveMQ Task ] DEBUG FailoverTransport
- Attempting connect to: tcp://localhost:61616?trace=true
2009-03-19 15:47:56,937 [ActiveMQ Task ] DEBUG FailoverTransport
- Connect fail to: tcp://localhost:61616?trace=true, reason:
java.net.ConnectException: Connection refused
2009-03-19 15:47:56,938 [ActiveMQ Task ] DEBUG FailoverTransport
- Waiting 40 ms before attempting connection.
?
With debug level logging enabled, the failover transport provides a detailed log
of its attempts to establish a connection with the broker. This can be extremely
helpful in ?situations where ?you experience ?connection problems ?from a client
application.
?
启用了DEBUG级别的日志后,失效转移连接器提供了其尝试建立和代理之间连接的详细日志.这
在客户端程序出现连接问题时相当有用.
?
Once a connection with the broker ?is established, the TCP transport will ?start
tracing all commands exchanged ?with the broker to ?the log. An example ?of such
traces is shown next:
?
一旦建立和和代理之间的连接,TCP传输连接器会追踪所有与代理之间交互的命令.下面是这种
追踪的示例:
?
2009-03-19 15:48:02,038 [ActiveMQ Task ] DEBUG FailoverTransport
- Waiting 5120 ms before attempting connection.
2009-03-19 15:48:07,158 [ActiveMQ Task ] DEBUG FailoverTransport
- Attempting connect to: tcp://localhost:61616?trace=true
2009-03-19 15:48:07,162 [ActiveMQ Task ] DEBUG Connection:11
- SENDING: WireFormatInfo {...}
2009-03-19 15:48:07,183 [127.0.0.1:61616] DEBUG Connection:11
- RECEIVED: WireFormatInfo { ... }
2009-03-19 15:48:07,186 [ActiveMQ Task ] DEBUG Connection:11
- SENDING: ConnectionControl { ... }
2009-03-19 15:48:07,186 [ActiveMQ Task ] DEBUG FailoverTransport
- Connection established
2009-03-19 15:48:07,187 [ActiveMQ Task ] INFO FailoverTransport
- Successfully connected to tcp://localhost:61616?trace=true
2009-03-19 15:48:07,187 [127.0.0.1:61616] DEBUG Connection:11
- RECEIVED: BrokerInfo { ... }
2009-03-19 15:48:07,189 [ublisher.main()] DEBUG Connection:11
- SENDING: ConnectionInfo { ... }
2009-03-19 15:48:07,190 [127.0.0.1:61616] DEBUG Connection:11
- RECEIVED: Response {commandId = 0, responseRequired = false,
correlationId = 1}
2009-03-19 15:48:07,203 [ublisher.main()] DEBUG Connection:11
- SENDING: ConsumerInfo { ... }
2009-03-19 15:48:07,206 [127.0.0.1:61616] DEBUG Connection:11
- RECEIVED: Response { ... }
2009-03-19 15:48:07,232 [ublisher.main()] DEBUG Connection:11
- SENDING: SessionInfo { ... }
2009-03-19 15:48:07,239 [ublisher.main()] DEBUG Connection:11
- SENDING: ProducerInfo { ... }
Sending: {offer=51.726420585933745, price=51.67474584009366,
up=false, stock=CSCO}
on destination: topic://STOCKS.CSCO
2009-03-19 15:48:07,266 [ublisher.main()] DEBUG Connection:11
- SENDING: ActiveMQMapMessage { ... }
2009-03-19 15:48:07,294 [127.0.0.1:61616] DEBUG Connection:11
- RECEIVED: Response { ... }
Sending: {offer=94.03931872048393, price=93.94537334713681,
up=false, stock=ORCL}
on destination: topic://STOCKS.ORCL
?
For the purpose of readability, some details of specific commands have been left
out except for ?one log message, ?which is marked ?bold. These traces ?provide a
full ?peek ?into ?the ?client-broker communication, ?which ?can ?help ?to narrow
application connection problems further.
?
为了便于阅读,一些命令的细节信息省略了只留下了一个日志信息,如粗体字所示.这些追踪信息
记录了客户端代理之间通信的详细细节,可以帮助定位排查应用程序和代理之间的连接问题.
?
This simple example shows that with a few minor configuration changes, many more
logging details can be viewed. But beyond standard Log4J-style logging, ActiveMQ
also provides a special logger for internal broker events.
?
这个简单的例子表明,只要做一些微小的配置调整,即可记录更多细节日志.除了标准的Log4J
风格的日志,ActiveMQ还提供了一种特殊的记录内部代理事件的日志机制.
?
14.4.3 Internal broker event logging
14.4.3 代理内部事件日志
?
The previous sections demonstrated how the ?broker side and the client side ?can
be monitored through the use of standard Log4J logging. Similar functionality is
available on ?the broker ?side for ?internal broker ?operations using ?a logging
interceptor (aka logging plug-in). ActiveMQ plug-ins were introduced in ?chapter
6 where you ?saw how they ?can be used ?to authenticate client ?applications and
authorize access to broker resources. The logging interceptor is a simple broker
plug-in that uses the broker’s internal event mechanism to log internal ?broker
events. ?The ?types ?of ?events ?that ?are ?logged ?can ?be ?controlled ?via the
configuration of the logging plug-in using the properties shown in table 14.2.
?
前面的章节中介绍了如何使用标准的Log4J日志机制监控代理端和客户端.同样,在代理段可以使用
日志拦截器(aka logging plug-in)监控代理的内部操作.第6章中介绍过使用ActiveMQ的插件机制
实现客户端认证以及对访问代理资源实现授权.日志拦截器是一中简单的代理插件运用代理内部事件
机制记录代理内部事件.
?
The logging plug-in is useful for seeing more information about the broker’s internal
events. This can be useful for debugging purposes during development as well as
for informational purposes during production deployment. It provides more finite
logging for particular event types and allows you to see more information about what
the broker’s doing.
?
使用日志插件有助于了解代理内部事件的更多信息.这在开发阶段有助于调试而在生产部署阶段有助于
了解更多信息.日志插件能针对特定的事件类型提供更多日志信息,并运行你了解更多当前代理正在进行
的操作的相关信息.
?
To install this plug-in, add the <loggingBrokerPlugin/> element to the list of your
plug-ins in the conf/activemq.xml configuration file. Here’s an example of this:
?
添加<loggingBrokerPlugin/>元素到conf/activemq.xml配置文件中的插件列表中即可安装这个日志插件.
示例代码如下所示:
...
<plugins>
<loggingBrokerPlugin/>
</plugins>
...
?
After restarting the broker, you’ll see output indicating that the logging plug-in has
been activated. After table 14.2 we see an example of such output during the broker
startup.
?
重启代理之后,从输出中可以看到日志插件已经被激活了.表14.2之后是代理启动时的输出信息:
?
Table 14.2 Logging plug-in properties
表14.2 日志插件属性
?
Property name Default value Description
属性名称默认值描述
logAll false Log all events
logAll false 为所有事件记录日志
?
logMessageEvents false Log only events related to producing, consuming,
and dispatching messages
logMessageEvents false 只为消息生产,消费和分发事件记录日志
?
logConnectionEvents true Log only events related to connections and sessions
logConnectionEvents true 只为连接和session相关的事件记录日志
?
logTransactionEvents false Log only events related to transaction handling
logTransactionEvents false 只为事务处理相关事件记录日志
?
logConsumerEvents false Log only events related to message consumption
logConsumerEvents false 只为消息处理相关事件记录日志
?
logProducerEvents false Log only events related to message production
logProducerEvents false 只为消息生产相关事件记录日志
?
logInternalEvents false Log only events related to internal broker operations
such as failover, querying internal objects, and so on
logInternalEvents false 只为代理内部操作比如,失效转移,查询内部对象等事件记录日志
?
...
Loading message broker from: xbean:activemq.xml
INFO | Created LoggingBrokerPlugin: LoggingBrokerPlugin(logAll=false,
logConnectionEvents=true, logConsumerEvents=false,
logProducerEvents=false, logMessageEvents=false,
logTransactionEvents=false, logInternalEvents=false)
...
?
Note that the logging plug-in is using the default configuration. Send some messages
to the broker, and you’ll see the following output from the broker:
注意日志插件使用了默认的配置.发送一些消息给代理后,你将看到下面的来自代理的输出消息:
...
INFO | Adding Connection :
org.apache.activemq.broker.ConnectionContext@1c45ce17
INFO | Adding Session : SessionInfo {commandId = 3, responseRequired =
false, sessionId = ID:mongoose.local-58504-1278340965484-0:0:1}
INFO | Removing Session : SessionInfo {commandId = 0, responseRequired =
false, sessionId = ID:mongoose.local-58504-1278340965484-0:0:-1}
INFO | Removing Session : SessionInfo {commandId = 3, responseRequired =
false, sessionId = ID:mongoose.local-58504-1278340965484-0:0:1}
INFO | Removing Connection : ConnectionInfo {commandId = 1,
responseRequired = true, connectionId =
ID:mongoose.local-58504-1278340965484-0:0,
clientId = ID:mongoose.local-58504-1278340965484-1:0, userName = null,
password = *****, brokerPath = null, brokerMasterConnector = false,
manageable = true, clientMaster = true}
...
?
Note that the output indicates that ?a connection and session were added ?to the
broker (a connection and a session ?were created), and a connection and ?session
were removed from ?the broker (a ?connection and session ?were destroyed). These
are events that ?are logged from ?a producer connecting ?to the broker, ?sending
some ?messages, and ?disconnecting from ?the broker. ?If you ?want to ?see more
detailed information, then you need to enable the appropriate logging properties
as listed in table 14.2. Coupled with the other logging techniques, the ?logging
interceptor can ?help you ?to gain ?a much ?better perspective ?of the ?internal
broker activities while building message-oriented systems.
?
注意,由输出信息可以看出一个连接和session被添加到了代理中(即创建了一个连接和session),
同时一个连接和session被从代理中移除(即,销毁了一个连接和session).这些日志信息来自一个
消息生产者连接代理发送了一些信息,然后断开和代理之间的连接.如果你想了解更多细节方面信息
你需要启用表14.2中所示的适当的日志属性.在构建面向消息的系统时,使用消息插件再配合其他
日志技术可以帮助你获取更好的代理内部的信息.