Java学习路线:JUL日志系统(一)日志框架介绍
目录
打印日志
日志的级别
打印文件
日志过滤器
日志输出流程
首先,为什么要使用日志系统?
如果单纯地用System.out.println打印信息,如果项目比较大,存在大量的信息就会显得非常凌乱。
而且,当我们希望在debug的时候打印某些信息,而运行的时候不打印,使用直接输出的方法就行不通了。
因此,我们需要使用日志框架来规范日志的输出。
打印日志
JDK为我们提供了一个自带的日记框架,位于java.util.logging(JUL名称的来源)包下,可以使用此框架来实现日志的规范化打印:
public static void main(String[] args) {
//获取日志打印器Logger logger = Logger.getLogger(Main.class.getName());
//输出一个字符串信息logger.info("我是日志");
}
以上日志打印的结果为:
十一月 01, 2024 9:21:52 下午 com.test.Main main
信息: 我是日志
可以看到,日志打印是会比普通的print方法多出一些内容的
日志的级别
日志分为7个级别:
- SERVER(最高级别) :一般用于代表严重错误
- WARNING:一般用于表示某些警告,单不足以判断为错误
- INFO(默认级别):常规消息
- CONFIG
- FINE
- FINER
- FINEST(最低级别)
我们之前使用的代码:
logger.info("我是日志");
就是输出的INFO级别的日志
可以通过log方法来设定日志输出的级别:
public static void main(String[] args) {Logger logger = Logger.getLogger(Main.class.getName());
//server级别的错误可以传入异常logger.log(Level.SEVERE,"我是server日志",new IOException("IO错误"));logger.log(Level.WARNING,"我是warning日志");logger.log(Level.INFO,"我是info日志");logger.log(Level.CONFIG,"我是config日志");logger.log(Level.FINE,"我是fine日志");}
输出的结果为:
十一月 01, 2024 10:07:41 下午 com.test.Main main
严重: 我是server日志
java.io.IOException: IO错误
at com.test.Main.main(Main.java:13)十一月 01, 2024 10:07:41 下午 com.test.Main main
警告: 我是warning日志
十一月 01, 2024 10:07:41 下午 com.test.Main main
信息: 我是info日志
可以看到,server级别的错误可以传入异常类型,打印出的日志会明确得到异常的类型,但程序并不会因为这个传入的异常终止
另外,可以发现低于默认级别的日志没有输出,这是因为日志设定的输出等级就是输出默认级别以上的内容,而我们可以手动修改日志的打印级别:
public static void main(String[] args) {Logger logger = Logger.getLogger(Main.class.getName());//修改日志级别logger.setLevel(Level.ALL);//不使用父日志处理器logger.setUseParentHandlers(false);//自定义日志处理器ConsoleHandler hander = new ConsoleHandler();hander.setLevel(Level.ALL);logger.addHandler(hander);logger.log(Level.SEVERE,"我是server日志",new IOException("IO错误"));logger.log(Level.WARNING,"我是warning日志");logger.log(Level.INFO,"我是info日志");logger.log(Level.CONFIG,"我是config日志");logger.log(Level.FINE,"我是fine日志");}
每一个Logger都有一个父日志打印器,而这个父日志打印器默认使用的ConsoleHandler,这个的日志级别为INFO。并且,默认情况下,Java 的日志记录器会使用父处理器进行日志输出。因此想自定义日志输出级别时,需要先关闭父处理器。
既然关闭了父处理器,就需要自己再新建一个处理器,在这段代码中,设置了两次Level.ALL,logger.setLevel(Level.ALL)的作用是确保日志记录器捕获所有日志信息,hander.setLevel(Level.ALL)的作用是控制实际输出的日志内容。即便记录器捕获了所有级别的日志,但只有满足处理器级别条件的日志才会被真正输出。
打印文件
日志处理器不仅仅只有控制台打印,也可以打印文件
这时就需要使用文件处理器
(文件处理器和日志处理器可以同时存在)
//打印到本地文件//自定义文件处理器FileHandler fileHandler = new FileHandler("test.log");//设置文件打印的级别fileHandler.setLevel(Level.WARNING);logger.addHandler(fileHandler);
运行后会生成一个test.log文件,文件中记录了打印的日志:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE log SYSTEM "logger.dtd">
<log>
<record><date>2024-11-01T22:33:44</date><millis>1730471624479</millis><sequence>0</sequence><logger>com.test.Main</logger><level>SEVERE</level><class>com.test.Main</class><method>main</method><thread>1</thread><message>我是server日志</message><exception><message>java.io.IOException: IO错误</message><frame><class>com.test.Main</class><method>main</method><line>32</line></frame></exception>
</record>
<record><date>2024-11-01T22:33:44</date><millis>1730471624496</millis><sequence>1</sequence><logger>com.test.Main</logger><level>WARNING</level><class>com.test.Main</class><method>main</method><thread>1</thread><message>我是warning日志</message>
</record>
</log>
可以看到,文件处理器打印出的内容格式和控制台处理器打印出的内容格式不太一样,文件处理器默认打印出的格式为xml格式
这样有点难以阅读,我们想修改一下文件处理器打印出的格式,应该怎么办呢?
这时就要用到另外一个类,叫做SimpleFormatter,这个类叫做日志格式化器,是专门用于将日志转化为简单易读的格式的。
而控制台处理器就默认使用了这个类。
在文件处理器中使用.setFormatter()方法添加格式化器:
SimpleFormatter simpleFormatter = new SimpleFormatter();//打印到本地文件//自定义文件处理器FileHandler fileHandler = new FileHandler("test.log");fileHandler.setFormatter(simpleFormatter);//设置文件打印的级别fileHandler.setLevel(Level.WARNING);logger.addHandler(fileHandler);
除了SimpleFormatter,也可以使用XMLFormatter来将日志的格式改为xml格式
日志过滤器
如果我们不希望某些日志信息被输出,可以自定义日志过滤器
Filter customFilter = new Filter() {@Overridepublic boolean isLoggable(LogRecord record) {// 只记录包含 "IMPORTANT" 的日志return record.getMessage().contains("IMPORTANT");}};// 将过滤器添加到处理器
handler.setFilter(customFilter);
自定义日志过滤器的本质是通过重写Filter接口中的isLoggable接口实现的
过滤器可以被应用到handler中,也可以被应用到logger中
logger.setFilter(customFilter);
日志输出流程
整个日志输出流程是一个层层筛选、逐步处理的过程:
- 应用程序生成日志,
Logger
接收并通过其自身的过滤器进行初步筛选。 - 筛选通过的日志记录传递给
Handler
,并经过Handler
的过滤器进一步筛选。 - 最终符合条件的日志通过
Handler
输出到指定的外部系统。
相关文章:

Java学习路线:JUL日志系统(一)日志框架介绍
目录 打印日志 日志的级别 打印文件 日志过滤器 日志输出流程 首先,为什么要使用日志系统? 如果单纯地用System.out.println打印信息,如果项目比较大,存在大量的信息就会显得非常凌乱。 而且,当我们希望在debug的…...

[渲染层网络层错误] net::ERR_CONTENT_LENGTH_MISMATCH 问题解决
问题描述 问题背景 微信小程序访问后端img资源的时候,偶尔出现这个感叹号,图片加载不出来,但是对应的url贴出来在浏览器中访问,或者重新加载是可以访问的。 错误描述 经查询前端报错 [渲染层网络层错误] net::ERR_CONTENT_LE…...
C 语言编程中的常见错误及解决方案
在 C 语言开发中,编译和链接错误是常见的问题,尤其是在处理多个源文件时。本文将总结一些常见的错误,并提供相应的解决方案,以帮助开发者更高效地排查和修复这些问题。 1. 结构体作用域问题 问题描述 在函数参数列表中定义结构体…...

开源模型应用落地-glm模型小试-glm-4-9b-chat-批量推理(二)
一、前言 GLM-4是智谱AI团队于2024年1月16日发布的基座大模型,旨在自动理解和规划用户的复杂指令,并能调用网页浏览器。其功能包括数据分析、图表创建、PPT生成等,支持128K的上下文窗口,使其在长文本处理和精度召回方面表现优异&a…...

【C++篇】数据之林:解读二叉搜索树的优雅结构与运算哲学
文章目录 二叉搜索树详解:基础与基本操作前言第一章:二叉搜索树的概念1.1 二叉搜索树的定义1.1.1 为什么使用二叉搜索树? 第二章:二叉搜索树的性能分析2.1 最佳与最差情况2.1.1 最佳情况2.1.2 最差情况 2.2 平衡树的优势 第三章&a…...

C#-类:声明类、声明类对象
一:类的声明 class 类名 {//特征——成员变量//行为——成员方法//保护特征——成员属性//构造函数和析构函数//索引器//运算符重载//静态成员 }类名:帕斯卡 同一个语句块中的不同类 不能重名 二:声明类对象 2.1 类的声明 ≠ 类对象的声…...

【AIGC】ChatGPT提示词Prompt高效编写技巧:逆向拆解OpenAI官方提示词
博客主页: [小ᶻZ࿆] 本文专栏: AIGC | ChatGPT 文章目录 💯前言💯OpenAI官方提示词的介绍OpenAI官方提示词的结构与组成如何通过分析提示词找到其核心组件 💯OpenAI官方提示词分析案例一:制定教学计划案例二&…...

【linux】端口监听和终止进程
端口监听和终止进程 有时候,即使进程看起来已经关闭,它可能仍然占用着端口。你可以使用 netstat -tulpn | grep <端口号> 来查看哪个进程正在使用该端口,然后使用 kill -9 来强制关闭该进程。 [naienotebook-npu-b1bb152e-7655cb9d4…...

【网络安全】|kali中安装nessus
1、使用 df -h 命令查看磁盘使用情况,确保磁盘容量大于40G 简单粗暴办法:重装系统,装系统中注意磁盘空间相关的选项 //磁盘扩容:https://wiki.bafangwy.com/doc/670/ 2、安装 nessus 安装教程 https://blog.csdn.net/Cairo_A/a…...

Docker可视化管理面板DPanel的安装
本文软件由网友 rui 推荐; 什么是 DPanel ? DPanel 是一款 Docker 可视化管理面板,旨在简化 Docker 容器、镜像和文件的管理。它提供了一系列功能,使用户能够更轻松地管理和部署 Docker 环境。 软件特点: 可视化管理&…...

【android12】【AHandler】【3.AHandler原理篇AHandler类方法全解】
AHandler系列 【android12】【AHandler】【1.AHandler异步无回复消息原理篇】-CSDN博客 【android12】【AHandler】【2.AHandler异步回复消息原理篇】-CSDN博客 其他系列 本人系列文章-CSDN博客 1.简介 前面两篇我们主要介绍了有回复和无回复的消息的使用方法和源码解析&a…...

使用Docker Compose构建多容器应用
💓 博客主页:瑕疵的CSDN主页 📝 Gitee主页:瑕疵的gitee主页 ⏩ 文章专栏:《热点资讯》 使用Docker Compose构建多容器应用 引言 Docker Compose 简介 安装 Docker Compose 创建基本配置 运行多容器应用 查看服务状态 …...
面试知识目录
面试知识目录 八股文 java基础 java反射java HashMap面向对象多线程虚拟机内存 SpringMybatisMySQLPostgresqlSQL优化Nosql...

Rust移动开发:Rust在Android端集成使用介绍
Andorid调用Rust 目前Rust在移动端上的应用,一般作为应用sdk的提供,供各端使用,目前飞书底层使用Rust编写通用组件。 该篇适合对Android、Rust了解,想看如何做整合,如果想要工程源码,可以评论或留言有解疑…...

vue3动态监听div高度案例
案例场景 场景描述:现在左边的线条长度需要根据右边盒子的高度进行动态变化 实践代码案例 HTML部分 <div v-for"(device, index) in devices" :key"index"><!-- 动态设置 .left-bar 的高度 --><div class"left-bar"…...

数据转换 | Matlab基于SP符号递归图(Symbolic recurrence plots)一维数据转二维图像方法
目录 基本介绍程序设计参考资料获取方式 基本介绍 Matlab基于SP符号递归图(Symbolic recurrence plots)一维数据转二维图像方法 符号递归图(Symbolic recurrence plots)是一种一维时间序列转图像的技术,可用于平稳和非平稳数据集;对噪声具有…...

分类算法——逻辑回归 详解
逻辑回归(Logistic Regression)是一种广泛使用的分类算法,特别适用于二分类问题。尽管名字中有“回归”二字,逻辑回归实际上是一种分类方法。下面将从底层原理、数学模型、优化方法以及源代码层面详细解析逻辑回归。 1. 基本原理 …...
只允许指定ip远程连接ssh
我们都会使用securtcrt或者xshell等软件进行远程登录,这样虽然会给我们带来很多便捷,但是同样会存在一定的风险。有很多人专门通过重复的扫描试图破解我们的linux服务器,从而获取免费的“肉鸡”。因此我们可以通过设置hosts.allow和hosts.den…...

Rust 力扣 - 2841. 几乎唯一子数组的最大和
文章目录 题目描述题解思路题解代码题目链接 题目描述 题解思路 我们遍历长度为k的窗口,用一个哈希表记录窗口内的所有元素(用来对窗口内元素去重),我们取哈希表中元素数量大于等于m的窗口总和的最大值 题解代码 use std::coll…...

TwinCL: A Twin Graph Contrastive Learning Model for Collaborative Filtering
TwinCL: A Twin Graph Contrastive Learning Model for Collaborative Filtering 摘要 在推荐和协同过滤领域,图对比学习(Graph Contrasive Learning,GCL)已经成为一种有影响的方法。然而,对比学习有效性的原因还没有…...

51c自动驾驶~合集58
我自己的原文哦~ https://blog.51cto.com/whaosoft/13967107 #CCA-Attention 全局池化局部保留,CCA-Attention为LLM长文本建模带来突破性进展 琶洲实验室、华南理工大学联合推出关键上下文感知注意力机制(CCA-Attention),…...

阿里云ACP云计算备考笔记 (5)——弹性伸缩
目录 第一章 概述 第二章 弹性伸缩简介 1、弹性伸缩 2、垂直伸缩 3、优势 4、应用场景 ① 无规律的业务量波动 ② 有规律的业务量波动 ③ 无明显业务量波动 ④ 混合型业务 ⑤ 消息通知 ⑥ 生命周期挂钩 ⑦ 自定义方式 ⑧ 滚的升级 5、使用限制 第三章 主要定义 …...
Oracle查询表空间大小
1 查询数据库中所有的表空间以及表空间所占空间的大小 SELECTtablespace_name,sum( bytes ) / 1024 / 1024 FROMdba_data_files GROUP BYtablespace_name; 2 Oracle查询表空间大小及每个表所占空间的大小 SELECTtablespace_name,file_id,file_name,round( bytes / ( 1024 …...

渗透实战PortSwigger靶场-XSS Lab 14:大多数标签和属性被阻止
<script>标签被拦截 我们需要把全部可用的 tag 和 event 进行暴力破解 XSS cheat sheet: https://portswigger.net/web-security/cross-site-scripting/cheat-sheet 通过爆破发现body可以用 再把全部 events 放进去爆破 这些 event 全部可用 <body onres…...

如何将联系人从 iPhone 转移到 Android
从 iPhone 换到 Android 手机时,你可能需要保留重要的数据,例如通讯录。好在,将通讯录从 iPhone 转移到 Android 手机非常简单,你可以从本文中学习 6 种可靠的方法,确保随时保持连接,不错过任何信息。 第 1…...

12.找到字符串中所有字母异位词
🧠 题目解析 题目描述: 给定两个字符串 s 和 p,找出 s 中所有 p 的字母异位词的起始索引。 返回的答案以数组形式表示。 字母异位词定义: 若两个字符串包含的字符种类和出现次数完全相同,顺序无所谓,则互为…...
服务器--宝塔命令
一、宝塔面板安装命令 ⚠️ 必须使用 root 用户 或 sudo 权限执行! sudo su - 1. CentOS 系统: yum install -y wget && wget -O install.sh http://download.bt.cn/install/install_6.0.sh && sh install.sh2. Ubuntu / Debian 系统…...

【分享】推荐一些办公小工具
1、PDF 在线转换 https://smallpdf.com/cn/pdf-tools 推荐理由:大部分的转换软件需要收费,要么功能不齐全,而开会员又用不了几次浪费钱,借用别人的又不安全。 这个网站它不需要登录或下载安装。而且提供的免费功能就能满足日常…...

20个超级好用的 CSS 动画库
分享 20 个最佳 CSS 动画库。 它们中的大多数将生成纯 CSS 代码,而不需要任何外部库。 1.Animate.css 一个开箱即用型的跨浏览器动画库,可供你在项目中使用。 2.Magic Animations CSS3 一组简单的动画,可以包含在你的网页或应用项目中。 3.An…...
uniapp 集成腾讯云 IM 富媒体消息(地理位置/文件)
UniApp 集成腾讯云 IM 富媒体消息全攻略(地理位置/文件) 一、功能实现原理 腾讯云 IM 通过 消息扩展机制 支持富媒体类型,核心实现方式: 标准消息类型:直接使用 SDK 内置类型(文件、图片等)自…...