JDK Logging
package org.example;
import java.io.NotSerializableException;
import java.util.logging.LogManager;
import java.util.logging.Logger;
import java.util.logging.Level;
public class Main {
private static Logger LOGGER;
static {
LOGGER = Logger.getLogger(Main.class.getName());
}
public static void main(final String[] args) {
LOGGER.info("an info msg");
LOGGER.warning("a warning msg");
LOGGER.severe("a severe msg");
LOGGER.log(Level.INFO, "test1: a info msg", new NotSerializableException());
LOGGER.log(Level.WARNING, "test1: a warning msg", new NotSerializableException());
LOGGER.log(Level.SEVERE, "test1: a severe msg", new NotSerializableException());
}
}
关键组件
- LogManager
JVM内logger的配置文件读取,管理,生成、获取等操作都依赖于它
LogManager$LoggerContext有private final Hashtable<String,LoggerWeakRef> namedLoggers = new Hashtable<>();存logger
- Handler
控制日志输出,JDK自带ConsoleHanlder把输出流重定向到System.err,调用Logger的方法进行输出时都会调用Handler的publish方法,每个logger可有多个handler
- Formatter
时间格式?线程名?i18n等
- Log Level
从高到低为OFF—>SEVERE—>WARNING—>INFO—>CONFIG—>FINE—>FINER—>FINEST—>ALL
常用Logger.getLogger();获得一个logger,然后用logger做日志输出
handler也有level
所有匿名logger都会把空的root logger作为parent
JDK默认logging配置 $JAVA_HOME/jre/lib/logging.properties
-Djava.util.logging.config.file
指定配置文件
-Djava.util.logging.manager
指定自定义的 LogManager 实现类,默认java.util.logging.LogManager
LoggerManager初始化中会添加两个logger,名称为””的root logger,另一个是名称为global的全局logger,级别是INFO
useParentHandlers属性控制日志不进行往上层logger传递
Tomcat log
-Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager
-Djava.util.logging.config.file=xx/conf/logging.properties
org.apache.catalina.startup.Bootstrap
-->private static final Log log = LogFactory.getLog(Bootstrap.class);
-->private static final LogFactory singleton = new LogFactory();
---->org.apache.juli.logging.LogFactory::getLog
------>org.apache.juli.logging.LogFactory::getInstance
-------->org.apache.juli.logging.DirectJDKLog::getInstance
---------->java.util.logging.Logger::getLogger(最终调用JDK中的日志器)
---------->java.util.logging.Logger::demandLogger
------------>java.util.logging.LogManager::getLogManager 得到这个全局日志管理器
------------>java.util.logging.LogManager::ensureLogManagerInitialized
------------>java.util.logging.LogManager::readPrimordialConfiguration
-------------->org.apache.juli.ClassLoaderLogManager::readConfiguration //读取配置
catalina、localhost、manager、admin、host-manager
从 7.0.54 开始,catalina.out 被替换为按日期分割的日志文件,格式为 catalina.YYYY-MM-DD.log
使用slf4j+logback
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>jul-to-slf4j</artifactId>
</dependency>
LogManager.getLogManager().reset();
SLF4JBridgeHandler.install();