目标:将debug,info级别的日志输出到本地文件,将warn,error级别的日志输出到ActiveMQ。

说明:本文还是使用之前的两个项目:Product和Logging。

经过一番搜索后,发现log4j还可以按照级别过滤日志,但过滤只能使用log4j.xml配置:

Filters can be defined at appender level. For example, to filter only certain levels, the LevelRangeFilter can be used like this:

在搜索资料的过程中,也看到了有网友说log4j.properties方式也可以实现按级别过滤日志,具体步骤请参看《Log4j按级别输出日志到不同文件配置分析》。此种方式的缺点是,如果有多个Appender,则需要多个继承的类(每个Appender需要重新定义一个),因此感觉不如log4j.xml方式通过为appender配置filter来的直接。

value="org.apache.activemq.jndi.ActiveMQInitialContextFactory" />

而Product项目的测试代码相当简单:

package com.demo.product;

import org.apache.log4j.Logger;

public class Main{

public static void main(String[] args) throws Exception {

Logger logger = Logger.getLogger(Main.class);

logger.debug("Debug");

logger.info("Info");

logger.warn("Warn");

logger.error("Error");

logger.fatal("Fatal");

System.exit(0);

}

}

我以为就这样配置就能让WARN和ERROR级别的日志输出到jms了,但是我运行的时候却报错了:

javax.jms.JMSException: Wire format negotiation timeout: peer did not send his wire format.

at org.apache.activemq.util.JMSExceptionSupport.create(JMSExceptionSupport.java:62)

at org.apache.activemq.ActiveMQConnection.syncSendPacket(ActiveMQConnection.java:1395)

at org.apache.activemq.ActiveMQConnection.ensureConnectionInfoSent(ActiveMQConnection.java:1481)

at org.apache.activemq.ActiveMQConnection.createSession(ActiveMQConnection.java:323)

at org.apache.activemq.ActiveMQConnection.createTopicSession(ActiveMQConnection.java:1112)

搜索这个问题,有很多人遇到了,这里列出了三种可能的原因:

1. You're connecting to the port not used by ActiveMQ TCP transport

Make sure to check that you're connecting to the appropriate host:port

2. You're using log4j JMS appender and doesn't filter out ActiveMQ log messages

Be sure to read How do I use log4j JMS appender with ActiveMQ and more importantly to never send ActiveMQ log messages to JMS appender

3. Your broker is probably under heavy load (or network connection is unreliable), so connection setup cannot be completed in a reasonable time

If you experience sporadic exceptions like this, the best solution is to use failover transport, so that your clients can try connecting again if the first attempt fails. If you're getting these kind of exceptions more frequently you can also try extending wire format negotiation period (default 10 sec). You can do that by using wireFormat.maxInactivityDurationInitalDelay property on the connection URL in your client. For example:

tcp://localhost:61616?wireFormat.maxInactivityDurationInitalDelay=30000

第一种情况显然不是。

第三种情况,由于我就一个jms connection,也没有往这个连接发送jms消息,所以不可能负载过重。

第二种情况是不要把activemq的日志发送到JMSAppender了,How do I use log4j JMS appender with ActiveMQ  一文中有以下配置:

## Be sure that ActiveMQ messages are not logged to 'jms' appender

log4j.logger.org.apache.activemq=INFO, stdout

上面的意思是,对于org.apache.activemq包下的INFO级别以上的日志,都输出到stdout appender中。我对比了一下,从拷贝而来的log4j.xml中也包含了类似的配置:

但是为何结果还是这样?几经思考,我重新查看了一下报错的日志:

后面的内容是这样的:

org.apache.activemq.transport.WireFormatNegotiator.negociate-118 | Received WireFormat ...

于是我去找到这个类,在这个negociate方法上打上断点(Maven项目的好处还包括可以自动下载jar包对应版本的源代码),开始调试,然后发现是这一句报错:

然后我想了想能不能不打印这个debug消息呢,于是我在开始的org.apache.activemq包中加上了level限制:

这样以后,问题解决。其实,只要我稍微细心一点,可以发现

log4j.logger.org.apache.activemq=INFO, stdout

这个配置不仅指明了org.apache.activemq包下的日志信息输出到stdout这个appender中,而且还指明了只有INFO以上的级别才能输出。二者同时指定才能达到目的,这在刚刚的xml文件中也得到体现。

现在,WARN和ERROR级别的日志就可以输出到ActiveMQ了:

在Logging项目中,和之前一样,LogMessageListener也只是简单打印了级别和内容:

public void onMessage(Message message) {

LoggingEvent event;

try {

event = (LoggingEvent)((ActiveMQObjectMessage)message).getObject();

System.out.println("[" + event.getLevel() + "] | " + event.getMessage());

} catch (JMSException e) {

e.printStackTrace();

}

}

