原文出处:http://javax0.wordpress.com/2014/03/05/logging-or-debugging/
Debugging is lame. You should debug log.
debugging是有缺陷的,你应该去打日志进行调试。
If your code is structured you do not need debug logging.
如果你的代码是结构化的,你不应该通过打日志的方式调试程序。
These are two opinions from the two ends of the line. I am, as usually, standing in the middle, and I will tell you why.
我们通常会得到上面两种观点。然后通常,对于我来说,对此保持这中立的态度,下面我来告诉你为什么。
First of all, there is no principal difference between debugging versus logging. They are just two different implementations of the same thing: observation of your execution engine state in time dimension.
首先,在debugging和logging之间没有原则上的区别。他们仅仅是实现在时间维度上观察你执行引擎状态的两种不同的方式。
Issue with debugging
关于debugging的问题
When you debug you step your program forward in time and at any point the execution stops you can examine the value of any variable. The shortage is that you can not step back in time. At some points you realize that you would just like to see what the value of a certain variable was just before some method was called, some object was created or whatsoever happened in the system. What you actually do in such a situation is to restart the code and hoping it behaves deterministic try to catch the execution at the earlier stage that you are interested in. And this is another shortage of debugging. You can not effectively debug a code that does not behave deterministic. And trust me: most bugs behave non deterministic.
当你及时的通过debug步入你的程序并且在任何一个执行点停止时,你都可以检测到任何一个变量的值。然而它的缺点就是不能及时的跳回。在一些点上你意识到你仅仅想要的是看看在调用某个方法或者是某个对象被创建或者是在整个系统中其他的什么事情发生前某个确定变量的值是什么。在这种情形下你确实想做的是去重启你的代码,并且希望他们的行为是确定性的,在你感兴趣的早期阶段尝试去抓取执行状态。然而这又是另一个debugging的缺点,就是你不能够有效的调试一段行为不确定的代码。而且请相信我:大多数的bug行为是不确定性的。
Issue with logging
关于logging
With logs the major issue is different. It is not the time but rather the breadth of states, variables that you can look at is the problem. You insert log statements into your code dumping the values of variables into a log file at a certain point of execution. When you examine the log file you can scroll back and forth. However if you did not print out the value of a certain variable at a certain execution point, there is no way to get it from the log file. The solution is the same as with debugging: execute the code again, this time extended with the new log statements. If, however, you have enough information in your log files, then you will just get enough information to track down a bug even if that is not deterministic. Only ‘if you have’ …
对于logs它的问题是不同的。它不是及时性的而是在一个宏观的状态下,你看到的变量是个问题。在一个确切的执行点,你插入log状态到将变量值写到log文件的代码中。在日志文件中你可以山下滚动的检查。然而如果你没有在某个特定的执行点去打印出它的值,那你就不能够从日志文件中获取到它。这个解决办法和debugging的方式十分类似,就是再次调试你的代码,这个时间点去扩展出新的log状态。然而如果在你的日志文件中有足够的信息,接下来你将获取到足够的信息去跟踪一个bug即使他是不确定的,仅仅是当你有的时候。
Solution: logging all the states all the times?
解决方案:在任何时段logging所有的状态
The ideal solution would be to dump all variables into a possibly binary log file at each state of the execution and examine the content of the file afterwards. The examination would essentially look like a debugger, except that the change of the variables comes from the recorded log file instead of from on the fly calculation. It would be like a playback of a recorded execution and as such you could replay it several times. I do not know if there is any tool like that for the JVM.
这个理想化的解决方案就是在每个执行状态下去将所有的变量添加到一个可能的二进制log文件中,并且检查这个文件之后的状态。这个检查可能会看起来想一个调试器,除了从记录log文件中获取到变量的变化过程,而不是从一个敏捷的计算器中。它就像是一端被记录下的执行过程的回放,并且你可以回放多次。不知道是否有些类似的工具对于JVM。
You just can not define what is “each state” effectively in a multi thread execution environment like the JVM is. This is one of the issues. The other thing is that if you’d start dumping the JVM memory after each command (forgetting the issues of multi-thread) it would require enormous amount of bandwidth and disk space.
在一个想JVM一样的多线程执行环境下,你不能够有效的定义什么事“每个状态”。这是一个问题。另外一件事就是如果你在每个命令之后(这里先忽略掉多线程的问题)去倾倒出JVM内存,他需要的是大量的带宽和存储空间。
Dreaming about the ideal solution not deliverable is sort of no use. What is the solution that can practically be executed?
关于理想的解决方案是不现实的。那么什么样的方法是可以实际的被执行的呢?
Practical approach
趋近实践
You can debug when it is appropriate. Full stop. You just did that so far, keep doing that. I tend to use log statements even when I debug some code and if the environment allows it I do it on the fly. When I find the root cause of the issue I am hunting I review the log statements and I delete them. They did the job while debugging, they are not needed anymore. At least that was my practice unit I found myself writing log statements that I have already created before. Why? Because fixing one bug does not mean that I have fixed all of them. There is nothing like all bugs fixed. But the log items littered the log file and that just increased the work to find the needed information hunting the next bug. In other words the log file is full of noise and that is why I deleted these items the first place. But for the same reason I could also delete the unit tests that already pass. It would save a lot of time during compilation, wouldn’t it? We do not do that.
你可以在适当的时候去调试。完全停止,就是仅仅这么做,并且保持下去。我趋向于使用log状态的方法,即使当我调试一些代码并且如果环境语序我在忙碌的时候这么做。当我发现了我寻找的问题的根源的时候,我会去重申log状态,并且去删除掉它们。当调试的时候,它们不再被需要我就会这么做。那似乎所有bug都没有被修复。但是这个log的选项将log文件搞得乱七八糟,并且它仅仅是增加了寻找下一个bug所需信息的工作量。换而言之,这个文件充满了噪音,并且这就是我为什么要首先删除掉这个 选项。但是也是也因为这个相同的原因,我也要删除掉已经通过的单元测试。这样它就会在编译时节省出来大量的时间,不是吗? 我们不会那么做。
Summary in one sentence? Log and debug the way it fits you and the issue you are hunting.
一言以蔽之? Log和debug的方式适用于你和你正在找寻的问题。