Tomcat教程

全部教程

×

使用 java.util.logging(默认)

JDK 所提供的默认 java.util.logging 实现功能太过局限,所以根本没有什么使用价值。其关键局限在于不能实现针对每一应用进行日志记录,因为配置是针对每一 VM 的。所以按照默认配置,Tomcat 会用 JULI 这种非常适用于容器的实现来代替默认的 LogManager 实现,从而避免了 LogManager 的缺点。

跟标准 JDK 的 java.util.logging 一样,JULI 也支持同样的配置机制,或者使用编程方式,或者指定属性值。它与 java.util.logging 的不同在于,它可以分别设置每一个类加载器属性文件(能够启用简单的、便于重新部署的应用配置),属性文件还支持扩展构造,能够更加自由地定义 handle 并将其指定给 logger。

JULI 是默认启用的,除了普通的全局 java.util.logging 配置之外,它支持每个类加载器配置。这意味着可以在下列层级来配置日志:

  • 全局范围。${catalina.base}/conf/logging.properties 文件。该文件通过由启动脚本设置的系统属性 java.util.logging.config.file 来指定。如果它不可读或没有配置,默认采用 JRE 中的 ${java.home}/lib/logging.properties 文件。
  • 在 Web 应用范围内。该文件为 WEB-INF/classes/logging.properties。

JRE 中默认的 logging.properties 指定了 ConsoleHandler,用于将日志输出至 System.err。Tomcat 中默认的 conf/logging.properties 也添加了几个能够写入文件的 FileHandlers。

handler 的日志级别容差值默认为 INFO,取值范围为:SEVERE、WARNING、INFO、CONFIG、FINE、FINER、FINEST 或 ALL。你也可以从特殊的包中收集日志,然后为这种日志指定相应的级别。

为了启用 部分 Tomcat 内部的调试日志功能,应该配置适合的 logger 和 handle 来使用 FINEST 或 ALL 级别。比如:

org.apache.catalina.session.level=ALLjava.util.logging.ConsoleHandler.level=ALL

当启用调试日志功能时,建议将范围尽量缩小,因为该功能会产生大量信息。

JULI 所使用的配置与纯 java.util.logging 所支持的配置基本相同,只不过使用了一些扩展,以便更灵活地配置 logger 和 handler。主要的差别在于:

  • handler 名称前可以加上前缀,所以同一类可以实例化出多个 handler。前缀是一个以数字开头的字符串,并以 . 结尾。比如 22foobar. 就是个有效的前缀。
  • 系统属性

还有一些额外的实现类,它们可以与 Java 所提供的类一起使用。在这些类中,最著名的就是 org.apache.juli.FileHandler。

org.apache.juli.FileHandler 支持日志缓存。日志缓存默认是没有启用的。使用 handler 的 bufferSize 属性可以配置它:属性值为 0 时,代表使用系统默认的缓存(通常使用 8k 缓存);属性值小于 0 时,将在每个日志写入上强制使用 writer flush(将缓存区中的数据强制写出到系统输出)功能;属性值大于 0 时,则使用带有定义值的 BufferedOutputStream 类——但要注意的是,这也将应用于系统默认的缓存。

以下是一个 $CATALINA_BASE/conf 中的 logging.properties 文件:

handlers = 1catalina.org.apache.juli.FileHandler, \
           2localhost.org.apache.juli.FileHandler, \
           3manager.org.apache.juli.FileHandler, \
           java.util.logging.ConsoleHandler
.handlers = 1catalina.org.apache.juli.FileHandler, java.util.logging.ConsoleHandler
############################################################# Handler specific properties.# Describes specific configuration info for Handlers.############################################################
1catalina.org.apache.juli.FileHandler.level = FINE1catalina.org.apache.juli.FileHandler.directory = ${catalina.base}/logs1catalina.org.apache.juli.FileHandler.prefix = catalina.
2localhost.org.apache.juli.FileHandler.level = FINE2localhost.org.apache.juli.FileHandler.directory = ${catalina.base}/logs2localhost.org.apache.juli.FileHandler.prefix = localhost.
3manager.org.apache.juli.FileHandler.level = FINE3manager.org.apache.juli.FileHandler.directory = ${catalina.base}/logs3manager.org.apache.juli.FileHandler.prefix = manager.3manager.org.apache.juli.FileHandler.bufferSize = 16384
java.util.logging.ConsoleHandler.level = FINE
java.util.logging.ConsoleHandler.formatter = java.util.logging.SimpleFormatter
############################################################# Facility specific properties.# Provides extra control for each logger.############################################################
org.apache.catalina.core.ContainerBase.[Catalina].[localhost].level = INFO
org.apache.catalina.core.ContainerBase.[Catalina].[localhost].handlers = \
   2localhost.org.apache.juli.FileHandler

org.apache.catalina.core.ContainerBase.[Catalina].[localhost].[/manager].level = INFO
org.apache.catalina.core.ContainerBase.[Catalina].[localhost].[/manager].handlers = \
   3manager.org.apache.juli.FileHandler
# For example, set the org.apache.catalina.util.LifecycleBase logger to log# each component that extends LifecycleBase changing state:#org.apache.catalina.util.LifecycleBase.level = FINE

下例是一个用于 servlet-examples 应用的 WEB-INF/classes 中的 logging.properties 文件:

handlers = org.apache.juli.FileHandler, java.util.logging.ConsoleHandler
############################################################# Handler specific properties.# Describes specific configuration info for Handlers.############################################################

org.apache.juli.FileHandler.level = FINE
org.apache.juli.FileHandler.directory = ${catalina.base}/logs
org.apache.juli.FileHandler.prefix = ${classloader.webappName}.

java.util.logging.ConsoleHandler.level = FINE
java.util.logging.ConsoleHandler.formatter = java.util.logging.SimpleFormatter

1. 文档引用

查看下列资源获取额外的详细信息:

  • org.apache.juli 包的相关 Tomcat 文档。
  • java.util.logging 包的 Oracle Java 6 文档。

2. 生产环境使用中的注意事项

可能需要注意以下方面:

  • 将 ConsoleHandler 从配置中移除。默认(多谢 .handlers 设置)日志会使用 FileHandler 和 ConsoleHandler。后者的输出经常会被捕获到一个文件中,比如 catalina.out。从而导致同一消息可能生成了两个副本。
  • 对于不使用的应用(比如 host-manager),可以考虑将 FileHandlers 移除。
  • handler 默认使用系统缺省编码来写入日志文件,通过 encoding 属性可以修改设置,详情查看相关的 javadoc 文档。
  • 配置 Access log 。