用Java清理调试级别的日志记录?

时间:2010-03-05 14:25:11

标签: java logging logback

我是否有更简洁的方法来编写调试级别日志语句?在某些方面,可以说字符串文字基本上是对代码进行注释并在一行中提供日志记录并且它已经非常干净。但是在我添加调试级别日志语句之后,我发现代码更容易上下读取。举个例子(如果我回到家用电脑,我可能会更新到一个真实的例子):

int i = 0;
logger.debug("Setting i to 0,"); //Just an example, would show something more complex
i++;

InputStream is = socket.getInputStream();
DataOutputStream dos = new DataOutputStream(socket.getOutputStream());

IOUtils.write(request, dos);
logger.debug("request written to output");

while (!is.read(buffer))
    logger.debug("Reading into buffer");

logger.debug("Data read completely from socket");

CustomObject.doStuff(buffer);
logger.debug("Stuff has been done to buffer");

4 个答案:

答案 0 :(得分:3)

您可以尝试使用方面,尽管这些方法的局限性在于您只能在方法调用“周围”放置日志语句,即在进入和/或离开特定方法之前。

对于更详细的日志记录,我担心除了手动编码的日志消息之外别无他法。

我确实尝试从代码中删除那些不太需要的调试日志语句,一旦确保它按照应有的方式工作(必须进行单元测试)。

答案 1 :(得分:2)

问问自己我是否在不同的机器/国家/地球上运行此操作,并且出现问题,我只有一个日志文件,我需要知道哪些信息可以解决哪些问题?

在for循环或while循环中谨慎使用调试日志。例如,如果要从文件中读取1000条记录,则对每条记录执行op。您可以在for循环之前记录“文件存在且可读并将读取1000条记录”并在完成该过程后打印状态。如果说是1000000条记录,那么你可以打印每次100或1000次迭代的东西

在你的代码中,除了用于将i设置为0的记录器之外,其他任何一种对我来说都是有意义的。如果记录器statmeent中的字符串很难计算,也要小心使用log.isDebugEnabled()。

例如:

if(log.isDebugEnabled) {
   logger.debug("Here " + obj.aMethodCallThatTakes5MinsToEvaluateToString());
}

更新1:SLF4J只能解决问题的一半。

if(slfLog.isDebugEnabled) {
   slfLog.debug(obj.getObjectThatTakes5Mins());
}

是的,阻止了toString,但是如果你正在记录一个实际的对象,这是一些计算的结果,你就不会被阻止。

答案 2 :(得分:1)

如果您需要非常精细的调试指令,我不确定您是否可以将实际代码与调试代码分开。

如果您希望它处于更高级别,可能使用AOP添加日志记录有助于简化阅读,可能使用proxy对象?

但是,如果您的调试指令与您提供的示例中的细粒度一样,恕我直言,您可以通过使用单元测试替换记录器来获得更多。不要在日志中写下发生的事情,测试一下。

答案 3 :(得分:0)

如果你不喜欢日志语句,你将无法做很多事情。信息需要以某种方式存在。

你能做什么,正在强烈考虑那里需要什么。您基本上是为日志文件阅读器编写的,每个定义都不知道您的程序是如何工作的,因此信息需要简明扼要。就个人而言,我经常将方法名称添加到日志语句中。

另请注意,slf4j允许您使用{} -syntax,这有点帮助

 log.debug("main() date={}, args={}", new java.util.Date(), args);

另请注意,进行单元测试后,您可以将很多内容移动到那里,因为您知道这样做有效。