java - 无法让Tomcat的java.util日志记录与特定类一起使用

标签 java tomcat java.util.logging

我正在使用在Tomcat 8.0容器中运行的Liferay 7.0。

在启动期间,我正在为Liferay挂钩注册特定的类。此类必须在Tomcat的系统类路径中。因此.jar文件位于CATALINA_BASE/lib/ext

我需要该类的日志输出,但是我无法弄清楚如何通过Tomcat配置文件正确配置Java的日志。

我对Tomcat的logging.properties进行了如下修改(粗体字更改)

首先,我定义了一个附加处理程序:

handlers = 1catalina.org.apache.juli.AsyncFileHandler, 2myhandler.org.apache.juli.AsyncFileHandler, java.util.logging.ConsoleHandler
.handlers = 1catalina.org.apache.juli.AsyncFileHandler, java.util.logging.ConsoleHandler

The handler is configured as follows:

2myhandler.org.apache.juli.AsyncFileHandler.level = FINE
2myhandler.org.apache.juli.AsyncFileHandler.directory = ${catalina.base}/logs
2myhandler.org.apache.juli.AsyncFileHandler.prefix =  my-class.
2myhandler.org.apache.juli.AsyncFileHandler.formatter = java.util.logging.SimpleFormatter
2myhandler.java.util.logging.SimpleFormatter.format=%1$tF %1$tT %4$s [%2$s] %5$s %6$s %n

And the link between the handler and my class is done like this:

com.mypackage.MyClass.level = ALL
com.mypackage.MyClass.handlers = 2myhandler.org.apache.juli.AsyncFileHandler
com.mypackage.MyClass.useParentHandlers=false

My class uses

private static final LOGGER = Logger.getLogger("com.mypackage.MyClass");


Tomcat启动时,将创建文件my-hook.log(文件名中带有时间戳)。

但是我的日志消息都没有出现在文件中。

在代码中我有构造函数中的以下内容:

logger.log(Level.INFO, "MyClass initialized");
System.out.println("*** MyClass loaded ***");


启动Liferay时,我可以在控制台窗口中看到*** MyClass loaded ***消息,但是日志消息未写入(现有)文件中。

我在这里想念什么?

请注意,我无法切换到Log4J(在Liferay Portlet中使用),因为这会在Liferay提供的Log4j和lib/ext中的Log4j之间产生类加载器冲突。

最佳答案

因此.jar文件位于CATALINA_BASE / lib / ext中


在安装Tomcat 8时,我可以看到CATALINA_BASE / lib,但没有名为ext的子目录。我想您应该确保common.loader的系统属性在路径中显示ext。在我的机器上没有扩展路径:

common.loader="${catalina.base}/lib","${catalina.base}/lib/*.jar","${catalina.home}/lib","${catalina.home}/lib/*.jar"



当我启动Liferay时,我可以在控制台窗口中看到* MyClass loading *消息,但是日志消息未写入(现有)文件中。


那么,类加载器便可以找到您的类,并且因为文件存在而创建了处理程序。修改MyClass以包括来自DebugLogging的代码。包括辅助函数,并将main方法的主体复制到MyClass构造函数中。这将跟踪记录器树的外观。在答案中包括输出。

package com.mypackage;

import java.io.PrintStream;
import java.util.Enumeration;
import java.util.logging.Handler;
import java.util.logging.Level;
import java.util.logging.LogManager;
import java.util.logging.Logger;

public class MyClass {

    private static final String CLASS_NAME = MyClass.class.getName();
    private static final Logger logger = Logger.getLogger(CLASS_NAME);


    public static void main(String[] args) {
        new MyClass();
    }

    public MyClass() {
        logger.log(Level.INFO, "MyClass initialized");
        System.out.println("*** MyClass loaded ***");
        logger.log(Level.FINEST, "Finest");
        logger.log(Level.FINER, "FINER");
        logger.log(Level.FINE, "FINE");
        logger.log(Level.CONFIG, "CONFIG");
        logger.log(Level.INFO, "INFO");
        logger.log(Level.WARNING, "WARNING");
        logger.log(Level.SEVERE, "SEVERE");
        logger.finest("Finest Log");
        logger.finer("Finer Log");
        logger.fine("Fine Log");
        logger.config("Config Log");
        logger.info("Info Log");
        logger.warning("Warning Log");
        logger.severe("Severe Log");
        printConfig(System.out);
    }

