Java日志框架-JUL

JUL全称Java util logging

入门案例

先来看着入门案例,直接创建logger对象,然后传入日志级别和打印的信息,就能在控制台输出信息。

 可以看出只输出了部分的信息,其实默认的日志控制器是有一个默认的日志级别的,默认就是info 所以最多优先级比info低的都不能输出。

 

    @Test
    public  void testQuick() {
        System.out.println("hello");
        //传入唯一标识,一般为当前的类名
       Logger logger=  Logger.getLogger("com.itheima.julTest");
       
        logger.severe("severe logger message");//logger.log(Level.severe,"logger message");
        logger.warning("warning logger message");
        logger.info("info logger message");  //默认日志级别
        logger.config("config logger message");
        logger.fine("fine logger message");
        logger.finer("finer logger message");
        logger.finest("finest logger message");
    }

自定义日志级别

设置handler,设置handler和logger的级别

  • Handler:日志处理器,每个Logger会关联持有多个Handler,Logger会把日志交给Handler进行处理,由Handler负责日志记录。Handler在这里是一个抽象,其具体实现决定了日志输出的位置,比如控制台,文件等

也就是说,通过使用不同的handler可以将日志输出到文件或者控制台。

下面这个地方:
            //logger设置不使用父logger的handler,不然日志会重复记录。此处后面会讲
            logger.setUseParentHandlers(false);

如果不设置,将会输出两边日志信息

 @Test
    public  void loggerLevel() {

            //创建日志记录器,传入参数是日志记录器的名称
            Logger logger = Logger.getLogger("com.itheima");

            //创建一个输出到控制台的handler
            ConsoleHandler consoleHandler = new ConsoleHandler();
            //设置handler的日志级别为ALL,输出全部日志。
            consoleHandler.setLevel(Level.ALL);

            //把handler添加到logger中
            logger.addHandler(consoleHandler);
            //logger也设置日志级别为ALL
            logger.setLevel(Level.ALL);

            //logger设置不使用父logger的handler,不然日志会重复记录。此处后面会讲
            logger.setUseParentHandlers(false);
            //记录severe级别信息
            logger.severe("severe信息");
            //记录warning级别信息
            logger.warning("warning信息");
            logger.info("info信息");
            logger.config("config信息");
            logger.fine("fine信息");
            logger.finer("finer信息");
            logger.finest("finest信息");
        }

父子关系

一开始以为是继承,后来发现并不是,只是通过设置可以复用一些配置

默认父子关系通过名称的层级关系来确定的。层级关系用 . 号分开。

也可以通过手动设置。

JUL在初始化时会创建一个顶层的RootLogger作为所有Logger的父Logger。

下面的代码中就是:rootlogger->logger1->logger2logger3.

 @Test
    public void testLoggerParent(){
        //创建一个名称为aaa的logger
        Logger logger1 = Logger.getLogger("aaa");

        //创建一个名称为aaa.bbb的logger
        Logger logger2 = Logger.getLogger("aaa.bbb");

        //创建一个名称为aaa.bbb.ccc的logger
        Logger logger3 = Logger.getLogger("aaa.bbb.ccc");

        //此时logger3的父Logger是logger2, logger2的父logger是logger1

        //判断logger3的父Logger是不是logger2
        System.out.println(logger3.getParent() == logger2);

        //判断logger2的父logger是不是logger1
        System.out.println(logger2.getParent() == logger1);

        //logger1的父节点是顶级Logger RootLogger
        System.out.println("logger1的父logger是 " + logger1.getParent());

        //RootLogger的父Logger
        System.out.println("RootLogger的父Logger是 " + logger1.getParent().getParent());

        //手动设置父Logger
        logger3.setParent(logger1);
        //判断设置是否成功
        System.out.println(logger3.getParent() == logger1);

    }

子Logger默认会使用父Logger的Handler对象

