这两天,开发的系统遇到了一个非常奇怪的问题,我们的前台程序会将日志时而输出到webapp.log,时而输出到其他日志文件如AlarmThreshold.log中,初看并无规律,但秉着“机器永远不会出错,出错的总是人”这一理念,试着分析原因。

log4j是java使用最为广泛的日志框架,它的使用也相对简单,通过配置appender,logger来定义日志的输出位置,输出格式等,也可以将数据输出到控制台,远程文件系统,数据库等。下面给出一个log4.xml的配置文件:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
<log4j:configuration debug="false" xmlns:log4j="http://jakarta.apache.org/log4j/">
<appender name="console" class="org.apache.log4j.ConsoleAppender">//控制台输出
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%d{hh:mm:ss.SSS} [%t] %p - %m%n"/>
</layout>
</appender> <appender name="OptToDB" class="com.langchao.comm.logweb.OperationAppender">//自定义输出
<param name="Sql" value="%m" />
<filter class="org.apache.log4j.varia.LevelRangeFilter">
<param name="LevelMin" value="INFO" />
<param name="LevelMax" value="INFO" />
</filter>
</appender> <appender name="common" class="org.apache.log4j.DailyRollingFileAppender">//滚动文件输出
<param name="File" value="${PM4H_LOG}/webapp.log"/>
<param name="DatePattern" value="'.'yyyy-MM-dd"/>
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %p - %m%n"/>
</layout>
<filter class="org.apache.log4j.varia.LevelRangeFilter">
<param name="LevelMin" value="DEBUG" />
<param name="LevelMax" value="FATAL" />
</filter>
</appender> <appender name="development" class="org.apache.log4j.DailyRollingFileAppender">
<param name="File" value="${PM4H_LOG}/webdevelopment.log"/>
<param name="DatePattern" value="'.'yyyy-MM-dd"/>
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %p - %m%n"/>
</layout>
<filter class="org.apache.log4j.varia.LevelRangeFilter">
<param name="LevelMin" value="DEBUG" />
<param name="LevelMax" value="FATAL" />
</filter>
</appender>
<!-- ============================================ new pm log =============================================== -->
<appender name="pm.web.log.debug" class="org.apache.log4j.DailyRollingFileAppender">
<param name="File" value="${PM4H_LOG}/webapp.log" />
<param name="DatePattern" value="'.'yyyy-MM-dd" />
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern"
value="%d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %p [%X{module}-%X{lognumber}] [USER:%X{user}] [%X{class}].[%X{method}]: %m%n" />
</layout>
<filter class="org.apache.log4j.varia.LevelRangeFilter">
<param name="LevelMin" value="DEBUG" />
<param name="LevelMax" value="DEBUG" />
</filter>
</appender> <appender name="pm.web.log.error" class="org.apache.log4j.DailyRollingFileAppender">
<param name="File" value="${PM4H_LOG}/webapp.log" />
<param name="DatePattern" value="'.'yyyy-MM-dd" />
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern"
value="%d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %p [%X{module}-%X{lognumber}] [USER:%X{user}] [%X{class}].[%X{method}]: %m%n" />
</layout>
<filter class="org.apache.log4j.varia.LevelRangeFilter">
<param name="LevelMin" value="WARN" />
<param name="LevelMax" value="FATAL" />
</filter>
</appender> <appender name="pm.web.log.info" class="org.apache.log4j.DailyRollingFileAppender">
<param name="File" value="${PM4H_LOG}/webapp.log" />
<param name="DatePattern" value="'.'yyyy-MM-dd" />
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern"
value="%d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %p [%X{module}-%X{lognumber}] [USER:%X{user}] %X{operation} %X{target} %X{target_count} %X{operation_action}: %m%n" />
</layout>
<filter class="org.apache.log4j.varia.LevelRangeFilter">
<param name="LevelMin" value="INFO" />
<param name="LevelMax" value="INFO" />
</filter>
</appender>
<!-- ==================================== end =========================================== -->
<logger name="commonLogger" additivity="false">
<level value ="INFO"/>
<appender-ref ref="common" />
<appender-ref ref="console" />
</logger> <logger name="developmentLogger" additivity="false">
<level value ="INFO"/>
<appender-ref ref="common" />
<appender-ref ref="console" />
</logger> <logger name="operationlog" additivity="false">
<level value ="INFO"/>
<appender-ref ref="OptToDB" />
</logger> <logger name="com.ibatis" additivity="false">
<level value ="DEBUG"/>
<appender-ref ref="console" />
</logger> <logger name="java.sql" additivity="false">
<level value ="DEBUG"/>
<appender-ref ref="console" />
</logger> <logger name="pm.web.log" additivity="false">//自定义logger,代码中可以通过Log.getLogger获取
<level value ="DEBUG"/>
<appender-ref ref="pm.web.log.error" />
<appender-ref ref="pm.web.log.info" />
<appender-ref ref="pm.web.log.debug" />
<appender-ref ref="console" />
</logger> <root>//默认logger,其他logger均集成此logger
<level value="INFO" />
<appender-ref ref="common" />
</root> </log4j:configuration>

系统运行时首先会读取该配置文件初始化logger,对于rootlogger来说,通常是全局的。

