最近在敲代码的时候经常出错,老是找不到原因,崩溃~~,(为什么不debug一下??作为一只小菜鸟,感觉只要debug和框架有关的,基本都看不懂),然后经人提醒才知道可以通过日志来打印一些关键信息来找错(以前的我都是简单粗暴的在代码中写输出语句的),但是以前学习的时候根本没怎么学日志,这一块的知识基本为空白,所以现在要好好补一下这方面的知识了。。。
日志的概念
1 日志文件
日志文件是用于记录系统操作事件的文件集合,可以分为事件日志和消息日志。具有 处理历史数据、诊断问题的追踪以及理解系统的活动等重要作用。
在计算机中,日志文件是记录在操作系统或其他软件运行中发生的事件或在通信软件的不同用户之间的文件。记录是保持日志的行为。
1.1 调试日志
软件开发中,我们经常需要去调试程序,做一些信息,状态的输出便于我们查询程序的运行状况。为了让我们能够更加灵活和方便的控制这些调试的信息,所有我们需要专业的日志技术。Java中寻找bug会需要重现。调试也就是debug可以在程序中暂停程序运行,可以查看程序在运行中的情况。日志主要是为了更方便的去重现问题。
1.2 系统日志
系统日志是记录在系统硬件、软件和系统问题的信息,同时还可以监视系统中发生的事件。
2 Java日志框架
问题:
1、控制日志输出的内容和格式
2、控制日志输出的位置
3、日志优化:异步日志,日志文件的归档和压缩
4、日志系统的维护
5、面向接口开发–日志的门面
2.1 为什么要用日志框架
因为软件系统发展到今天已经很复杂,特别是服务器端软件,涉及到的知识、内容,问题太多。在某些方面使用别人成熟的框架,就相当于让别人帮你完成一些基础工作,你只需要集中精力完成系统的业务逻辑。而且框架一般都是成熟、稳定的。它可以处理系统很多细节问题,比如:事务处理,安全性,数据流控制等问题。还有框架一般都经过很多人使用,所有结构很好,扩展性也很好。
2.2 现有的日志框架
JUL(java util logging)、logback、log4j、log4j2
JCL(Jakarta Commons Logging)、slf4j(Simple Logging Facade for Java)
日志门面
JCL、slf4j
日志实现
JUL、logback、log4j、log4j2
3 JUL学习
JUL全称Java util Logging 是Java原生的日志框架,使用时不需要另外引入第三方类库,相对其他日志框架使用方便,学习简单,能够在小型应用中灵活使用。
3.1
Loggers:被称为记录器,应用程序通过获取Logger对象,调用其API来发布日志信息。Logger通常是应用程序访问日志系统的入口程序。
Appenders: 也被称为Handlers,每个Logger都会关联一组Handlers,Logger会将日志交给关联Handlers处理,有Handlers负责将日志做记录。Handlers在此是一个抽象,其具体的实现决定了日志记录的位置可以是控制台、文件、网络上的其他日志服务或操作系统日志等。
Layouts:也被称为formatters,它负责对日志事件中的数据进行转换和格式化。Layouts决定了数据在一条日志记录中的最终形式。
Level:每条日志消息都有一个关联的日志级别。该级别粗略指导了日志消息的重要性和紧迫,我可以将Level和Loggers,Appenders做关联以便于我们过滤消息。
Filters:过滤器,根据需要指定哪些信息会被记录,哪些信息会被放过。
日志案例
目录结构:
注意:使用@Test注解时需要引入依赖
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<version>2.2.4.RELEASE</version>
</dependency>
</dependencies>
package log1;
import org.junit.Test;
import java.util.logging.Level;
import java.util.logging.Logger;
public class JUTTest {
//初始案例
@Test
public void testQ(){
//获取日志记录器对象
Logger logger=Logger.getLogger("log1.JUTTest");
//日志记录输出
logger.info("hello jul");
//通用方法进行日志记录
logger.log(Level.INFO,"info msg");
//通过占位符 方式输出变量值
String name="itcast";
Integer age=13;
logger.log(Level.INFO,"用户信息:{0},{1}",new Object[]{name,age});
}
/* 输出结果
2月 16, 2020 9:56:33 下午 log1.JUTTest testQ
信息: hello jul
2月 16, 2020 9:56:33 下午 log1.JUTTest testQ
信息: info msg
2月 16, 2020 9:56:33 下午 log1.JUTTest testQ
信息: 用户信息:itcast,13
*/
//日志级别
@Test
public void testLogLevel(){
//获取日志记录器对象
Logger logger=Logger.getLogger("log1.JUTTest");
//日志记录输出
logger.severe("severe");// 比 info 级别高,能输出
logger.warning("warning");//比 info 级别高,能输出
logger.info("info"); //默认日志级别
//下面的几个没有 info 级别高,所以不会有输出
logger.config("config");
logger.fine("fine");
logger.finer("finer");
logger.finest("finest");
}
/* 输出结果:
2月 16, 2020 9:37:04 下午 log1.JUTTest testLogLevel
严重: severe
2月 16, 2020 9:37:04 下午 log1.JUTTest testLogLevel
警告: warning
2月 16, 2020 9:37:04 下午 log1.JUTTest testLogLevel
信息: info*/
}
//自定义日志级别
@Test
public void testLogConfig(){
//获取日志记录器对象
Logger logger=Logger.getLogger("log1.JUTTest");
//关闭系统默认配置
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 文件输出
FileHandler fileHandler=new FileHandler("d:/jul.log");
//进行关联
fileHandler.setFormatter(simpleFormatter);
//日志记录输出
logger.severe("severe");// 比 info 级别高,能输出
logger.warning("warning");//比 info 级别高,能输出
logger.info("info"); //默认日志级别
//下面的几个没有 info 级别高,所以不会有输出
logger.config("config");
logger.fine("fine");
logger.finer("finer");
logger.finest("finest");
}
/*
2月 16, 2020 10:21:50 下午 log1.JUTTest testLogConfig
严重: severe
2月 16, 2020 10:21:50 下午 log1.JUTTest testLogConfig
警告: warning
2月 16, 2020 10:21:50 下午 log1.JUTTest testLogConfig
信息: info
2月 16, 2020 10:21:50 下午 log1.JUTTest testLogConfig
配置: config
2月 16, 2020 10:21:50 下午 log1.JUTTest testLogConfig
详细: fine
2月 16, 2020 10:21:50 下午 log1.JUTTest testLogConfig
较详细: finer
2月 16, 2020 10:21:50 下午 log1.JUTTest testLogConfig
非常详细: finest
*/
```java
在这里插入代码片
生成的日志文件: