loginJava和一般:最佳实践?

有时当我看到我的日志代码时,我想知道我是否正确。 对此可能没有明确的答案,但我有以下担忧:

库类

我有几个库类可能会logging一些INFO消息。 致命错误报告为例外情况。 目前我在我的类中有一个静态logging器实例,类名是logging名。 (Log4j's: Logger.getLogger(MyClass.class)

这是正确的吗? 也许这个库类的用户不想从我的实现中得到任何消息,或者想要将它们redirect到特定于应用程序的日志。 我应该允许用户从“外部世界”设置一个logging器吗? 你如何处理这种情况?

一般日志

在某些应用程序中,我的类可能需要将日志消息写入到未由类名称标识的特定日志中。 (即: HTTP Request log )做这样的事情最好的办法是什么? 一个查找服务想到…

你的约定是相当标准和相当好(恕我直言)。

有一点需要注意的是内存碎片来自过多的未经debugging的debugging,因此,使用Log4J(以及大多数其他Java日志logging框架),您最终会得到如下结果:

 if (log.isDebugEnabled()) { log.debug("..."); } 

因为构build日志消息(你可能没有使用)可能是昂贵的,特别是如果做了成千上万次。

你的INFO级别的日志logging不应该太“健谈”(从你所说的话来看,这听起来好像不是)。 INFO消息通常应该是有意义和重要的,就像正在启动和停止的应用程序一样。 如果遇到问题,您可能想知道的事情。 debugging/精细级别日志logging更多地用于实际存在您正在尝试诊断的问题。 debugging/精细logging通常只在需要时打开。 信息通常是在所有的时间。

如果有人不希望从你的类中获得特定的INFO消息,他们当然可以自由地改变你的log4jconfiguration,使它们不能被获取。 Log4j在这个部门非常简单(与Java 1.4日志logging相反)。

至于你的HTTP的事情,我一般没有发现这是Java日志logging的问题,因为通常一个类负责你感兴趣的内容,所以你只需要把它放在一个地方。 在(我的经验中很less见),当你需要通过看似不相关的类的通用日志消息时,只需要input一些可以很容易理解的标记。

关于实例化logging器,我已经使用Eclipse Java模板设置我的logging器取得了一些成功:

 private static Logger log = Logger.getLogger(${enclosing_type}.class); 

这样可以避免JVM利用堆栈跟踪的问题,并且首先可以减less创build堆栈跟踪的开销。

使用这样一个模板的好处是,如果你想为logging器设置一个统一的标准,你可以和你的团队分享。

它看起来像IntelliJ支持一个模板variables表示封闭types的名称相同的概念。 在NetBeans中我看不到一种方便的方法。

在@cletus的回答中 ,他写到了这个问题

 if (log.isDebugEnabled()) { log.debug("val is " + value); } 

这可以通过使用SL4J来克服。 它提供了格式化帮助

 log.debug("val is {}", value); 

消息只在级别debugging时才构造。

所以,现在,使用SL4J及其伴侣logging仪Logback,出于性能和稳定性的原因。

你所描述的那种log4jconfiguration的首选选项是使用log4jconfiguration文件 。 这允许您的实现的用户完全按照您的要求进行操作,因为他们可以稍后使用更适合自己实现的内容来覆盖您的configuration。 在这里看到一个非常彻底的底漆。

我可能从某个地方偷了这个东西,但是很好。

它降低了复制和重构时混合logging器的风险,而且键入的次数也更less。

在你的代码中:

 private final static Logger logger = LoggerFactory.make(); 

…和LoggerFactory中:

 public static Logger make() { Throwable t = new Throwable(); StackTraceElement directCaller = t.getStackTrace()[1]; return Logger.getLogger(directCaller.getClassName()); } 

(请注意,stackdump是在初始化过程中完成的,堆栈跟踪可能不会被JVM优化,但实际上没有保证)

我正在审查一个应用程序的日志级别,我目前正在检测一个模式:

 private static final Logger logger = Logger.getLogger(Things.class) public void bla() { logger.debug("Starting " + ...) // Do stuff ... logger.debug("Situational") // Algorithms for(Thing t : things) { logger.trace(...) } // Breaking happy things if(things.isEmpty){ logger.warn("Things shouldn't be empty!") } // Catching things try { ... } catch(Exception e) { logger.error("Something bad happened") } logger.info("Completed "+...) } 

一个log4j2文件定义了一个socket-appender和一个故障转移文件appender。 和一个控制台appender。 有时我会在情况需要时使用log4j2标记。

以为额外的angular度可能会有所帮助

另外,我认为Java的简单日志Facade(SLF4J)( http://www.slf4j.org/ )很重要。 由于在一个大项目的多样化部分使用不同的日志框架的一些问题,SLF4J是解决成功pipe理这些部分的问题的事实上的标准,不是吗?

第二个概念:似乎有些老派的任务可以被Aspect-Oriented-Programming取代,Spring frmwrk有它自己的实现 ,AOP-logging 在这里被认为是StackOverflow和Spring博客。