简体   繁体   English

Java中更干净的调试级别日志记录?

[英]Cleaner debug level logging in Java?

Is there a cleaner way for me to write debug level log statements? 我有没有更干净的方式编写调试级别日志语句? In some ways one could say that the string literals are basically commenting the code and providing logging in one line and that it is already very clean. 从某种意义上说,字符串文字基本上是在注释代码并在一行中提供日志记录,并且它已经很干净了。 But after I add debug level log statements, I find the code much less easier to read up and down. 但是,在添加调试级别日志语句之后,发现代码难以上下读起来。 Take this example (I may update to a real example if I get back to my home PC): 以以下示例为例(如果回到家用PC,我可能会更新为真实示例):

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");

You could try using aspects, although these have the limitation that you can only put log statements "around" method calls, ie before entering and/or after leaving a specific method. 您可以尝试使用方面,尽管这些方面具有局限性,即您只能将日志语句放在方法调用的“周围”,即在进入和/或离开特定方法之后。

For more detailed logging, I am afraid there is no other way than hand-coded log messages. 对于更详细的日志记录,恐怕没有什么办法只能是手工编码的日志消息。

I typically strive to remove the not-so-much-needed debug log statements from the code once I made sure that it works the way it should (for which unit tests are a must). 一旦确定它可以按应有的方式工作(必须进行单元测试),我通常会从代码中删除不需要的调试日志语句。

Ask yourself if I run this in a different machine/country/planet, and things go wrong and all I have is only a log file what information do I need to know what has gone wrong ? 问问自己我是否在其他机器/国家/地区/行星上运行此设备,但出现了问题,我所拥有的只是一个日志文件,我需要什么信息才能知道出了什么问题?

Use debug logs in a for loop, or a while loop sparingly. 在for循环或while循环中谨慎使用调试日志。 For example, if you are reading 1000 records from a file, performing an op for each record. 例如,如果您要从一个文件中读取1000条记录,请对每个记录执行一次操作。 You could record before the for loop that "file exists and is readable and is going to read 1000 records" and print status after the process is done. 您可以在for循环之前记录“文件存在并且可读并且将要读取1000条记录”,并在处理完成后打印状态。 If it is say 1000000 records then you could print something every say 100 or 1000 iterations 如果说1000000条记录,则可以说100或1000次迭代

In your code except for the logger for setting i to 0 everything else sorta makes sense to me. 在您的代码中,除了将i设置为0的记录器之外,其他一切对我来说都是有意义的。 Also care to use log.isDebugEnabled() if your string in the logger statmeent is hard to compute.. 如果记录器状态中的字符串难以计算,还应注意使用log.isDebugEnabled()。

ex: 例如:

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

UPDATE 1: SLF4J solves only half the problem. 更新1:SLF4J仅解决了一半问题。

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

Yes the toString is prevented but if you are logging an actual object which is result of some computation you are not prevented. 是的,可以防止toString,但是如果您记录的是由于某种计算而导致的实际对象,则不会阻止。

If you want very fine grained debug instructions I am not sure you can separate the actual code from the debug code. 如果您需要非常细粒度的调试说明,我不确定您可以将实际代码与调试代码分开。

If you want it at a higher level, maybe adding your logging using AOP could help make things easier to read, maybe use a proxy object? 如果您需要更高的级别,也许使用AOP添加日志记录可以使事情更容易阅读,或者使用代理对象?

But if you have debug instructions as fine grained as in the example you provided, IMHO you could gain more by replacing the loggers with unit tests. 但是,如果您的调试指令与您提供的示例中的粒度一样,恕我直言,您可以通过将记录器替换为单元测试来获得更多收益。 Don't write in a log that something happened, test that it did. 不要在日志中写出有什么事情发生,请测试是否发生了。

You will not be able to do much if you dislike the log statements. 如果您不喜欢日志语句,将无法做很多事情。 The information needs to be there somehow. 信息需要以某种方式存在。

What you CAN do, is strongly considering what NEEDS to be there. 您可以做的是,强烈考虑要有哪些需求。 You are basically writing for the log file reader who per definition does not know about how your program works, so the information needs to be concise and correct. 您基本上是在为日志文件阅读器写的,该阅读器的每个定义都不知道您的程序如何工作,因此信息必须简明而正确。 Personally I very frequently add the method name to the log statement. 我个人经常将方法名称添加到log语句中。

Also note that slf4j allows you to use the {}-syntax which helps somewhat 另请注意,slf4j允许您使用{}语法,这在一定程度上有所帮助

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

Also note that having unit tests, allow you to move much stuff to there simply because you know that THAT works. 还要注意,有了单元测试,仅仅因为您知道THAT起作用,就可以将很多东西移到那里。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM