Java日志框架(根据黑马程序员(BV11g411P7mv)整理)
最近开始到公司实习,发现公司日志代码属实看不太懂(所以最近的Log4j的事件
我不用半夜爬起来,哈哈),就想着到B站学习一下日志代码的书写,正好看到黑
马程序员出了日志框架的视频,在这做一下笔记。
懒得动手的同学可以在文末下载XMind文件(可能需要XMind VIP)。
一、JUL(Java util Logging)
1.概念&模型
1.1 概念
JUL全称Java util Logging是java原生的日志框架,使用时不需要另外引用第三方类库,相对其他日志框架使用方便,学习简单,能够在小型应用中灵活使用。
1.2 模型
2.代码
2.1 创建项目
创建一个maven项目,并导入jdk1.8和junit,如下图
2.2 入门例子
2.2.1 快速入门案例
@Test
public void testQuick() throws Exception{
// 1.获取日志记录器对象
Logger logger = Logger.getLogger("JULDemo1"); //一般起名为本类名
// 2.日志记录输出
logger.info("hello JUL");
// 通用方法进行日志记录
logger.log(Level.INFO, "info meg"); //日志级别,字符串消息
// 通过占位符方式输出变量
String name = "ghost";
Integer age = 18;
logger.log(Level.INFO, "用户信息:{0},{1}", new Object[]{name, age}); //占位符{0}对应name,{1}对应age
}
一些注意点:
占位符的{0}对应后面写的第一个参数name,{1}对应age,可以交换{0}和{1}位置,如下图
这个Logger是JDK8里面的,见下图
2.2.2 日志级别详解
2.2.2.1七种日志级别
1.SEVERE:最高级别,错误级别信息。比如说程序出现了严重问题造成了程序的终止,就可以用SEVERE进行记录。
2.WARNING:级别比SEVERE低一点,警告信息。记录程序发生的一些问题,这些问题不会造成程序的终止。
3.INFO:级别比WARNING低一点,消息记录。记录一些数据库的连接信息、IO的传递信息、网络通信信息都可以交给info。
4.CONFIG:级别比INFO低一点,配置信息。加载了配置文件,读取了配置文件的参数,都可以用CONFIG进行记录。
5:FINE&FINER&FINEST:debug日志记录的消息。用来记录程序的运行的状态、执行的流程还有参数的传递信息,FINE、FINER、FINEST的颗粒度有所不一。
6:ALL:全部日志开启。ALL的value值是Interger类型的最小值,比上面的日志级别的value值都小,设置了ALL那么全部日志级别都会开启。
7:OFF:全部日志关闭,解释见6。
同理,如果设置了日志级别为INFO(value=800),那么比INFO的value值低的CONFIG(700)、FINE(500)等等不会进行输出,而比INFO的value值高的WARNING(900)与SEVERE(1000)会进行输出。
2.2.2.2 日志级别代码示例
可见,只输出了info及以上vlaue值的日志信息。
@Test
public void testLogLevel() throws Exception{
// 1.获取日志记录器对象
Logger logger = Logger.getLogger("JULDemo1"); //一般起名为本类名
// 2.日志记录输出
logger.severe("severe");
logger.warning("warning");
logger.info("info"); //JUL默认的日志级别
logger.fine("fine");
logger.finer("finer");
logger.finest("finest");
}
2.2.2.3 自定义日志级别代码
/*自定义日志级别*/
@Test
public void testLogConfig() throws Exception{
// 获取日志记录器对象
Logger logger = Logger.getLogger("JULDemo1"); //一般起名为本类名
// 关闭系统默认配置
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); //处理器也配置一下
// 日志记录输出
logger.severe("severe");
logger.warning("warning");
logger.info("info"); //JUL默认的日志级别
logger.fine("fine");
logger.finer("finer");
logger.finest("finest");
}
查看输出结果,可以看到所有级别都输出了,如下图:
如上只是打印在控制台,现在我们创建一个FileHandler打印到指定路径上:
// 场景
FileHandler fileHandler = new FileHandler("C:\\Users\\ghost\\Desktop\\JUL.log"); //输出到桌面
// 进行关联
fileHandler.setFormatter(simpleFormatter);
logger.addHandler(fileHandler);
因为是输出到桌面的JUL.log上,我们到桌面创建一个JUL.log,如下图:
然后运行程序,再打开这个文件查看:
2.3 Logger对象父子关系
2.3.1 所有日志记录器的顶级父元素
/*Logger对象父子关系*/
@Test
public void testLogParent() throws Exception{
Logger logger1 = Logger.getLogger("com.ghost");
Logger logger2 = Logger.getLogger("com");
/*测试*/
// 判断logger1的父对象是不是logger2
System.out.println(logger1.getParent() == logger2); //true
// 所有日志记录器的顶级父元素:LogManager$RootLogger,name为一个空字符串:""
System.out.println("logger2 Parent:" + logger2.getParent() + ",name:" + logger2.getParent().getName());
}
输出结果如下图:
2.3.2 继承
com.ghost会继承com,而com没有我们自己定义的父包,就是继承LogManager$RootLogger,如下图
/*Logger对象父子关系*/
@Test
public void testLogParent() throws Exception{
Logger logger1 = Logger.getLogger("com.ghost");
Logger logger2 = Logger.getLogger("com");
/**
* 这里把logger2的日志级别设置为ALL,logger1的不变,然后输出logger1,看看会不会有继承关系
* */
// 关闭系统默认配置
logger2.setUseParentHandlers(false);
/*自定义配置日志级别*/
// 创建ConsoleHandler 控制台输出
ConsoleHandler consoleHandler = new ConsoleHandler();
// 创建简单格式转换对象
SimpleFormatter simpleFormatter = new SimpleFormatter();
// 进行关联
consoleHandler.setFormatter(simpleFormatter);
logger2.addHandler(consoleHandler);
// 配置日志具体级别
logger2.setLevel(Level.ALL);
consoleHandler.setLevel(Level.ALL); //处理器也配置一下
// 日志记录全部都输出了,说明com.ghost会继承com,而com没有我们自己定义的父包,就是继承LogManager$RootLogger
logger1.severe("severe");
logger1.warning("warning");
logger1.info("info"); //JUL默认的日志级别
logger1.fine("fine");
logger1.finer("finer");
logger1.finest("finest");
}
输出结果如下,说明有继承关系:
2.3 JUL配置文件入门
为了方便管理,我们希望把日志文件的相关配置都放到配置文件里。
怎么做呢,我们先回到上面的父子关系例子,logger对象在实例化之前一定会实例化他的顶级父元素,我们先来看看logger对象是怎么创建的。
我们再次回到上一步
回到父子关系的例子里,debug执行
先进入了我们打的第一个断点里
继续往下走就看到第二个断点
先加载配置类
再找配置文件和jre
最后找到logging.properties,我们复制路径进去看一下这个日志文件
简化一下
把这些放到IDEA里
修改日志级别观察是否成功
先修改日志文件
然后再写段代码来输出日志信息
查看控制台输出,可以看到全都输出了,确实是ALL级别
我们可以指定输出的路径,handlers里配置了两个,就向两个地方都输出(这里就是控制台和/logs里都输出),我这里就直接丢到桌面
再次执行代码
可以看到控制台输出了
回到桌面查看也可以看到有java0了(第一个日志文件是0,第二个1,以此类推)
2.4 JUL配置文件详解