Skip to main content

tplogin.cn首页 > 新闻资讯 >

由客户现场引发的思考

2012-05-09 00:02 浏览:
平时项目使用日志功能,找一个常用的拿来用就可以了.最近两周用户现场的问题,搞得我一头包,发现两个必须在项目与产品上十分重视的地方:日志+异常处理。首先说日志,用户现场出现的问题一般不容易重现出来,如果很容易重现,说明起初的测试并不过关。那么日志是唯一真实的信息来源。客户以及现场支持的人员反馈的信息某些时候会产生误导作用。如果这个时候日志不给力,那时你才知道什么叫举目无亲。
这一次现场的日志有部分日志输出出现了问题,只有异常信息,连堆栈都没有打出来,确认不了这些日志到底从哪里打出来的,为什么在那里catch了这个异常。么办法了。
在说异常,异常处理从来都是项目与产品中处理起来最让人头疼的事情,哪些异常应该捕获,捕获后如何处理,如果需要输出日志,输出什么级别的日志呢。那些异常必须抛出,抛出动作什么时候停止.等等。
再说此次现场问题。项目中有些异常属正常情况,比较实然Socket中断,IO读取出错等,都属于比较正常的异常,捕获并输出FINE级别日志是可以的。但有些线程捕获力度偏大,比如catch throwable,即便是OOM,也无法出局。更给力的是,这时输出的日志居然是FINE级别在生产环境上没有把日志启为FINE级别的,这些日志当然就出不来了。最终系统不断出错,日志文件无反应。为了下一阶段改进日志系统,发现大多数开源产品Geronimo,mina等都采有SLF4J。决定深入了解一下。
SLF4J(Simple Logging Facade for Java)是一个通用的日志门面库,为各种Log实现提供了一套通用的日志接口。SLF4J会根据classpath中所存在的适配器jar来决定将使用的日志实现库。
这样就完成了动态的修改系统日志的实现框架。
比如我们常用的log4j,如果我们的项目采用SLF4J+Log4j构建日志输出,则需要三个JAR文件:
1. slf4j-api-1.6.4.jar
2. slf4j-log4j12-1.6.4.jar
3. log4j-1.2.13.jar
slf4j-api-1.6.4.jarSlf4jSlf4j的接口,也是我们项目编译需要依赖的JAR文件。而slf4j-log4j12-1.6.4.jar就是上面说到适配器的jarlog4j-1.2.13.jar不用说了,log4jJAR文件。
 
其实slf4j-api-1.6.4.jar非常简洁,相信你几个小时或更短的时间内就能读完他的代码,20个类而已(目前好像是23个)。
 
那么SLF4J是如何根据classpath中所存在的适配器jar来决定将使用的日志实现库。其实每一个适配器jar里都含有一个特殊的类:Org.slf4j.impl.StaticLoggerBinder.class。实现LoggerFactoryBinder接口:
 
public interface LoggerFactoryBinder {

 public ILoggerFactory getLoggerFactory();

 public String getLoggerFactoryClassStr();

}
他是一个饿汉式的单例类,也就是通过该类的getLoggerFactory方法获得实现日志(这里指log4j)ILoggerFactory,然后再通过ILoggerFactory获得log4j的相应的Logger.多个熟悉的名字,这样就完成了Slf4jLog4j的姻缘。
SLF4J首先在classpath中寻找Org.slf4j.impl.StaticLoggerBinder.class,如果找到则结对成功。
如果找到多个StaticLoggerBinder,则会提示用户应只保留一个(Class path contains multiple SLF4J bindings)。
 
一些与Slf4j关系比较昧的日志实现,自身实现了适配器,比如目前比较火的logback。配置logback日志就只需要两个JARslf4j-api-1.6.4.jarlogback1.0.3.jar。属于此类的一般晚于Slf4j开发。目前未发现哪个日志实现主动弥补适配器这一缺口的。而且Log4j,slf4j,logback都是同一作者。
关于异常处理总结了几条:
1. 不处理的异常不捕获。前天有个同事这样写:
Try{ // some op
} catch(IOException e){
 Throw e;
}
 这是个不好的习惯。除非想只抛出IOException,其他异常不抛出的情况下考虑这样做。

2. 方法中只捕获异常,没有必须捕获Throwable. 特别是VirualMachineError.

3.没有必要的信息附加时,不要包装原始的异常.
   除非做异常转换,比如checkException转化为uncheckException
4. 一般情况不捕获Exception,因为这样有可能吃掉RuntimeException异常。
5. 异常日志输出一次。一个异常只在一个合适的地方输出。一方面代码简洁,另一方面方便定位问题。

本文出自 “天下无贼” 博客,请务必保留此出处http://guojuanjun.blog.51cto.com/277646/854962。

相关文章

中国移动中兴ZXHN E503路由器,如何登录wifi.cmcc设置

2022-04-15 08:22:30    浏览: 155

电脑跟手机如何打开tp-link路由器登录入口:tplogin.cn

2022-04-15 08:11:01    浏览: 125

水星路由器设置网址:melogin cn

2022-04-15 07:56:40    浏览: 141

默认网关不在由ip地址和子网掩码定义同一网络段上

2022-04-09 09:47:28    浏览: 106

水星幻影D128路由器,如何用手机一键登录melogin.cn设置路由器

2022-03-30 14:46:01    浏览: 72