如何知道什么时候有太多的日志消息?

时间:2009-10-16 19:21:01

标签: java logging

我遇到了一个非常好的库来解析CUE文件。但是当我开始阅读它的源代码时,我意识到它几乎是不可读的:

public void setParent(final CueSheet parent) {
    FileData.logger.entering(FileData.class.getCanonicalName(), "setParent(CueSheet)", parent);
    this.parent = parent;
    FileData.logger.exiting(FileData.class.getCanonicalName(), "setParent(CueSheet)");
}

每个方法都有logger.entering()和logger.exiting()消息。那不是太多了吗?

还有另一个用于解析音频标签的java库。对于它读取的每个文件,它也有15条日志消息。这很烦人,所以我注释掉了对logger的每一次调用。并且库的速度提高了两倍,因为它们使用了很多字符串连接来记录日志消息。

所以问题是:我是否应该记录所有内容,即使它不是大型企业应用程序?因为这些库显然不需要任何日志记录,除了错误消息。我的经验表明,记录器是调试的糟糕工具。我为什么要使用它?

9 个答案:

答案 0 :(得分:10)

如何知道什么时候记录太多?当您知道记录的信息从长远来看不重要时,用于调试操作或错误更正,或者应用程序不处理太多重要信息。

有时您需要记录几乎所有内容。性能或完全可能的分析是应用程序中最重要的部分吗?这真的取决于。

我过去曾与许多不同的网络服务集成,例如同一个应用程序中的10个。我们记录了所有 xml请求和响应。这是开销吗?从长远来看,我不这么认为,因为我们使用了大量的信用卡操作,并且应该记录服务器的每个进程。如果有错误,如何知道发生什么

你不会相信我在一些xml响应中看到的内容。我甚至收到了一台没有关闭标签的xml,来自一家大型飞机公司。 “过度原木”是一种不好的做法吗?当您必须证明错误来自其他供应商时,请向您的客户说明。

答案 1 :(得分:3)

大多数日志记录库都包含一种方法,用于在处理指令之前确认已启用日志记录:

例如:

public void foo(ComplicatedObject bar) {
    Logger.getInstance(Foo.class).trace("Entering foo(" + bar + ")");
}

取决于bar.toString()方法的效率,可能会非常昂贵。但是,如果您在执行字符串连接之前将其包装在检查日志记录级别中:

