JUL原理解析
- JUL示意图
- 通讲:
JUL架构如图,
最左侧是一个外部应用,外部应用如果需要日志记录就需要调用Logger对象,
Logger对象的初始化需要调用LogManager对象,它去加载配置文件。
然后用户便可以通过Logger对象设置日志的级别(Level)和消息内容(LogRecord),
通过过滤器(Filter)进行细粒度控制,
然后交由Handler对象决定日志输出的位置,
通过Formatter对象格式化消息输出内容,
最终实现输出。
- 各部分解释:
- 初始化LogManager
- LogManager加载logging.properties配置
- 添加Logger到LogManager
- 从单例LogManager获取Logger
- 设置级别Level,并指定日志记录LogRecord
- Filter提供了日志级别之外更细粒度的控制
- Handler是用来处理日志输出位置
- Formatter是用来格式化LogRecord的
- 初始化LogManager
-
代码部分(属赘余部分,留给我自己看的hh)
-
//学习自黑马程序员 package com.bohr.exercise.logLearning; import org.junit.Test; import java.io.*; import java.util.logging.*; public class JULtest { //快速入门 @Test public void testQuick(){ //获取日志记录器对象//JUL为自带,无需导入第三方包 //logger name 一般为包名或者类名 Logger logger = Logger.getLogger("com.bohr.exercise.logLearning.JULtest"); //日志记录输出 logger.info("hello,JUL"); //通用方法进行日志记录 logger.log(Level.INFO,"level_info_msg1"); //通过占位符方式输出变量值 String name = "itCast"; Integer age = 13; //注意“{0},{1}”占位符的格式 logger.log(Level.INFO,"用户信息:{0},{1}",new Object[]{name,age}); } //日志输出_控制台 public static void printLog(Logger logger){ //日志记录输出 logger.severe("severe"); logger.warning("warning"); logger.info("info"); //默认日志输出级别 logger.config("config"); logger.fine("fine"); logger.finer("finer"); logger.finest("finest"); } //日志级别 @Test public void testLogLevel(){ //获取日志记录器对象 Logger logger = Logger.getLogger("com.bohr.exercise.logLearning.JULtest"); //日志记录输出 logger.severe("severe"); logger.warning("warning"); logger.info("info"); //默认日志输出级别 logger.config("config"); logger.fine("fine"); logger.finer("finer"); logger.finest("finest"); } @Test //logger -> handler -> formatter //需要关闭父handler,new新的handler,formatter并关联,再配置日志的具体级别 //filehandler默认全部输出;consolehandler默认info级别 public void testLogLevelConfig() throws IOException { //获取日志记录器对象 Logger logger = Logger.getLogger("com.bohr.exercise.logLearning.JULtest"); //关闭系统默认配置 logger.setUseParentHandlers(false); //自定义配置日志级别 //创建ConsoleHandler,控制台 ConsoleHandler consoleHandler = new ConsoleHandler(); //创建简单格式转换对象 SimpleFormatter simpleFormatter = new SimpleFormatter(); //进行关联 consoleHandler.setFormatter(simpleFormatter); logger.addHandler(consoleHandler); //配置日志具体级别 logger.setLevel(Level.ALL); consoleHandler.setLevel(Level.ALL); //创建FileHandler 文件输出 //这里的pattern写文件路径(已存在),路径推荐从src开始写 FileHandler fileHandler = new FileHandler("src/logs/jul.log"); //进行关联 fileHandler.setFormatter(simpleFormatter); logger.addHandler(fileHandler); //配置日志具体级别 fileHandler.setLevel(Level.INFO); //日志记录输出 logger.severe("severe"); logger.warning("warning"); logger.info("info"); //默认日志输出级别 logger.config("config"); logger.fine("fine"); logger.finer("finer"); logger.finest("finest"); } //Logger 对象的父子级别,子logger继承父logger @Test public void testLogParent(){ //父子关系根据name,类似包结构 Logger loggerSon = Logger.getLogger("com.bohr"); Logger loggerPar = Logger.getLogger("com"); assert loggerPar == loggerSon.getParent(); //所欲日志记录器的顶级父元素:LogManager$RootLogger;name:"" (空字符串) System.out.println("loggerPar:" + loggerPar.getParent() + ";name:" + loggerPar.getParent().getName()); //这么输出,是info级别,看的是其父logger的配置,若禁用,则看其自己的配置 printLog(loggerSon); //改成自定义级别 //关闭默认配置 loggerPar.setUseParentHandlers(false); //new consoleHandler,formatter 并关联 ConsoleHandler consoleHandler = new ConsoleHandler(); SimpleFormatter simpleFormatter = new SimpleFormatter(); consoleHandler.setFormatter(simpleFormatter); loggerPar.addHandler(consoleHandler); //设置级别 loggerPar.setLevel(Level.ALL); consoleHandler.setLevel(Level.ALL); //再尝试打印 System.out.println("===================="); printLog(loggerSon); } //System.out.println(JULtest.class.getClassLoader().getResource("")); //加载自定义配置文件 @Test public void testLogProperties() throws IOException { //通过类加载器读取配置文件 InputStream ins = JULtest.class.getClassLoader() .getResourceAsStream("logging.properties"); System.out.println(JULtest.class.getClassLoader().getResource("")); //创建LogManager LogManager logManager = LogManager.getLogManager(); //通过LogManager加载配置文件 logManager.readConfiguration(ins); //创建日志记录器 Logger logger = Logger.getLogger("com"); printLog(logger); } }



