gpt4 book ai didi

Tomcat 日志记录困惑

转载 作者:行者123 更新时间:2023-11-28 22:24:58 25 4
gpt4 key购买 nike

我有全新安装的 tomcat。

为了改进日志记录,我编辑了 conf/logging.properties

第一步

换行

java.util.logging.ConsoleHandler.level = FINE

java.util.logging.ConsoleHandler.level = FINER

第二步

并附加行

org.apache.catalina.level = FINER

第三步

然后我启动服务器,如果我无法通过用户名 MyUsernameMyPasswordhttp://localhost:8080/manager/ 进行身份验证> 我看到了这个输出:

FINE [http-bio-443-exec-2] org.apache.catalina.authenticator.AuthenticatorBase.invoke Security checking request GET /manager/html
FINE [http-bio-443-exec-2] org.apache.catalina.loader.WebappClassLoaderBase.loadClass loadClass(org.apache.catalina.manager.HTMLManagerServlet, false)
FINE [http-bio-443-exec-2] org.apache.catalina.loader.WebappClassLoaderBase.loadClass Delegating to parent classloader1 java.net.URLClassLoader@1218025c
FINE [http-bio-443-exec-2] org.apache.catalina.loader.WebappClassLoaderBase.loadClass Loading class from parent
FINE [http-bio-443-exec-2] org.apache.catalina.realm.RealmBase.findSecurityConstraints Checking constraint 'SecurityConstraint[Status interface]' against GET /html --> false
FINE [http-bio-443-exec-2] org.apache.catalina.realm.RealmBase.findSecurityConstraints Checking constraint 'SecurityConstraint[JMX Proxy interface]' against GET /html --> false
FINE [http-bio-443-exec-2] org.apache.catalina.realm.RealmBase.findSecurityConstraints Checking constraint 'SecurityConstraint[Text Manager interface (for scripts)]' against GET /html --> false
FINE [http-bio-443-exec-2] org.apache.catalina.realm.RealmBase.findSecurityConstraints Checking constraint 'SecurityConstraint[HTML Manager interface (for humans)]' against GET /html --> true
FINE [http-bio-443-exec-2] org.apache.catalina.realm.RealmBase.findSecurityConstraints Checking constraint 'SecurityConstraint[Status interface]' against GET /html --> false
FINE [http-bio-443-exec-2] org.apache.catalina.realm.RealmBase.findSecurityConstraints Checking constraint 'SecurityConstraint[JMX Proxy interface]' against GET /html --> false
FINE [http-bio-443-exec-2] org.apache.catalina.realm.RealmBase.findSecurityConstraints Checking constraint 'SecurityConstraint[Text Manager interface (for scripts)]' against GET /html --> false
FINE [http-bio-443-exec-2] org.apache.catalina.realm.RealmBase.findSecurityConstraints Checking constraint 'SecurityConstraint[HTML Manager interface (for humans)]' against GET /html --> true
FINE [http-bio-443-exec-2] org.apache.catalina.authenticator.AuthenticatorBase.invoke Calling hasUserDataPermission()
FINE [http-bio-443-exec-2] org.apache.catalina.realm.RealmBase.hasUserDataPermission User data constraint has no restrictions
FINE [http-bio-443-exec-2] org.apache.catalina.authenticator.AuthenticatorBase.invoke Calling authenticate()
FINER [http-bio-443-exec-2] org.apache.catalina.realm.RealmBase.authenticate Username MyUsername NOT successfully authenticated
FINE [http-bio-443-exec-2] org.apache.catalina.authenticator.AuthenticatorBase.invoke Failed authenticate() test
FINE [http-bio-443-exec-2] org.apache.catalina.core.StandardHostValve.custom Processing ErrorPage[errorCode=401, location=/WEB-INF/jsp/401.jsp]
FINER [http-bio-443-exec-2] org.apache.catalina.core.StandardWrapper.allocate Returning non-STM instance
FINE [http-bio-443-exec-2] org.apache.catalina.core.ApplicationDispatcher.doForward Disabling the response for futher output
FINE [ContainerBackgroundProcessor[StandardEngine[Catalina]]] org.apache.catalina.session.ManagerBase.processExpires Start expire sessions StandardManager at 1525428004090 sessioncount 0
FINE [ContainerBackgroundProcessor[StandardEngine[Catalina]]] org.apache.catalina.session.ManagerBase.processExpires End expire sessions StandardManager processingTime 4 expired sessions: 0

问题

现在我修改步骤 2 并将包 realm 添加到定义中。现在第 2 步添加了这一行:

org.apache.catalina.realm.level = FINER

为什么 FINER-Loggings 消失了?我的意思是,org.apache.catalina.realm 更具体,对吧?

最佳答案

如果我的理解正确,您最终会得到如下所示的日志记录属性:

java.util.logging.ConsoleHandler.level = FINER
org.apache.catalina.realm.level = FINER

Java Logging Overview section 1.1状态:

Applications make logging calls on Logger objects. Loggers are organized in a hierarchical namespace and child Loggers may inherit some logging properties from their parents in the namespace.

当读取记录器名称时,父记录器位于点的左侧。因此,org.apache.catalinaorg.apache.catalina.realm 的父级和 org.apache.catalina.core .

执行代码代码必须为demand a logger为了让它存在。 简单地在属性文件中添加行不会创建记录器。如果创建了它们,它们将只是 garbage collected。反正。这意味着假设您有一个记录器树 A <- B <- C .您要为 B 设置级别因此所有B children 所以你加A.B.level属性文件中的行。但是,在运行时,需要的记录器是 AC

所以你需要处理的是"" <- A <- A.B.C当你期待 "" <- A <- A.B <- A.B.C

综上所述,我认为您的记录器在运行时看起来像:

"" <- org.apache.catalina <- org.apache.catalina.realm.RealmBase并且没有 Tomcat 代码创建一个名为 org.apache.catalina.realm 的实际记录器.

可以通过连接JConsole来验证运行 JVM 并检查 MBean 选项卡并列出记录器名称。在 Tomcat 上这将不起作用,因为返回的记录器取决于调用类加载器。

要解决此问题,您可以使用 config要求记录器并将其保存在内存中的选项。您只需在 system class path 上的自定义代码上安装它.

否则您必须在属性文件中指定所有已知的子记录器名称,这可能会很冗长。

First idea: If we look at the CSS specifity we know that .mydiv{ color:red} is not as specific as div.mydiv{color: green} so a div.mydiv contains text in red? Inheriance means if not specified what is anti-inheritance.

与 CSS 不同,JUL 有一个运行时记录器树和一个属性文件。当执行代码需要记录器时,运行时记录器树会动态调整。只有在代码需要记录器时才会使用这些属性。在属性文件中指定记录器名称并不意味着什么,除非记录器是由代码创建的。这可以更改记录器的父级,从而更改级别。试一试:

package so;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.Properties;
import java.util.logging.Level;
import java.util.logging.LogManager;
import java.util.logging.Logger;

public class TheMissingParent {

private static final Logger[] LAZY_ONE;
static {
LAZY_ONE = new Logger[] { Logger.getLogger("org.apache.catalina"),
Logger.getLogger("org.apache.catalina.realm.RealmBase") };
}

private static volatile Logger[] LAZY_TWO;

public static void main(String[] args) {
loadProperties();
printAncestors(LAZY_ONE);
findlLongLostParents();
System.out.println("====");
printAncestors(LAZY_ONE);
}

private static void loadProperties() {
Properties props = new Properties();
props.put("org.apache.catalina.realm.level", "FINER");

try(ByteArrayOutputStream out = new ByteArrayOutputStream()) {
props.store(out, "");
LogManager.getLogManager().readConfiguration(new ByteArrayInputStream(out.toByteArray()));
} catch (IOException ioe) {
throw new AssertionError(ioe);
}
}

private static void findlLongLostParents() {
LAZY_TWO = new Logger[] {Logger.getLogger("org.apache.catalina.realm") };
}

private static void printAncestors(Logger[] loggers) {
// System.out.println(loggers.toString());
for (Logger l : loggers) {
printAncestors(l);
System.out.println();
}
}

private static void printAncestors(Logger l) {
if (l != null) {
printAncestors(l.getParent());
System.out.print("<-");
String name = l.getName();
if (name != null && name.isEmpty()) {
System.out.append("\"\"");
} else {
System.out.append(name);
}

for(Logger p = l; p != null; p = p.getParent()) {
Level lvl = p.getLevel();
if (lvl != null) {
System.out.append('{').append(lvl.getName()).append('}');
break;
}
}
}
}
}

这将输出:

<-""{INFO}<-org.apache.catalina{INFO}
<-""{INFO}<-org.apache.catalina{INFO}<-org.apache.catalina.realm.RealmBase{INFO}
====
<-""{INFO}<-org.apache.catalina{INFO}
<-""{INFO}<-org.apache.catalina{INFO}<-org.apache.catalina.realm{FINER}<-org.apache.catalina.realm.RealmBase{FINER}

这是核心问题。如果 Tomcat(或某些自定义代码)从不要求 org.apache.catalina.realm logger 属性文件中的那一行只是死代码。

Second, if you say so, noone specified to org.apache.catalina nor org.apache nor org nor `` to be level INFO, so where would the value INFO came from?

描述了这种行为 in the LoggerManager class level docs :

If neither of these properties is defined then, as described above, the LogManager will read its initial configuration from a properties file "lib/logging.properties" in the JRE directory.

根记录器命名为空字符串""是所有记录器的父级。始终创建根记录器。

关于Tomcat 日志记录困惑,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50172433/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com