Java日志初探JUL
今天想了解以下Java中的日志框架,毕竟做项目调试光用sout也不行所以就开始了对日志的学习。
日志概述
就我的理解来说,日志就是用来日志文件或控制台打印程序运行过程中的信息,这些信息被我们用来查看程序运行的状况,方便我们的伟华,排错。
日志系统有日志门面和日志主题,什么是日志门面呢?
就是日志框架特别多,我们使用日志门面,就可以用一套API操作各种框架,比如JDBC可以用来操作MySql,还可以操作Oracle.
JUL架构
- Logger:Logger是我们访问日志系统的入口程序,我们要搞日志信息,都要靠实例化出的logger对象
- Handler:处理器,负责将日志做记录,处理器的具体实现,决定了日志记录是写入文件,还是打在控制台,还是网络上其他的日志服务或操作系统
- Formatter:负责对日志中的数据进行转换和格式化,它决定了一条日志记录的最终形式
- Filter:过滤器,可以定制哪些信息被记录,哪些信息放过
简单使用
通过Logger.getLogger获取Logger的实例化对象
Logger logger = Logger.getLogger("com.kk.web01.bean.City");
"com.kk.web01.bean.City" 只是一个类的全类名,之后这个logger打出的日志中间都会出现这个全类名,这个也是我们定位错误的依据。
这两条语句差不多,都是打印方法参数里的字符串
logger.info("ingo信息");
logger.log(Level.INFO,"info信息");
.ingf()打印INFO级别的日志信息
Level是一个枚举类,Level.INFO设置这条信息是info级别
@Test
void testLog(){
//获取日志记录对象
Logger logger = Logger.getLogger("com.kk.web01.bean.City");
//日志记录输出
logger.info("第一次用JUL");
//通用方法进行日志记录
//Level是一个枚举类
logger.log(Level.INFO,"info信息");
//通过占位符 方式输出变量值 不需要手动拼接字符串,效率高一点
String name ="余明款";
Integer age = 20;
logger.log(Level.INFO,"用户信息:{0},{1}",new Object[]{name,age});
}
日志级别
OFF
public static final Level OFF = new Level("OFF",Integer.MAX_VALUE, defaultBundle);
每一个枚举对象里都有两个属性,一个name,就是"OFF",一个Integer代表颗粒度,OFF的颗粒度是最大的,代表关闭日志,所有日志都不输出,这个级别比较特殊
SEVER
public static final Level SEVERE = new Level("SEVERE",1000, defaultBundle);
SEVER用来输出程序比较严重的问题,级别最高
WARNING
public static final Level WARNING = new Level("WARNING", 900, defaultBundle);
WARNING用来输出比较重要的可能引起严重错误的信息
INFO
public static final Level INFO = new Level("INFO", 800, defaultBundle);
INFO级别输出重要的正常运行信息
CONGIF
public static final Level CONFIG = new Level("CONFIG", 700, defaultBundle);
CONFIG级别显示各种各样的配置信息
FINE、FINER、FINEST
public static final Level FINE = new Level("FINE", 500, defaultBundle);
public static final Level FINER = new Level("FINER", 400, defaultBundle);
public static final Level FINEST = new Level("FINEST", 300, defaultBundle);
这三兄弟是显示程序正常运行时的信息的,一般用一个就行了
ALL
public static final Level ALL = new Level("ALL", Integer.MIN_VALUE, defaultBundle);
ALL级别代表所有级别全开。
JUL默认情况下日志只开启到INFO级别,我们可以用这段代码测试一下
@Test
void testLogLevel(){
Logger logger = Logger.getLogger("com.kk.web01.bean.City");
logger.severe("severe");
logger.warning("warning");
logger.info("info"); //JUL默认的级别,高的输出,低的过滤
logger.config("config");
logger.fine("fine");
logger.finer("finer");
logger.finest("finest");
}
最后的输出结果是
果然只输出到INFO级别
自定义日志级别
自定义日志级别的原理
Logger对象相当于一个入口,他会关联Handler和Format,所以我们可以定义我们自己的Format和Handler再和我们的logger对象关联,从而输出我们想要的结果
@Test
//自定义日志级别
void testlevel() throws IOException {
Logger logger = Logger.getLogger("com.kk.web01.bean.City");
//自定义配置日志级别
//关闭系统默认配置
logger.setUseParentHandlers(false);
//创建ConsolHandler对象 控制台的输出
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("logs/test.log");
//进行关联
fileHandler.setFormatter(simpleFormatter);
logger.addHandler(fileHandler);
logger.severe("severe");
logger.warning("warning");
logger.info("info"); //JUL默认的级别,高的输出,低的过滤
logger.config("config");
logger.fine("fine");
logger.finer("finer");
logger.finest("finest");
}
这段代码先给logger关闭默认配置,再给他关联上我们配置的Handler,和Format,他就可以按我们自己定义的级别输出了