我可以期望向${catalina.base}/logs/webapp.log
发出"Hi!"的日志条目吗?
雄猫配置
{$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
Web 应用级日志记录配置
部署到/webapp
的战争WEB-INF/classes/logger.properties
au.com.mydomain.level = ALL
代码中的用法
部署到/webapp
的 WAR 中的代码
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!");
...
}
答案是"否">
正如在调试器中确认的那样,如果 Web 应用程序执行以下操作:
import java.util.logging.Logger;
...
Logger foo = Logger.getLogger("foo");
然后foo
的直接父级是org.apache.juli.ClassLoaderLogManager$RootLogger
,它是由Catalina建立的JVM范围的记录器,并且是{$CATALINA_BASE}/conf/logger.properties
中定义的所有其他记录器的最终祖先。
但一切都没有丢失
可以获得对"每网络应用"记录器的引用:
String prefix = "org.apache.catalina.core.ContainerBase.[Catalina].[localhost].[/webapp]";
Logger hmm = Logger.getLogger(prefix);
这意味着我们可以获取一个将每个 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
.
作为一个令人讨厌的副作用,如果你有两个网络应用程序在同一容器中运行这个技巧(例如,/prod 和/test(,那么它们将覆盖父级。
作为一个潜在的令人讨厌的副作用,我们的记录器根现在在JVM范围的记录器层次结构中的两个点上是一个"孩子",这可能会在某个地方,某个时候让某人感到不安。