经过分析,系统出现日志错误答应你的原因是,后台jar包与前台使用了不同的日志打印方式,后台程序在拿不到指定logger后,会使用root节点配置的appender,最过分的是,私有实现竟在代码中修改了appender指向的File,这种流氓似得行径给定位问题带来了巨大困难,与发射类似,运行时修改代码的成本太高了。

原因找到之后,剩下的就简单了,在重定向逻辑中加入判断是否是前后台分别处理,即可。

log4j学习一:解决系统日志错位问题的更多相关文章

  1. struts2 log4j:WARN Please initialize the log4j system properly. 解决方法

    在tomcat启动的时候,出现这个警告: log4j:WARN No appenders could be found for logger (org.apache.commons.digester. ...

  2. log4j学习(二) 不要用log4j了,用slf4j + logback吧

    标题比较尴尬,log4j学习系列的最后一篇是放弃log4j    - -!  一. 简介 log4j的作者提出了slf4j,简单日志门面,相当于是一套统一的java日志api,是个接口标准,编程时使用 ...

  3. MindSpore联邦学习框架解决行业级难题

    内容来源:华为开发者大会2021 HMS Core 6 AI技术论坛,主题演讲<MindSpore联邦学习框架解决隐私合规下的数据孤岛问题>. 演讲嘉宾:华为MindSpore联邦学习工程 ...

  4. 【IScroll深入学习】解决IScroll疑难杂症

    前言 在去年,我们对IScroll的源码进行了学习,并且分离出了一段代码自己使用,在使用学习过程中发现几个致命问题: ① 光标移位 ② 文本框找不到(先让文本框获取焦点,再滑动一下,输入文字便可重现) ...

  5. log4jWARN Please initialize the log4j system properly解决办法

    原因是没有对log4j这个jar进行文件配置. 要解决这个问题非常简单,建立LOG4J 的配置文件即可.在src 目录下创建配置文件,选择菜单File > New > File,文件名输入 ...

  6. Log4j学习

    学习链接: http://www.codeceo.com/article/log4j-usage.html http://www.blogjava.net/kit-soft/archive/2009/ ...

  7. log4j:WARN Please initialize the log4j system properly.解决

    log4j:WARN No appenders could be found for logger (org.springframework.context.support.ClassPathXmlA ...

  8. 自学了三天的SeaJs学习,解决了前端的一些问题,与小伙伴们一起分享一下!

    我为什么学习SeaJs? [第一]:为了解决项目中资源文件版本号的问题,以及打包压缩合并等问题. [第二]:好奇心和求知欲.[我发现很多知名网站也都在使用(qq空间, msn, 淘宝等等),而且 Se ...

  9. log4j学习日记-写入数据库

    1.首先创建日志数据库 用的是MySQL CREATE TABLE `td_log` (   `lid` int(11) NOT NULL AUTO_INCREMENT,   `lusername` ...

随机推荐

  1. 爬虫学习之基于Scrapy的爬虫自动登录

    ###概述 在前面两篇(爬虫学习之基于Scrapy的网络爬虫和爬虫学习之简单的网络爬虫)文章中我们通过两个实际的案例,采用不同的方式进行了内容提取.我们对网络爬虫有了一个比较初级的认识,只要发起请求获 ...

  2. pyunit实现数据测试框架

    PyUnit提供的动态方法,只编写一个测试类来完成对整个软件模块的测试,这样对象的初始化工作可以在setUp()方法中完成,而资源的释放则可以在tearDown()方法中完成. 使用PyUnit可以像 ...

  3. EasyUI Layout Full - Not Correct in IE8

    EasyUI Full布局在IE10,IE9下正常,IE8无效果,标记一下有知道的可以留个言! 如图 IE 10 IE 8

  4. 【BZOJ 1491】 [NOI2007]社交网络

    Description Input Output 输出文件包括n 行,每行一个实数,精确到小数点后3 位.第i 行的实数表 示结点i 在社交网络中的重要程度. Sample Input 4 4 1 2 ...

  5. Java中“||”与“|”的区别

    两者都是或,但是不一样.举个例实例给你看你就明白了: int i=0;if(3>2 || (i++)>1) i=i+1;System.out.println(i); 这段程序会打印出1,而 ...

  6. linux whereis which

    whereis 命令只能用于程序名的搜索,而且只搜索二进制文件(参数-b).man说明文件(参数-m)和源代码文件(参数-s). [root@localhost ~]# whereis svn svn ...

  7. 读书笔记 (一) ———Fundamentals of Multiagent Systems with NetLogo Examples by Prof. Jose M Vidal

    在网上发现Prof. Jose M Vidal用NetLogo仿真Multi-agent system的视频,随后下载他的著作Fundamentals of Multiagent Systems wi ...

  8. 1014: [JSOI2008]火星人prefix - BZOJ

    Description 火星人最近研究了一种操作:求一个字串两个后缀的公共前缀.比方说,有这样一个字符串:madamimadam,我们将这个字符串的各个字符予以标号:序号: 1 2 3 4 5 6 7 ...

  9. 认识OD的两种断点

    OllyDBG从原理上来区分,有两种不同的断点:软件断点和硬件断点. 也许会有朋友说那不是还有内存断点吗? 内存断点严格来说是属于一种特殊的软件断点. 内存断点: 内存断点每次只能设置一个,假如你设置 ...

  10. spoj 2178

    好水...... #include<cstdio> #include<cstdlib> #include<cstring> #include<algorith ...