您的位置:首页 > 其它

程序中log打印的梳理

2016-06-15 00:00 337 查看
程序中记录日志一般有两个目的:Troubleshooting和显示程序运行状态。好的日志记录方式可以提供我们足够多定位问题的依据。

这周看过很多代码,对里面的日志记录方式有些想法,今天是周末,也想总结下我对这个问题的看法。日志记录大家都会认为简单,但如何通过日志可以高效定位问题可不是简单的事情。这里我会写下面三个方面的内容,主要是举例为主,提醒我以后得注意这些方面

怎样记日志可以方便Troubleshooting

程序运行状态可以记哪些

应该避免怎样的日志方式

方便Troubleshooting的日志:

对外部的调用封装:

程序中对外部系统与模块的依赖调用前后都记下日志,方便接口调试。出问题时也可以很快理清是哪块的问题

Java代码

LOG.debug("Calling external system:" + parameters);

Object result = null;

try {

result = callRemoteSystem(params);

LOG.debug("Called successfully. result is " + result);

} catch (Exception e) {

LOG.warn("Failed at calling xxx system . exception : " + e);

}

状态变化:
程序中重要的状态信息的变化应该记录下来,方便查问题时还原现场,推断程序运行过程

Java代码

boolean isRunning;

isRunning = true;

LOG.info("System is running");

//...

isRunning = false;

LOG.info("System was interrupted
3ff0
by " + Thread.currentThread().getName());

系统入口与出口:
这个粒度可以是重要方法级或模块级。记录它的输入与输出,方便定位

Java代码

void execute(Object input) {

LOG.debug("Invoke parames : " + input);

Object result = null;

//business logical

LOG.debug("Method result : " + result);

}

业务异常:
任何业务异常都应该记下来

Java代码

try {

//business logical

} catch (IOException e) {

LOG.warn("Description xxx" , e);

} catch (BusinessException e) {

LOG.warn("Let me know anything");

} catch (Exception e) {

LOG.error("Description xxx", e);

}

void invoke(Object primaryParam) {

if (primaryParam == null) {

LOG.warn("Why this primary param is null?");

return;

}

}

非预期执行:
为程序在“有可能”执行到的地方打印日志。如果我想删除一个文件,结果返回成功。但事实上,那个文件在你想删除之前就不存在了。最终结果是一致的,但程序得让我们知道这种情况,要查清为什么文件在删除之前就已经不存在呢

Java代码

int myValue = xxxx;

int absResult = Math.abs(myValue);

if (absResult < 0) {

LOG.info("Original int " + myValue + "has nagetive abs " + absResult);

}

很少出现的else情况:
else可能吞掉你的请求,或是赋予难以理解的最终结果

Java代码

Object result = null;

if (running) {

result = xxx;

} else {

result = yyy;

LOG.debug("System does not running, we change the final result");

}

程序运行状态
程序在运行时就像一个机器人,我们可以从它的日志看出它正在做什么,是不是按预期的设计在做,所以这些正常的运行状态是要有的。

程序运行时间:

Java代码

long startTime = System.currentTime();

// business logical

LOG.info("execution cost : " + (System.currentTime() - startTime) + "ms"); 

大批量数据的执行进度


Java代码

LOG.debug("current progress: " + (currentPos * 100 / totalAmount) + "%");

关键变量及正在做哪些重要的事情:
执行关键的逻辑,做IO操作等等

Java代码

String getJVMPid() {

String pid = "";

// Obtains JVM process ID

LOG.info("JVM pid is " + pid);

return pid;

}

void invokeRemoteMethod(Object params) {

LOG.info("Calling remote method : " + params);

//Calling remote server

}

避免的日志方式

无意义的Log:
日志不包含有意义的信息: 你肯定想知道的是哪个文件不存在吧

Java代码

File file = new File("xxx");

if (!file.isExist()) {

LOG.warn("File does not exist"); //Useless message

}

混淆信息的Log:
日志应该是清晰准确的: 当看到日志的时候,你知道是因为连接池取不到连接导致的问题么?

Java代码

Connection connection = ConnectionFactory.getConnection();

if (connection == null) {

LOG.warn("System initialized unsuccessfully");

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: