Java日志体系

  • 日志实现 JUL、logback、log4j、log4j2
  • JUL日志级别 java.util.logging.Level
  • 示例讲解功能
    • JULTest 测试类 test方法 不同日志输出方法
    • testLogConsoleConfig方法 控制台输出测试
    • testLogFileConfig方法 输出文件测试
    • 日志对象父子关系
    • testLogProperties配置文件方式
  • 日志原理解析

日志实现 JUL、logback、log4j、log4j2

  • Loggers:被称为记录器,应用程序通过获取Logger对象,调用其API来来发布日志信息。Logger通常时应用程序访问日志系统的入口程序。
  • Appenders:也被称为Handlers,每个Logger都会关联一组Handlers,Logger会将日志交给关联Handlers处理,由Handlers负责将日志做记录。Handlers在此是一个抽象,其具体的实现决定了日志记录的位置可以是控制台、文件、网络上的其他日志服务或操作系统日志等。
  • Layouts:也被称为Formatters,它负责对日志事件中的数据进行转换和格式化。Layouts决定了数据在一条日志记录中的最终形式。
  • Level:每条日志消息都有一个关联的日志级别。该级别粗略指导了日志消息的重要性和紧迫,我可以将Level和Loggers,Appenders做关联以便于我们过滤消息。
  • Filters:过滤器,根据需要定制哪些信息会被记录,哪些信息会被放过。

JUL日志级别 java.util.logging.Level

各级别按降序排列如下:

  • SEVERE(最高值):SEVERE 是指示严重失败的消息级别
  • WARNING :WARNING 是指示潜在问题的消息级别
  • INFO :INFO 是报告消息的消息级别
  • CONFIG :CONFIG 是用于静态配置消息的消息级别
  • FINE :FINE 是提供跟踪信息的消息级别
  • FINER :FINEST 指示一条最详细的跟踪消息
  • FINEST(最低值):FINEST 指示一条最详细的跟踪消息

特殊级别

  • OFF:可用来关闭日志记录。
  • ALL:启用所有消息的日志记录。

示例讲解功能

创建maven工程,因为jul是java的jdk提供的日志,所以不需要添加jar包。直接使用。

JULTest 测试类 test方法 不同日志输出方法

获取日志记录器,使用不同的方法打印日志。

