日志规范(初稿)
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
日志规范
一.什么时候打日志
原则:一般来说日志分为两种:业务日志和异常日志,使用日志我们希望能达到以下目标:
1.对程序运行情况的记录和监控;
2.在必要时可详细了解程序内部的运行状态;
3.对系统性能的影响尽量小
通常情况下在程序日志里记录一些比较有意义的状态数据:程序启动,退出的时间点;程序运行消耗时间;耗时程序的执行进度;重要变量的状态变化。除此之外,在公共的日志里规避打印程序的调试或者提示信息。
日志等级:
1.成品阶段:我的代码是INFO 等级,第三方库是WARN。
2.测试、集成阶段:我的代码是DEBUG 等级,第三方库是WARN(或
者如果需要的话是INFO)。
3.开发阶段:任何有意义的信息。
注意:不建议使用TRACE/FINEST 等级
二.怎么打日志(日志最佳实践)
编码规范:
1.在一个对象中通常只使用一个Logger对象,Logger应该是static final
的,只有在少数需要在构造函数中传递logger的情况下才使用private
final。
static final logger_LOG=loggerFactory.getLogger(Main.class);
2.输出Exceptions的全部Throwable信息,因为logger.error(msg)和logger.error(msg,e.getMessage())这样的日志输出方法会丢失掉最重要的StackTrace信息。
例子:void foo(){
try { // do something... }
catch ( Exception e ){
_LOG.error(e.getMessage()); // 错误
_LOG.error("Bad things : ",e.getMessage()); // 错误
_LOG.error("Bad things : ",e); // 正确
} }
3.不允许记录日志后又抛出异常,因为这样会多次记录日志,只允许记录一
次日志。
例子:void foo() throws LogException{
try{ // do something...
}catch ( Exception e ){
_LOG.error("Bad things : ", e);
throw new LogException("Bad things : ",e);
} }
4.不允许出现System print(包括System.out.println和
System.error.println)语句。
例子:void foo() {
try{ // do something...
}catch( Exception e ){
System.out.println(e.getMessage()); // 错误
System.err.println(e.getMessage()); // 错误
_LOG.error("Bad things : ",e ); // 正确
} }
5.不允许出现printStackTrace。
例子:void foo() {
try { // do something...
}catch ( Exception e ) {
e.printStackTrace(); // 错误
_LOG.error("Bad things : ", e ); //正确
}}
6.日志性能的考虑,如果代码为核心代码,执行频率非常高,则输出日志建
议增加判断,尤其是低级别的输出
debug日志太多后可能会影响性能,有一种改进方法是:
if (LOGGER.isDebugEnabled ()) {
LOGGER.debug("returning content: "+ content);
}
7.但更好的方法是Slf4j提供的最佳实践:
LOGGER.debug("returning content: {}", content);
一方面可以减少参数构造的开销,另一方面也不用多写两行代码。
8.日志可读性,不仅仅面向开发
举个例子吧,我们来看看下面这条日志信息:
ERROR: Save failure - SQLException .....
保存什么呢?这条消息在开发者看来是能说明一些问题的,但是对于正在苦苦查看产品问题的可怜家伙来说,却毫无用处。
更合适的信息是这样的:
RROR: Save failure- Entity=Person, Data=[id=123 surname="Mario"] - SQLException....
9.提交前去除编码帮助日志
编程时用的debug,需要发布时去掉:
如:void aMethod(String aParam) {
LOGGER.debug(“Enter in aMethod”);
if (“no”.equals(aParam)) {
LOGGER.debug(“User says no”);
发布时,去除帮助日志。
10.减少应使用debug导致性能开销增加
如果是Slf4j,可以将
(“Person name is “ + person.getName());
改为:(“Person name is {}“, person.getName());
这样这就避免创建了不必要的字符串实例。
三.日志的要素
本文制定日志规范的原因,除了让日志统一格式外,更重要能记录有效的数据,为后面数据挖掘做准备。
如何记录有效日志?需要记录哪些要素?需要大家共想。
个人举例:
1.以行为维度记录:比如-----谁在什么时间,在什么地方,正在干什么。
2.以模块维度记录:比如----分支付,下单,查看,登陆等模块记录,统一加
上前缀。
……..