3

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

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

4 回答 4

3

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

对于更详细的日志记录,恐怕除了手工编码的日志消息之外别无他法。

一旦我确保它按应有的方式工作(对于单元测试是必须的),我通常会努力从代码中删除不太需要的调试日志语句。

于 2010-03-05T14:41:36.493 回答
2

问问自己我是否在不同的机器/国家/星球上运行它,并且出现问题,我所拥有的只是一个日志文件,我需要哪些信息才能知道出了什么问题?

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

在您的代码中,除了将 i 设置为 0 的记录器之外,其他一切对我来说都是有意义的。如果您在 logger statmeent 中的字符串难以计算,也请注意使用 log.isDebugEnabled()。

前任:

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

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

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

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

于 2010-03-06T10:49:33.290 回答
1

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

如果您希望它处于更高级别,也许使用AOP添加日志记录可以帮助使事情更容易阅读,也许使用代理对象?

但是,如果您有像您提供的示例中那样细粒度的调试指令,恕我直言,您可以通过用单元测试替换记录器来获得更多收益。不要在日志中写某事发生了,测试它确实发生了。

于 2010-03-05T14:40:57.717 回答
0

如果您不喜欢日志语句,您将无能为力。信息需要以某种方式存在。

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

另请注意,slf4j 允许您使用 {}-syntax 这在一定程度上有所帮助

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

另请注意,进行单元测试时,您可以将很多东西移到那里,因为您知道那是可行的。

于 2010-03-06T11:01:03.403 回答