您现在的位置是:首页 > 经典句子

【JAVA日志框架】JUL,JDK原生日志框架详解。

作者:利杜鹃时间:2024-03-25 18:54:14分类:经典句子

简介  文章浏览阅读3.4k次,点赞73次,收藏68次。Java日志体系混乱?系列文章第一篇,五分钟,快速掌握JDK原生日志框架——JUL。_jul jdk

点击全文阅读

前言

Java日志体系混乱?Java日志框架系列,清晰简洁整理好整个Java的日志框架体系。第一篇,JDK原生日志框架——JUL。

目录

1.概述

2.日志级别

3.配置

4.继承关系


1.概述

日志框架的核心问题:

日志是用来记录应用的一些运行信息的。假设没有日志框架,我们要在应用里手动实现日志相关功能,我们需要关注些什么?其实仔细想想无非两点:

记录哪些信息?

记录到哪里去?

当然作为日志框架来说,为了方便使用,它还要关注一点就是:

如何进行方便的配置

java日志体系中是先有的log4j,后面才有了JDK自带的jul,两者是两套体系,互不兼容。但其实本质上jul就是抄的log4j,其架构上都是一模一样的。以上三点核心问题,我们看作为日志框架的开山鼻祖的log4j是怎样解决的:

log4j给出的答案是:

记录哪些信息——日志级别(level)

记录到哪里去——提供不同的输出方式(appender),文件、控制台、其它等等

如何进行方便的配置——除硬编码外,提供配置文件

jul是一模一样的,其只是把appender改成了handler而已。

2.日志级别

package com.eryi;import com.sun.scenario.effect.impl.sw.sse.SSEBlend_SRC_OUTPeer;import java.util.logging.Level;import java.util.logging.Logger;public class Test {    @org.junit.Test    public void test1() {    //级别由低到高,默认输出info以上级别        Logger logger = Logger.getLogger("abc");        logger.log(Level.FINEST,"FINEST level");        logger.log(Level.FINER,"FINER level");        logger.log(Level.FINE,"FINE level");        logger.log(Level.CONFIG,"CONFIG level");        logger.log(Level.INFO,"INFO level");        logger.log(Level.WARNING,"WARNING level");        logger.log(Level.SEVERE,"SEVERE level");        logger.log(Level.FINEST,"FINEST level");        System.out.println("hello");    }}

日志为什么是红色的?因为底层调用了system.erro,所以会输出的字体是红色的。

3.配置

可以用代码的方式对JUL进行配置:

public static void main(String[] args) {        // 获取根记录器        Logger rootLogger = Logger.getLogger("");        // 移除默认处理器        rootLogger.setUseParentHandlers(false);        // 创建控制台处理器        ConsoleHandler consoleHandler = new ConsoleHandler();                // 设置级别        consoleHandler.setLevel(Level.INFO);        // 设置自定义格式器        consoleHandler.setFormatter(new SimpleFormatter());        // 设置自定义过滤器        consoleHandler.setFilter(new CustomFilter());        // 将处理器添加到根记录器        rootLogger.addHandler(consoleHandler);        // 输出日志        Logger logger = Logger.getLogger(JULConfigExample.class.getName());        logger.severe("Severe message");        logger.warning("Warning message");        logger.info("Info message");        logger.config("Config message");        logger.fine("Fine message");        logger.finer("Finer message");        logger.finest("Finest message");    }    // 自定义格式器    static class SimpleFormatter extends Formatter {        @Override        public String format(LogRecord record) {            return "[" + record.getLevel() + "] - " + record.getMessage() + "\n";        }    }    // 自定义过滤器    static class CustomFilter implements Filter {        @Override        public boolean isLoggable(LogRecord record) {            // 在这里可以添加自定义的过滤逻辑            return record.getLevel().intValue() >= Level.INFO.intValue();        }    }

当然更合理、更方便的方式肯定是配置文件。配置文件的示例模板在jre/lib目录下:

把它拷贝过来改一下:

#默认配置handlers= java.util.logging.ConsoleHandler.level= FINEST#file hander配置java.util.logging.FileHandler.pattern = %h/java%u.logjava.util.logging.FileHandler.limit = 50000java.util.logging.FileHandler.count = 1java.util.logging.FileHandler.formatter = java.util.logging.XMLFormatter#console handler配置java.util.logging.ConsoleHandler.level = FINESTjava.util.logging.ConsoleHandler.formatter = java.util.logging.SimpleFormatter# 具体包路径下的日志级别com.eryi.level = FINEST

解读一下配置:

默认配置:

handlers: 指定默认的处理器,这里是java.util.logging.ConsoleHandler,表示使用控制台输出。

.level: 设置默认的日志级别,这里是FINEST,表示记录最详细的日志。

File Handler配置:

java.util.logging.FileHandler.pattern: 设置文件处理器的日志文件的命名模式,%h表示用户主目录,%u表示一个唯一的数值,%g表示循环计数器。这里是 %h/java%u.log

java.util.logging.FileHandler.limit: 设置文件处理器的每个日志文件的大小限制,这里是 50000 字节。

java.util.logging.FileHandler.count: 设置文件处理器循环的文件数,这里是 1 个。

java.util.logging.FileHandler.formatter: 设置文件处理器的日志格式,这里是 java.util.logging.XMLFormatter,表示使用 XML 格式。

Console Handler配置:

java.util.logging.ConsoleHandler.level: 设置控制台处理器的日志级别,这里是 FINEST

java.util.logging.ConsoleHandler.formatter: 设置控制台处理器的日志格式,这里是 java.util.logging.SimpleFormatter,表示使用简单格式。

具体包路径下的日志级别:

com.eryi.level: 设置特定包路径下的日志级别,这里是 FINEST,表示 com.eryi 包下的日志级别为最详细。

这里要说一下为什么有了.level的配置之后还推出了专门指定某个包路径下日志级别的配置。是因为logger之间是有父子关系的。.level会对根logger生效,其余logger是继承自根logger的,但肯定工程上不一定是全局日志级别都是一致的,会有需求需要单独定制某一个或者某一些的logger的日志级别。

使用效果如下:

4.继承关系

logger之间存在父子关系。

root logger是最顶层的父logger:

Logger a = Logger.getLogger("a");Logger b = Logger.getLogger("b");System.out.println(a.getParent());System.out.println(b.getParent());

通过父名·子名定义父子关系:

Logger a = Logger.getLogger("a");Logger b = Logger.getLogger("a.b");System.out.println(a.getParent());System.out.println(b.getParent()==a);

为什么在设计的时候会存在父子关系?

Java Util Logging(JUL)的Logger之间存在父子关系,这是为了实现日志记录的层次结构和更方便的配置管理。这种父子关系的设计使得日志记录器可以继承和继承配置。

点击全文阅读

郑重声明:

本站所有活动均为互联网所得,如有侵权请联系本站删除处理

我来说两句