/*** java 原生日志jul测试*/
public class JULTest {@Testpublic void  test(){//获取日志记录器对象Logger logger = Logger.getLogger("cn.ling.logs.JULTest");//日志记录输出logger.info("Hello JUL");//通用方法进行日志记录logger.log(Level.INFO, "JUL log");//占位符方式输出变量值logger.log(Level.INFO,"用户信息:{0},{1}",new Object[]{"小美",18});}
}

输出结果:

三月 17, 2021 2:13:02 下午 cn.ling.logs.JULTest test
信息: Hello JUL
三月 17, 2021 2:13:02 下午 cn.ling.logs.JULTest test
信息: JUL log
三月 17, 2021 2:13:02 下午 cn.ling.logs.JULTest test
信息: 用户信息:小美,18

testLogConsoleConfig方法 控制台输出测试

下面只有测试方法代码,放到上面测试类里面即可:

使用默认日志级别Info执行代码:

@Testpublic void testLogConsoleConfig(){//获取日志记录器对象Logger logger = Logger.getLogger("cn.ling.logs.JULTest");logger.severe("severe");logger.warning("warning");logger.info("info");logger.config("config");logger.fine("fine");logger.finer("finer");logger.finest("finest");}

输出结果:日志级别在info之下的日志不会输出:

三月 17, 2021 2:17:52 下午 cn.ling.logs.JULTest testLogConsoleConfig
严重: severe
三月 17, 2021 2:17:52 下午 cn.ling.logs.JULTest testLogConsoleConfig
警告: warning
三月 17, 2021 2:17:52 下午 cn.ling.logs.JULTest testLogConsoleConfig
信息: info

关闭默认日志级别:logger.setUseParentHandlers(false)

@Testpublic void testLogConsoleConfig(){//获取日志记录器对象Logger logger = Logger.getLogger("cn.ling.logs.JULTest");//关闭默认日志级别logger.setUseParentHandlers(false);//输出到控制台ConsoleHandler consoleHandler = new ConsoleHandler();//输出格式SimpleFormatter simpleFormatter = new SimpleFormatter();consoleHandler.setFormatter(simpleFormatter);//输出控制台的日志级别consoleHandler.setLevel(Level.ALL);logger.addHandler(consoleHandler);//日志输出级别logger.setLevel(Level.CONFIG);logger.severe("severe");logger.warning("warning");logger.info("info");logger.config("config");logger.fine("fine");logger.finer("finer");logger.finest("finest");}

输出结果:consoleHandler.setLevel(Level.ALL); 输出所有;logger.setLevel(Level.CONFIG);输出config级别。两者取范围最小的,即日志级别最大哪个作为输出标准

三月 17, 2021 2:23:15 下午 cn.ling.logs.JULTest testLogConsoleConfig
严重: severe
三月 17, 2021 2:23:15 下午 cn.ling.logs.JULTest testLogConsoleConfig
警告: warning
三月 17, 2021 2:23:15 下午 cn.ling.logs.JULTest testLogConsoleConfig
信息: info
三月 17, 2021 2:23:15 下午 cn.ling.logs.JULTest testLogConsoleConfig
配置: config

如果logger.setUseParentHandlers(false)不设置为false,将会重复输出info以上的日志。如下

三月 17, 2021 2:26:30 下午 cn.ling.logs.JULTest testLogConsoleConfig
严重: severe
三月 17, 2021 2:26:30 下午 cn.ling.logs.JULTest testLogConsoleConfig
严重: severe
三月 17, 2021 2:26:30 下午 cn.ling.logs.JULTest testLogConsoleConfig
警告: warning
三月 17, 2021 2:26:30 下午 cn.ling.logs.JULTest testLogConsoleConfig
警告: warning
三月 17, 2021 2:26:30 下午 cn.ling.logs.JULTest testLogConsoleConfig
信息: info
三月 17, 2021 2:26:30 下午 cn.ling.logs.JULTest testLogConsoleConfig
信息: info
三月 17, 2021 2:26:30 下午 cn.ling.logs.JULTest testLogConsoleConfig
配置: config

testLogFileConfig方法 输出文件测试

@Testpublic void testLogFileConfig() throws IOException {//获取日志记录器对象Logger logger = Logger.getLogger("cn.ling.logs.JULTest");//关闭默认日志级别logger.setUseParentHandlers(false);//输出到控制台ConsoleHandler consoleHandler = new ConsoleHandler();//输出格式SimpleFormatter simpleFormatter = new SimpleFormatter();consoleHandler.setFormatter(simpleFormatter);//输出控制台的日志级别consoleHandler.setLevel(Level.ALL);FileHandler fileHandler = new FileHandler("D:/logs/jul.log");fileHandler.setFormatter(simpleFormatter);logger.addHandler(fileHandler);//日志输出级别logger.setLevel(Level.CONFIG);logger.severe("severe");logger.warning("warning");logger.info("info");logger.config("config");logger.fine("fine");logger.finer("finer");logger.finest("finest");}

输出结果:

java.nio.file.NoSuchFileException: D:\logs\jul.log.lckat sun.nio.fs.WindowsException.translateToIOException(WindowsException.java:79)at sun.nio.fs.WindowsException.rethrowAsIOException(WindowsException.java:97)at sun.nio.fs.WindowsException.rethrowAsIOException(WindowsException.java:102)at sun.nio.fs.WindowsFileSystemProvider.newFileChannel(WindowsFileSystemProvider.java:115)at java.nio.channels.FileChannel.open(FileChannel.java:287)at java.nio.channels.FileChannel.open(FileChannel.java:335)at java.util.logging.FileHandler.openFiles(FileHandler.java:459)at java.util.logging.FileHandler.<init>(FileHandler.java:292)at cn.ling.logs.JULTest.testLogFileConfig(JULTest.java:73)at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)at java.lang.reflect.Method.invoke(Method.java:498)at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)at org.junit.runners.ParentRunner.run(ParentRunner.java:363)at org.junit.runner.JUnitCore.run(JUnitCore.java:137)at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:69)at com.intellij.rt.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:33)at com.intellij.rt.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:220)at com.intellij.rt.junit.JUnitStarter.main(JUnitStarter.java:53)

输出目录不存在,需要添加目录

日志对象父子关系

上面代码中的描述都比较详细,后面代码,如果描述的不够详细,希望自己去尝试尝试,这里仅仅把代码贴出来。

