2

我可以期待“嗨!”的日志条目吗?将发射到${catalina.base}/logs/webapp.log?

Tomcat 配置

{$CATALINA_BASE}/conf/logger.properties

# DECLARE HANDLERS
handlers = 3webapp.org.apache.juli.FileHandler

# CONFIGURE HANDLERS
3webapp.org.apache.juli.FileHandler.level = ALL
3webapp.org.apache.juli.FileHandler.directory = ${catalina.base}/logs
3webapp.org.apache.juli.FileHandler.prefix = webapp
3webapp.org.apache.juli.FileHandler.rotatable = false

# Webapp-local 'ROOT' logger??  The Apache-provided logger.properties
# calls these 'Facility specific'

org.apache.catalina.core.ContainerBase.[Catalina].[localhost].[/webapp].level = ALL
org.apache.catalina.core.ContainerBase.[Catalina].[localhost].[/webapp].handlers = 3webapp.org.apache.juli.FileHandler

Webapp 级别的日志记录配置

WEB-INF/classes/logger.propertiesWAR 部署到/webapp

au.com.mydomain.level = ALL

代码中的用法

WAR 中的代码部署到/webapp

package au.com.mydomain.foo;
import java.util.logging.Logger;
import java.util.logging.Level;

public class Bar {
  ...
  Logger.getLogger(Bar.class.getName()).log(Level.INFO, "Hi!");
  ...
}
4

1 回答 1

1

答案是不”

正如调试器中所确认的那样,如果 Web 应用程序这样做:

 import java.util.logging.Logger;
 ...
 Logger foo = Logger.getLogger("foo");

Thenfoo的直接父org.apache.juli.ClassLoaderLogManager$RootLogger级是 JVM 范围的记录器,它由 Catalina 设置,并且是 中定义的所有其他记录器的最终祖先{$CATALINA_BASE}/conf/logger.properties

但一切都没有丢失

可以获得对“per-webapp”记录器的引用:

String prefix = "org.apache.catalina.core.ContainerBase.[Catalina].[localhost].[/webapp]";
Logger hmm = Logger.getLogger(prefix);

这意味着我们可以获得一个以 per-webapp 记录器为父的记录器:

Logger.getLogger(prefix + "." + MyClass.class.getName())

一个可怕的,可怕的黑客

但是,当然,所有现有代码都在没有指定前缀的情况下执行 Logger.getLogger()。

如果您执行以下操作(在类似的地方ServletContextListener#contextInitialized(ServletContextEvent),您可以:

// eg "org.apache.catalina.core.ContainerBase.[Catalina].[localhost].[/webapp]"
String tomcatHack = sce.getServletContext().getInitParameter("tomcatHack");

if (tomcatHack != null) {
   Logger ctxLog = Logger.getLogger("webappLogger");
   Logger appLog = Logger.getLogger("au.com.mydomain");
   appLog.setParent(ctxLog);
}

现在后续日志:

Logger.getLogger("au.com.mydomain.foo").log(Level.INFO, "Ha!");

... 将出现在log.log.

作为一个令人讨厌的副作用,如果你有两个 web 应用程序在同一个容器中运行这个技巧(例如,/prod 和 /test),那么它们将覆盖父级。

作为一个潜在的令人讨厌的副作用,我们的 logger 根现在在 JVM 范围的 logger 层次结构中的两个点上是一个“孩子”,这可能会在某个时间、某个地方让某人感到不安。

于 2013-10-09T04:38:29.350 回答