如果使用addHandler添加新的handler,也会使用新添加的handler再输出一次
 

    @Test
    public void testUserParentHandler()  {
        //创建一个名为aaa的logger
        Logger logger1 = Logger.getLogger("aaa");
        //创建一个名为aaa.bbb的logger,父Logger是handler
        Logger logger2 = Logger.getLogger("aaa.bbb");

        //创建一个handler
        ConsoleHandler consoleHandler  = new ConsoleHandler();

        //把handler添加到logger1和logger2中。
        logger1.addHandler(consoleHandler);
        logger2.addHandler(consoleHandler);

        //使用logger进行日志输出

        //记录severe级别信息
        logger2.severe("severe信息");
        //记录warning级别信息
        logger2.warning("warning信息");
        logger2.info("info信息");
        logger2.config("config信息");
        logger2.fine("fine信息");
        logger2.finer("finer信息");
        logger2.finest("finest信息");

    }

分析:
每个级别的日志信息输出了三次,因为logger2使用了父Logger logger1 ,父Logger的父Logger RootLogger、还有自身的handler共三个handler,所以日志会输出三倍。

 

使用logger2.setUseParentHandlers(false); 设置不使用父Logger的Handler。

FileHandler和SimpleFormatter

前面说到了通过设置handler可以将日志输出到文件,这里就测试一下

 

    @Test
    public void testFileHandler(){
        Logger logger = Logger.getLogger("juldemo.JULDemo");
        logger.setLevel(Level.ALL);
        try {
            //创建一个输出到文件的handler,第一个参数是生成文件名的pattern,第二个参数是是否已追加的方式输出到文件,默认false
            FileHandler fileHandler = new FileHandler("D:\\project\\idea\\log_learning\\jul_demo\\logs\\java%u.log",true);
            //创建一个SimpleFormatter,输出格式
            SimpleFormatter formatter = new SimpleFormatter();
            //设置formatter
            fileHandler.setFormatter(formatter);
            //设置日志级别
            fileHandler.setLevel(Level.ALL);
            //把handler添加到logger
            logger.addHandler(fileHandler);
            //设置不使用父Logger的handler
            logger.setUseParentHandlers(false);
            logger.severe("severe信息");
            //记录warning级别信息
            logger.warning("warning信息");
            logger.info("info信息");
            logger.config("config信息");
            logger.fine("fine信息");
            logger.finer("finer信息");
            logger.finest("finest信息");
        } catch (IOException e) {
            e.printStackTrace();
        }

    }

通过配置文件配置


#配置RootLogger的Handler,有java.util.logging.ConsoleHandler,java.util.logging.FileHandler
handlers= java.util.logging.ConsoleHandler,java.util.logging.FileHandler

#配置RootLogger的日志级别ALL
.level= ALL

java.util.logging.FileHandler.pattern = D:\\project\\idea\\log_learning\\jul_demo\\logs\\java%u.log
#默认一个文件最多50000条日志记录
java.util.logging.FileHandler.limit = 50000
#设置FileHandle的日志级别为ALL
java.util.logging.FileHandler.level= ALL

#配置生成一个文件
java.util.logging.FileHandler.count = 1
#配置使用SimpleFormatter格式器
java.util.logging.FileHandler.formatter = java.util.logging.SimpleFormatter
#配置追加模式
java.util.logging.FileHandler.append=true

#ConsoleHandler的日志级别默认是INFO
java.util.logging.ConsoleHandler.level = ALL
#ConsoleHandler的默认格式化器时SimpleFormatter
java.util.logging.ConsoleHandler.formatter = java.util.logging.SimpleFormatter