    private static void printConfig(PrintStream ps) {
        LogManager lm = LogManager.getLogManager();
        ps.append("LogManager=").append(lm.getClass().getName());
        ps.append("@");
        printLoader(lm, ps);
        ps.println();
        synchronized (lm) {
            Enumeration<String> e = lm.getLoggerNames();
            while (e.hasMoreElements()) {
                Logger l = lm.getLogger(e.nextElement());
                if (l != null) {
                    print(l, ps);
                }
            }
        }
    }

    private static void print(Logger l, PrintStream ps) {
        ps.append("scn=").append(l.getClass().getSimpleName());
        ps.append("@");
        printLoader(l, ps);
        ps.append(", n=").append(String.valueOf(l.getName()));
        ps.append(", uph=").append(String.valueOf(l.getUseParentHandlers()));

        ps.append(", l=").append(String.valueOf(l.getLevel()));
        ps.append(", fl=").println(String.valueOf(l.getFilter()));
        for (Handler h : l.getHandlers()) {
            ps.append("\t").append(l.getName()).append("->");
            ps.append(h.getClass().getName());
            ps.append("@");
            printLoader(h, ps);
            ps.append(", h=")
                    .append(String.valueOf(h.getLevel())).append(", fl=")
                    .append(String.valueOf(h.getFilter())).println();
        }
    }

    private static void printLoader(Object o, PrintStream ps) {
        if (o != null) {
            Object cl = o.getClass().getClassLoader();
            if (cl != null) {
                ps.append(cl.getClass().getSimpleName());
            } else {
                ps.append("null");
            }
        } else {
            ps.append("null");
        }
    }
}


您的处理程序在handlers中声明。这样就足以使用处理程序。文件的存在表明处理程序已构建。

在我的机器上,调试输出显示处理程序已设置:

scn=Logger@null, n=com.mypackage.MyClass, uph=false, l=ALL, fl=null
com.mypackage.MyClass->org.apache.juli.AsyncFileHandler@AppClassLoader, h=FINE, fl=null


文件日志包含:

2020-02-15 11:48:55 INFO [com.mypackage.MyClass <init>] MyClass initialized  
2020-02-15 11:48:55 FINE [com.mypackage.MyClass <init>] FINE  
2020-02-15 11:48:55 CONFIG [com.mypackage.MyClass <init>] CONFIG  
2020-02-15 11:48:55 INFO [com.mypackage.MyClass <init>] INFO  
2020-02-15 11:48:55 WARNING [com.mypackage.MyClass <init>] WARNING  
2020-02-15 11:48:55 SEVERE [com.mypackage.MyClass <init>] SEVERE  
2020-02-15 11:48:55 FINE [com.mypackage.MyClass <init>] Fine Log  
2020-02-15 11:48:55 CONFIG [com.mypackage.MyClass <init>] Config Log  
2020-02-15 11:48:55 INFO [com.mypackage.MyClass <init>] Info Log  
2020-02-15 11:48:55 WARNING [com.mypackage.MyClass <init>] Warning Log  
2020-02-15 11:48:55 SEVERE [com.mypackage.MyClass <init>] Severe Log  


根据文档,您可以为Tomcat指定系统属性org.apache.juli.ClassLoaderLogManager.debug=true,该属性将配置信息发送到System.err。这可能会帮助您进一步排除故障。

关于java - 无法让Tomcat的java.util日志记录与特定类一起使用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60209810/

相关文章:

java - 当 Java、C++ 或任何面向对象语言中的属性是动态和可变的时,如何创建一个类?

tomcat - tomcat的session指的是什么?

java - logger java 不通过 System.out

java - 无法找到 c3p0 日志消息

java - Jsp/MySQL- 将 SELECT 查询的输出存储到字符串中?

java - 如何在 JavaFX 8 WebView 中设置/记住滚动条拇指位置?

java - 在 Cassandra 中实现 FIFO 读取

tomcat - 对 Tomcat 的 "temp"和 "work"目录的澄清

java - 在tomcat启动时调用REST服务

java - java.util.logging.Logger类的info()方法是I/O操作吗?