@Testpublic void testLogParent(){Logger loggerF = Logger.getLogger("cn.ling.logs");Logger loggerS = Logger.getLogger("cn.ling.logs.JULTest");System.out.println("loggerF==loggerS 结果:"+(loggerF==loggerS.getParent()));//true//关闭默认配置 如果修改为true子日志对象和父对象同事打印日志loggerF.setUseParentHandlers(false);ConsoleHandler consoleHandler = new ConsoleHandler();SimpleFormatter simpleFormatter = new SimpleFormatter();consoleHandler.setFormatter(simpleFormatter);loggerF.addHandler(consoleHandler);loggerF.setLevel(Level.ALL);consoleHandler.setLevel(Level.ALL);//日志级别loggerS.severe("severe");loggerS.warning("warning");loggerS.info("info");loggerS.config("config");loggerS.fine("fine");loggerS.finer("finer");loggerS.finest("finest");}

**输出结果:**为什么比上面输出的日志多,因为日志级别不一样。

loggerF==loggerS 结果:true
三月 17, 2021 2:34:52 下午 cn.ling.logs.JULTest testLogParent
严重: severe
三月 17, 2021 2:34:52 下午 cn.ling.logs.JULTest testLogParent
警告: warning
三月 17, 2021 2:34:52 下午 cn.ling.logs.JULTest testLogParent
信息: info
三月 17, 2021 2:34:52 下午 cn.ling.logs.JULTest testLogParent
配置: config
三月 17, 2021 2:34:52 下午 cn.ling.logs.JULTest testLogParent
详细: fine
三月 17, 2021 2:34:52 下午 cn.ling.logs.JULTest testLogParent
较详细: finer
三月 17, 2021 2:34:52 下午 cn.ling.logs.JULTest testLogParent
非常详细: finest

testLogProperties配置文件方式

创建配置文件logging.properties

##RootLogger使用的处理器(获取时设置):顶级父元素
handlers=java.util.logging.ConsoleHandler,java.util.logging.FileHandler
#RootLogger日志等级
.level=INFO##自定义Logger
#cn.ling.handlers=java.util.logging.FileHandler
#自定义Logger日志等级
#cn.ling.level=INFO
#忽略父日志设置
#cn.ling.useParentHandlers=false##控制台处理器
#输出日志级别
java.util.logging.ConsoleHandler.level=INFO
#指定handler对象的字符集
java.util.logging.ConsoleHandler.encoding=UTF-8
#输出日志格式
java.util.logging.ConsoleHandler.formatter=java.util.logging.SimpleFormatter##文件处理器
#输出日志级别
java.util.logging.FileHandler.level=INFO
#指定 handler 对象日志消息格式对象 SimpleFormatter 或者 XMLFormatter
java.util.logging.FileHandler.formatter=java.util.logging.SimpleFormatter
#输出日志文件路径
java.util.logging.FileHandler.pattern=D:/logs/jul.log
#输出日志文件限制大小(50000字节)
java.util.logging.FileHandler.limit=50000
#输出日志文件限制个数
java.util.logging.FileHandler.count=10
#输出日志文件 是否是追加(不会覆盖前边的日志)
java.util.logging.FileHandler.append=true# 指定日志消息格式
java.util.logging.SimpleFormatter.format = %4$s: %5$s [%1$tc]%n

测试代码:

 @Testpublic void testLogProperties() throws IOException {InputStream resourceAsStream = JULTest.class.getClassLoader().getResourceAsStream("logging.properties");Logger logger = Logger.getLogger("cn.ling.logs.JULTest");LogManager manager = LogManager.getLogManager();manager.readConfiguration(resourceAsStream);logger.severe("severe");logger.warning("warning");logger.info("info");logger.config("config");logger.fine("fine");logger.finer("finer");logger.finest("finest");}

console输出结果:

严重: severe [星期三 三月 17 14:39:00 CST 2021]
警告: warning [星期三 三月 17 14:39:00 CST 2021]
信息: info [星期三 三月 17 14:39:00 CST 2021]

**日志文件如下:**重复使因为我执行了两次的原因。

日志原理解析

  1. 初始化LogManager
    LogManager加载logging.properties配置
    添加Logger到LogManager
  2. 从单例LogManager获取Logger
  3. 设置级别Level,并指定日志记录LogRecord
  4. Filter提供了日志级别之外更细粒度的控制
  5. Handler是用来处理日志输出位置
  6. Formatter是用来格式化LogRecord的

Java日志体系(三) jul 配置文件详解,日志示例相关推荐

  1. 细说Java性能测试第三课 性能测试详解2

    如何制定一份有效的性能测试方案? 上一讲我们学习了性能测试的场景,并且明确了每个场景的核心意义,这一讲我将带你学习如何做好一份性能测试方案,相信你对测试方案这个概念并不陌生,那如何做好一份性能测试方案 ...

  2. java异常体系_JAVA异常体系结构详解

    一.什么是异常 异常:程序在运行过程中发生由于硬件设备问题.软件设计错误等导致的程序异常事件.(在Java等面向对象的编程语言中)异常本身是一个对象,产生异常就是产生了一个异常对象.      --百 ...

  3. JAVA框架之Hibernate【配置文件详解】

    Hibernate配置文件主要功能是配置数据库连接和Hibernate运行时所需的各种属性,配置文件应该位于JAVA应用或者JAVA Web应用的类文件中,刚开始接触Hibernate的时候,感觉Hi ...

  4. 如何定义日志消息的级别?详解日志的5个级别

    作者 | aib42 译者 | 刘嘉洋,无明 出处丨 高效开发运维 日志级别如何划分? 日志记录是软件开发的一个概念,几乎所有(可能并不是所有)软件都能从日志记录中获得很多好处.在开始一个大项目时,日 ...

  5. nginx学习简介-安装-启动-命令-nginx配置文件详解

    nginx是什么:nginx是一个高性能的HTTP和反向代理web服务器.同时也提供了IMAP/POP3/SMTP服务. nginx特点:开源.占内存少.轻量级.高性能(有报告表面nginx能支持高达 ...

  6. Java集合(四) LinkedList详解

      在上篇文章Java集合(三) ArrayList详解的学习和源码分析中,我们知道ArrayList是以数组实现,它的优势是查询性能高,劣势是按顺序增删性能差.如果在不确定元素数量的情况时,不建议使 ...

  7. eclipse java 逆向工程_Mybatis 逆向工程的三种方法详解

    Mybatis 逆向工程 逆向工程通常包括由数据库的表生成 Java 代码 和 通过 Java 代码生成数据库表.而Mybatis 逆向工程是指由数据库表生成 Java 代码. Mybaits 需要程 ...

  8. BIND配置文件详解(三)

    本文档摘录自<BIND9管理员手册>,如果有不对或者不清楚的地方,请大家告诉我,谢谢!   BIND配置文件详解(三)   7.server语句 服务器(server)语句的定义和使用: ...

  9. JAVA框架——struts(一)struts快速入门,struts访问流程,struts配置文件详解,动态方法调用

    一. Struts2框架概述 是一种基于MVC模式的轻量级web框架.本质是一个Servlet.作为控制器建立模型与视图的数据交互.Struts2以WebWord为核心,采用拦截器的机制处理客户的请求 ...

  10. Linux日志系统-03:logrotate主配置文件详解

    logrotate主配置文件详解 一.logrotate主配置文件/etc/logrotate.conf # see "man logrotate" for details # r ...

最新文章

  1. 力扣(LeetCode)刷题,简单+中等题(第33期)
  2. 【hdoj_1398】SquareCoins(母函数)
  3. LeetCode 669. Trim a Binary Search Tree修剪二叉搜索树 (C++)
  4. Caffe中Interp层的使用
  5. [置顶] C语言中各种数据类型的长度 sizeof char, short, int, long, long long
  6. java 跳转虚拟目录_java tomcat虚拟目录的深入了解
  7. deepin20自带c语言,deepin 20.1终于找到你-国产操作系统deepin之初体验
  8. Java基础题笔记1
  9. teststand调用python模块_NI TestStand 2019下载-测试管理软件NI TestStand 2019下载v19.0.1 官方版-西西软件下载...
  10. 王者服务器延迟高,王者荣耀延迟高卡住不动怎么办 卡顿的解决方法汇总
  11. [No000013F]WPF学习之X名称空间详解
  12. 在Apache上调试Asp.net 1.1/2.0代码
  13. 不小心合并了icloud通讯录_苹果手机号码被删除如何恢复?找回通讯录的具体步骤...
  14. 透过“简书钻”来探究简书的商业模式转变
  15. python源码中的学习笔记_第10章_面向对象的特征、特殊方法与属性、以及深浅拷贝
  16. JAVA虚拟机环境如何在IMX6平台上搭建呢?
  17. Cadence16.6版本下Pspice仿真的使用
  18. Redis Cluster集群
  19. 使用HttpClient的时候报错java.io.IOException: Attempted read from closed stream
  20. TP5 控制器命名大小写问题

热门文章

  1. 《大秦赋》热血霸气台词场景记录
  2. [踩坑记录]VS2017+大恒MER-131-210U3C相机
  3. 成都Uber优步司机奖励政策(2月25日)
  4. 瀚高数据库查询表字段及备注
  5. Fixture证书权限导致CSR申请证书失败的问题 [已解决]
  6. 第62次上IM课(IMO71:How to use Adverb)
  7. 通达信交易服务器修改,GitHub - sjj6love/TdxTradeServer: TongDaXin Tarde Server 通达信交易服务器...
  8. Nlite后期处理技术小结(第三次更新...全文完)(by bluewind)
  9. 【防火墙_动态路由-OSPF】
  10. 脱壳总结之 - upx,aspack, FSG,PECompact2.X,WinUpack脱壳