#设置日志格式
java.util.logging.SimpleFormatter.format= %1$tc %2$s%n%4$s: %5$s%6$s%n


    @Test
    public void testCustomConfig(){
        LogManager logManager = LogManager.getLogManager();
        try {
            logManager.readConfiguration(this.getClass().getClassLoader().getResourceAsStream("logging.properties"));
            Logger logger = Logger.getLogger("juldemo.JULDemo");
            logger.severe("severe信息");
            //记录warning级别信息
            logger.warning("warning信息");
            logger.info("info信息");
            logger.config("config信息");
            logger.fine("fine信息");
            logger.finer("finer信息");
            logger.finest("finest信息");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/80747.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Linux命令200例:nc非常有用的网络工具(常用)

🏆作者简介,黑夜开发者,全栈领域新星创作者✌。CSDN专家博主,阿里云社区专家博主,2023年6月csdn上海赛道top4。 🏆数年电商行业从业经验,历任核心研发工程师,项目技术负责人。 &…

PHP-MD5注入

0x00 前言 有些零散的知识未曾关注过,偶然捡起反而更加欢喜。 0x01 md5 注入绕过 md5函数有两个参数,第一个参数是要进行md5的值,第二个值默认为false,如果为true则返回16位原始二进制格式的字符串。意思就是会将md5后的结果当…

MVCC 是否彻底解决了事物的隔离性 ?

目录 1. 什么是 MVCC 2. MVCC 是否彻底解决了事物的隔离性 3. MySQL 中如何实现共享锁和排他锁 4. MySQL 中如何实现悲观锁和乐观锁 1. 什么是 MVCC MVCC(Multi-Version Concurrency Control,多版本并发控制)是一种多版本并发控制机制&…

vue项目使用qrcodejs2遇到Cannot read property ‘appendChild‘ of null

这个问题是节点还没创建渲染完就读取节点,这个时候应该先让节点渲染完成在生成,解决方法有以下两种 1、使用$nextTick()方法进行,这个方法是用来在节点创建渲染完成后进行的操作 that.$nextTick(() > {let qrcode …

Java基础知识小结(内部类、BigInteger、枚举、接口、重写重载和序列化)

一、Java内部类 1、内部类 在Java中,也可以嵌套类(类中的类)。嵌套类的目的是将属于同一类的类分组,这使代码更具可读性和可维护性。 要访问内部类,请创建外部类的对象,然后创建内部类的对象:…

SpringBoot中优雅的实现隐私数据脱敏(提供Gitee源码)

前言:在实际项目开发中,可能会对一些用户的隐私信息进行脱敏操作,传统的方式很多都是用replace方法进行手动替换,这样会由很多冗余的代码并且后续也不好维护,本期就讲解一下如何在SpringBoot中优雅的通过序列化的方式去…

【框架类】—MVVM框架

一、MVVM框架有哪些 Vue.jsReact.jsAngular.js 二、对MVVM的认识 1. MVC是什么 全称 Model View Controller, 它采用模型(Model)-视图(View)-控制器(controller)的方法把业务逻辑、数据与界面显示分离 2. MVVM的定义 MVVM是一种软件架构模式,它代表了模型 --视…

深入理解JVM——垃圾回收与内存分配机制详细讲解

所谓垃圾回收,也就是要回收已经“死了”的对象。 那我们如何判断哪些对象“存活”,哪些已经“死去”呢? 一、判断对象已死 1、引用计数算法 给对象中添加一个引用计数器,每当有一个地方引用它时,计数器就加一&…

探索无限创造力的星辰大道,画出想象的浩瀚宇宙!-turtle

介绍 视频教程地址在此:https://www.bilibili.com/video/BV1Pm4y1H7Tb/ 大家好,欢迎来到本视频!今天,我们将一同探索Python编程世界中的一个有趣而创意的库——Turtle库。无需专业绘画技能,你就可以轻松地用代码绘制…

人工智能在网络安全中的作用:当前的局限性和未来的可能性

人工智能 (AI) 激发了网络安全行业的想象力,有可能彻底改变安全和 IT 团队处理网络危机、漏洞和勒索软件攻击的方式。 然而,对人工智能的能力和局限性的现实理解至关重要,并且存在许多挑战阻碍人工智能对网络安全产生直接的变革性影响。 在…

概述、搭建Redis服务器、部署LNP+Redis、创建Redis集群、连接集群、集群工作原理

Top NSD DBA DAY09 案例1:搭建redis服务器案例2:常用命令限案例3:部署LNPRedis案例4:创建redis集群 1 案例1:搭建redis服务器 1.1 具体要求如下 在主机redis64运行redis服务修改服务运行参数 ip 地址192.168.88.6…

在 ubuntu 18.04 上使用源码升级 OpenSSH_7.6p1到 OpenSSH_9.3p1

1、检查系统已安装的当前 SSH 版本 使用命令 ssh -V 查看当前 ssh 版本,输出如下: OpenSSH_7.6p1 Ubuntu-4ubuntu0.7, OpenSSL 1.0.2n 7 Dec 20172、安装依赖,依次执行以下命令 sudo apt update sudo apt install build-essential zlib1g…

[论文笔记]Glancing Transformer for Non-Autoregressive Neural Machine Translation

引言 这是论文Glancing Transformer for Non-Autoregressive Neural Machine Translation的笔记。 传统的非自回归文本生成速度较慢,因为需要给定之前的token来预测下一个token。但自回归模型虽然效率高,但性能没那么好。 这篇论文提出了Glancing Transformer,可以只需要一…

6.RocketMQ之索引文件ConsumeQueue

本文着重分析为consumequeue/topic/queueId目录下的索引文件。 1.ConsumeQueueStore public class ConsumeQueueStore {protected final ConcurrentMap<String>, ConcurrentMap<Integer>, ConsumeQueueInterface>> consumeQueueTable;public boolean load(…

Selenium 测试用例编写

编写Selenium测试用例就是模拟用户在浏览器上的一系列操作&#xff0c;通过脚本来完成自动化测试。 编写测试用例的优势&#xff1a; 开源&#xff0c;免费。 支持多种浏览器 IE&#xff0c;Firefox&#xff0c;Chrome&#xff0c;Safari。 支持多平台 Windows&#xff0c;Li…

Xxl-job安装部署以及SpringBoot集成Xxl-job使用

1、安装Xxl-job&#xff1a; 可以使用docker拉取镜像部署和源码编译两种方式&#xff0c;这里选择源码编译安装。 代码拉取地址&#xff1a; https://github.com/xuxueli/xxl-job/tree/2.1.2 官方开发文档&#xff1a; https://www.xuxueli.com/xxl-job/#%E3%80%8A%E5%88%…

Android5:活动生命周期

创建项目Stopwatch activity_main.xml <?xml version"1.0" encoding"utf-8"?> <LinearLayoutxmlns:android"http://schemas.android.com/apk/res/android"xmlns:tools"http://schemas.android.com/tools"android:layout_w…

ROS-PyQt小案例

前言&#xff1a;目前还在学习ROS无人机框架中&#xff0c;&#xff0c;&#xff0c; 更多更新文章详见我的个人博客主页【前往】 ROS与PyQt5结合的小demo&#xff0c;用于学习如何设计一个界面&#xff0c;并与ROS中的Service和Topic结合&#xff0c;从而控制多个小乌龟的运动…

设计HTML5表单

HTML5基于Web Forms 2.0标准对HTML4表单进行全面升级&#xff0c;在保持简便、易用的基础上&#xff0c;新增了很多控件和属性&#xff0c;从而减轻了开发人员的负担。表单为访问者提供了与网站进行互动的途径&#xff0c;完整的表单一般由控件和脚本两部分组成。 1、认识HTML…

ansible的playbook剧本

playbook剧本 PlayBook1.playbooks 本身由以下各部分组成2.示例&#xff1a;3.运行playbook补充参数&#xff1a; 4.定义、引用变量5.指定远程主机sudo切换用户6.when条件判断7.迭代8.Templates 模块1.先准备一个以 .j2 为后缀的 template 模板文件&#xff0c;设置引用的变量2…