从结果中能看到输出的日志级别仅仅包括了WARN和ERROR:

至于剩下的DEBUG和INFO级别的日志,则直接配置输出到RollingFileAppender即可。日志文件的内容也当然和预期一样了:

最后贴出完整的log4j.xml配置内容:

log4j:configuration SYSTEM "log4j.dtd">

value="[Log4j-JMS-Sample] %d{yyyy-MM-dd HH:mm:ss,SSS} %p [%t] %c.%M-%L | %m%n" />

value="%c %d{ISO8601} [%p] -- %m%n" />

value="org.apache.activemq.jndi.ActiveMQInitialContextFactory" />

当然,如果希望再把info和debug分开,可以多配置一个fileappender,让每个过滤器的LevelMax和LevelMin的值相等并为它们配置不同的文件即可。

参考:

linux activemq 打印日志,Log4j.xml配置日志按级别过滤并将指定级别的日志发送到ActiveMQ...相关推荐

  1. Log4j.xml配置日志按级别过滤并将指定级别的日志发送到ActiveMQ

    为什么80%的码农都做不了架构师?>>>    在之前的一篇博客<Spring+Log4j+ActiveMQ实现远程记录日志--实战+分析>的评论中,有同学提到这种方式应 ...

  2. 日志 log4j.xml配置详解

    <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE log4j:configuration SY ...

  3. springmvc 项目完整示例05 日志 --log4j整合 配置 log4j属性设置 log4j 配置文件 log4j应用...

    log4j 就是log for java嘛,老外都喜欢这样子,比如那个I18n  ---internationalization  不就是i和n之间有18个字母... http://logging.a ...

  4. Spring MVC 中使用AOP 进行统一日志管理--XML配置实现

    1.介绍 上一篇博客写了使用AOP进行统一日志管理的注解版实现,今天写一下使用XML配置实现版本,与上篇不同的是上次我们记录的Controller层日志,这次我们记录的是Service层的日志.使用的 ...

  5. Springboot日志log4j的配置

    sprongboot使用的默认日志框架是Logback,可以配置成log4j的配置. 只需要两步,就可以简单配置, 1.首先,引入依赖spring-boot-starter-log4j依赖.引入spr ...

  6. 日志管理:(五) log4j.xml 配置实例

    log4j配置实例: [code="xml"] <?xml version="1.0" encoding="UTF-8"?> & ...

  7. log4j xml配置保存日志天数

    <?xml version="1.0" encoding="UTF-8"?> <Configuration status="DEBU ...

  8. log4j xml配置详解

    http://zhangxiang390.iteye.com/blog/258455 熟读一个典型的log4j配置文件: Xml代码   <?xml version="1.0" ...

  9. Log4J xml配置

    <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE log4j:configuration PU ...

最新文章

  1. Linux在高铁项目的部署环境
  2. linux命令:返回上一次目录
  3. Linux 历史命令巧用
  4. 转: 理解RESTful架构
  5. C 的Pair用法分类整理(精)
  6. centos如何安装数据库mysql
  7. NOIP2018游记(更新完毕)
  8. linux下重新分区、数据备份相关(parted、dd等命令)
  9. python-excel写入代码
  10. HTML——网页设计基础
  11. 看似落魄的灵魂登场却如此隆重,风 吹散了平庸 爱漫延没有尽头
  12. Autojs之QQ 群发消息(是QQ 群发,不是QQ群 发)
  13. 免费的开源飞行规划软件Little Navmap
  14. 数据库分页【Limt与Limt..OFFSET 】
  15. python天气预报项目详细设计书_天气预报详细设计说明书
  16. centos6.7 安装端口映射工具 rinetd
  17. Day66 Web开发7 旅游详情页面
  18. 普林斯顿大学计算机科学排名,普林斯顿大学计算机硕士专业排名真实干货升级版...
  19. 给刚工作不久的测试人员的一封信
  20. SAP HANA数据库HA双机架构概念及运维

热门文章

  1. Display常用英文缩写
  2. 杰奇小说站PC端跳转WAP端实现方式
  3. qrcode将生成的二维码转成img格式
  4. 华为工业云平台:制造业企业数据平台建设最佳实践分享
  5. 怎么判断一篇微信公众号文章阅读量是不是刷上来的?
  6. STM32通过IIC读取MPU6050原始数据过程详解
  7. 后台录屏、应用外录屏、跨应用录屏、直播屏幕、录屏扩展(ios)
  8. 程序员用代码求救, 同事“秒懂”
  9. java netcdf精度_NetCDF 介绍
  10. C语言-实现对单循环链表中奇数和偶数结点的移动(前面奇数结点后面偶数结点)