static {
    Logger log = Logger.getInstance(Foo.class);

public void foo(ComplicatedObject bar) {
    if (log.isTraceEnabled()) {
        log.trace("Entering foo(" + bar + ")");
    }
}

如果该类的至少一个appender设置为Trace,则仅发生字符串连接。任何复杂的日志消息都应该这样做,以避免不必要的字符串创建。

答案 2 :(得分:2)

理想情况下,您使用允许记录级别的记录器;例如,log4j有致命/错误/警告/调试/信息。这样,如果将级别设置为“仅显示错误”,则不会失去您不需要的软件构建日志消息的速度。

也就是说,直到最终需要记录下来的东西才会记录太多。听起来大多数减慢你速度的日志应该是“跟踪”级别的;它向你展示了一个分析器会有什么。

答案 3 :(得分:0)

这取决于它的应用程序代码还是库?对于应用程序,一旦代码投入生产,记录器就很有用。它不应该用于调试,而是帮助您复制错误。当用户告诉您应用程序崩溃时,您始终需要最大的日志记录信息。

我同意它会降低代码的可读性。它甚至会使应用程序变慢!

这是一个完全不同的图书馆游戏。您应该具有足够级别的一致日志记录。库应该在发生错误时通知开发团队。

答案 4 :(得分:0)

日志记录应该为您提供堆栈跟踪无法跟踪问题的信息。这通常意味着信息是程序所做的某种历史痕迹,而不是失败时的状态。

过多的历史数据将被忽略。如果你可以安全地推断出一个方法被调用而不必实际记录它的入口和出口,那么删除那些记录条目是安全的。

另一个不好的迹象是,您的日志记录文件是否开始耗尽大量磁盘空间。你不仅要牺牲空间,你可能会放慢应用程序的速度。

答案 5 :(得分:0)

要回答这个问题,我为什么要使用记录器?

您是否遇到过一个软件,其中向最终用户显示的唯一错误是Fatal error occured。找出导致它的原因不是很好吗?

日志记录是一种可以真正帮助您缩小现场问题范围的工具。 请记住,最终用户系统没有很好的IDE来调试,最终用户通常不够熟悉运行这些工具。但是,在大多数情况下,最终用户能够将日志配置文件(由我们,聪明的程序员编写)复制到预定义的位置并获取日志文件并通过电子邮件将它们发送回给我们(贫穷的鞋底,因为必须解析兆字节的日志输出)他们遇到了问题。

话虽如此,日志记录应该是高度可配置的,并且在正常条件下产生最小的输出。此外,警卫应该保护更精细级别的日志记录,避免消耗太多资源。

我认为在示例中,您提供的所有日志记录都应该在TRACE级别完成。另外,因为在函数入口点和出口之间没有任何不好的事情发生,所以在那里只有一个日志语句可能是有意义的。

答案 6 :(得分:0)

多年来,我一直在推动在适当级别(跟踪,信息等)记录所有内容之间向后和向前摇摆,并认为任何都是完全浪费时间。实际上,它取决于跟踪或需要什么有用(日志记录可以是维护审计跟踪的廉价方式)。

就个人而言,我倾向于在组件或服务级别记录进入/退出,然后记录处理中的重要点,例如业务逻辑决策或对另一个服务/组件的调用。当然,错误总是被记录,但只有一次,并且在它们被处理的地方(堆栈跟踪和异常消息应该有足够的信息来诊断问题),并且任何服务/组件接口应该总是处理错误(即使它只是将其转换为更适合调用者的另一个。)

记录错误机会出错的问题是,您最终得到的信息太多,以至于无法识别问题,尤其是当它在服务器下运行时,最终会出现大量交织日志条目。显然,您可以通过在条目中合并请求ID并使用某些软件对其进行过滤来解决这个问题。当然,您也可以使用分布式和/或集群的情况,并且您有多个日志。

现在我从来没有真正编写跟踪进入/退出条目代码,代码只是妨碍了如果真的需要它就更容易使用像aspectj这样的东西。使用aspectj也可以保证一致(您可以在一个地方更改日志格式而不必更改每个操作)并且准确(如果某些重构添加了新的参数,并且开发人员忘记将其添加到日志记录中)。< / p>

我曾经考虑过做或想要查看某人是否已经拥有的东西是一个记录器,它将把条目保存在内存中,然后如果遇到错误则会写入,如果操作成功,则只丢弃条目。如果有人知道一个(理想情况下是log4j)请告诉我,或者如果有人有兴趣那么我就如何实现这个想法。

答案 7 :(得分:0)

这种级别的日志记录在规范上很糟糕 - 事实上,我几天前在Daily WTF中看到了代码exactly like this

但是伐木通常是一件非常好的事情。

答案 8 :(得分:0)

这是日志级别有用的地方。通常,日志级别的详细程度和优先级为TRACE,DEBUG,INFO,WARN,ERROR,FATAL。

开发人员在登录代码时必须有意识地使用正确的日志级别。

在创建Logger实例时,我们必须通过从配置中选择正确的日志级别(总是偏爱config)来传递它。这决定了要记录的级别。例如,在创建记录器时,如果日志级别的配置设置为“ INFO”,则低于“ INFO”(TRACE,DEBUG)的任何内容都不会被记录。

例如,在您上面提到的示例中,TRACE或DEBUG级别更有意义。

在生产中的运行时中,日志级别的配置应始终设置为INFO。

当生产中出现问题时,如果开发人员想找出根本原因,他们可以请求将日志级别更改为TRACE或DEBUG(主要是在可以复制方案的QA环境中),以了解什么确实正在发生(有时必须重新启动该应用程序才能更改日志级别,但这很有用)。

日志级别是一种很好的做法,因为在大多数情况下,我们将无法在环境中启动调试器。由于我们通过选择更高的日志级别来跳过不必要的文件写入,因此性能不会受到影响