深入分析Java的内置日志API(java.util.logging)(一)
简介
任何的软件系统,日志都是非常重要的一部分。良好统一的日志规范会大大提高应用程序的可维护性、可靠性,并进而提高开发效率,指导业务。在早期,Java工程师往往都是利用 System.err.println 或 System.out.println将 Java 应用内部的状态信息或错误消息打印到系统的控制台中,这种简易的保存方式显然无法满足保存日志信息所需的持久性和便利性等要求。所以,SUN 公司在发布 JDK 1.4 时,在 java.util.logging 包提供了一个日志框架。通常,直接使用 JUL 表示该框架。利用 JUL 的 API,Java 工程师可以输出不同重要级别(比如 error、info 和 debug)的日志信息到一个集中的位置(比如 rotating file)。同时,Java 工程师可以完全控制输出日志信息的重要级别和输出格式。
框架概述
笔者认为,学习任何一门新技术或新概念的最佳方式都是 先整体后细节。所以,笔者先抛出 JUL 的框架概述图:

- Application 将多种级别(level)的日志信息传递给 Logger 对象;
- Logger 对象使用 Level 和 Filter 对接受到的日志信息进行过滤;将日志信息转换成 LogRecord 对象后传递给 Handler 对象;
- Handler 对象使用 Level 和 Filter 对接受到的 LogRecord 对象进行过滤;并使用 Formatter 格式化 LogRecord 对象并输出到外部的文件或者数据库中。
- Logger 对象之间存在着父子层级关系,这种层级关系是通过 Logger 对象的名称来决定。
LogManager(日志管理器)
在 JUL 被 JVM 加载时,会有一个 LogManager 对象被创建出来作为全局组件而存在。这个全局组件主要负责创建和管理 Logger 对象,同时生成和维护全局的日志配置信息,这个全局配置信息可能是从配置文件中读取而来,也可能是从配置类读取而来。在默认配置的情况下,LogManager 只创建一个Level 为 Level.INFO 的 ConsoleHandler,该 ConsoleHandler 的日志信息输出目的地是 System.err。同时,这个 ConsoleHandle 属于 LogManager 中的 root logger(根记录器)。
在 Java 应用所使用的某个 JVM 中,有且仅有一个 LogManager 对象存在。通常,Java 工程师可以使用如下的代码获取该 LogManager 实例对象:
LogManager manager = LogManager.getLogManager();
通常情况下,Java 工程师都不要与该 LogManager 对象直接交互,除非某些特殊情形。比如重新加载配置类或配置文件,这种情况可以使用如下所示的实例代码:
// 重读配置类或配置文件
manager.readConfiguration();
// 重读特定位置的配置类与配置文件
manager.readConfiguration(inputStream);
通过使用 LogManager 的 getLoggingMXBen() 方法,可以获取一个 MXBen(Java Management Extensions)。简单地实例代码如下:
LoggingMXBean mxBean = manager.getLoggingMXBen();
当然,LogManager 还有很多其他的方法与特性,有兴趣的同学可以进一步查看 JavaDoc 或者源码。
Logger(日志记录器)
JUL 的主要入口类是 java.util.Logger。进行日志记录的第一步就是创建一个 Logger 对象:
Logger logger = Logger.getLogger("www.tiantianbianma.com");
传递给 Logger 类中 getLogger 工厂方法的字符串 “www.tiantianbianma.com” 就是所创建的 Logger 对象的名称。
在实际的项目开发中,一般的做法是使用当前 Java 类的名称或所在包的名称作为 Logger 对象的名称。一个常见的示例代码如下:
public class Application {
Logger logger = Logger.getLogger(this.getClass().getName());
}
如果需要一个静态的 Logger 对象,示例代码如下:
public class Application {
static Logger logger = Logger.getLogger(Application.class.getName());
}
如果需要查询 Logger 对象的名称,可以使用 getName() 方法。
String loggerName = logger.getName();
使用 Logger 对象进行日志记录的方式很多,部分方式的示例代码如下:
log (Level level, String message);
log (Level level, String message, Object param);
logp (Level level, String sourceClass, String sourceMethod, String msg);
logrb (Level level, String sourceClass, String sourceMethod, String bundle, String msg);
entering (String sourceClass, String sourceMethod);
...
深入分析Java的内置日志API(java.util.logging)(一)的更多相关文章
- java 并发——内置锁
坚持学习,总会有一些不一样的东西. 一.由单例模式引入 引用一下百度百科的定义-- 线程安全是多线程编程时的计算机程序代码中的一个概念.在拥有共享数据的多条线程并行执行的程序中,线程安全的代码会通过同 ...
- java script 内置对象
java script 内置对象 Date 日期对象 字符串对象 定义字符串的方法就是直接赋值 使用 String 对象的 toUpperCase() 方法来将字符串小写字母转换为大写,反之 toLo ...
- JDK内置日志系统
1.Java应用中的日志功能 ================= 一般的Java应用程序中都有记录日志的需求,目前主流的记录日志的方法是在应用程序中引入log4j,用log4j来生成日志.其实,JDK ...
- ASP.NET Core 2.1 : 十二.内置日志、使用Nlog将日志输出到文件
应用离不开日志,虽然现在使用VS有强大的调试功能,开发过程中不复杂的情况懒得输出日志了(想起print和echo的有木有),但在一些复杂的过程中以及应用日常运行中的日志还是非常有用. ASP.NET ...
- ThinkPHP内置日志记录
ThinkPHP内置日志记录日志记录http://document.thinkphp.cn/manual_3_2.html#log 日志的处理工作是由系统自动进行的,在开启日志记录的情况下,会记录下允 ...
- MyBatis 内置日志工厂基于运行时自省机制选择合适的日志工具
mybatis – MyBatis 3 | 日志 http://www.mybatis.org/mybatis-3/zh/logging.html MyBatis 内置日志工厂基于运行时自省机制选择合 ...
- 第七节:Asp.Net Core内置日志和整合NLog(未完)
一. Asp.Net Core内置日志 1. 默认支持三种输出方式:控制台.调试(底部输出窗口).EventSource,当然也可以在Program类中通过logging.ClearProviders ...
- 利用Java内置的API开发JMX功能
一.什么是JMX JMS是一种Java规范,定义了如何管理一个软件系统(或应用程序)的规范. 对于一个简单的应用程序,该程序本身不需要被管理.但如果是开发的一个复杂系统(如一个电商平台.一个企业内部管 ...
- java synchronized内置锁的可重入性和分析总结
最近在读<<Java并发编程实践>>,在第二章中线程安全中降到线程锁的重进入(Reentrancy) 当一个线程请求其它的线程已经占有的锁时,请求线程将被阻塞.然而内部锁是可重 ...
随机推荐
- VR上天了!全景商业化落地了!——VR全景智慧城市
几年前,VR创业公司SpaceVR就启动了旨在将宇航员视觉体验带给普通人的虚拟现实(VR)项目.SpaceVR计划将VR相机卫星送入太空,并将相机拍摄到的太空视频发送回地球,从而让VR用户身临其境地看 ...
- "php-cgi.exe - FastCGI 进程意外退出" 解决办法
问题描述: win7下iis中php-cgi.exe - FastCGI 进程意外退出 错误提示: HTTP 错误 500.0 - Internal Server Error D:\phpStudy\ ...
- Windows 7 下安装mysql-5.7.18-winx64.zip
mysql-5.7以后压缩包安装有了不小的变化 第一步:到官网下载https://dev.mysql.com/downloads/mysql/ 第二步:解压到一个文件夹 第三步:配置环境变量 把;%M ...
- javaSE_06Java中的数组(array)-提高练习
1.求1!+2!+3!+···+30!的和,定义一个方法 public class Test1{ public static void main(String[] args){ //1.求1!+2!+ ...
- 创建的docker容器时间显示错误/date错误/时区错误
前几天在测试应用的功能时,发现存入数据库中的数据create_time或者update_time字段总是错误,其他数据都是正常的,只有关于时间的字段是错误的. 进入linux服务器中查看,也没有任何的 ...
- 深入理解循环队列----循环数组实现ArrayDeque
我们知道队列这种数据结构的物理实现方式主要还是两种,一种是链队列(自定义节点类),另一种则是使用数组实现,两者各有优势.此处我们将要介绍的循环队列其实是队列的一种具体实现,由于一般的数组实现的队列结构 ...
- dedecms后台添加新变量和删除变量的方法
下面由做网站为大家来介绍dedecms后台添加新变量和删除变量的方法 添加新变量是做什么用的?答:可以在模板内调用的东东. 一.进入网站织梦(Dedecms)后台(以dede5.5为例),依次打开系统 ...
- 简单介绍phpcms以及phpcms如何安装?
一.先大体介绍一下phpcms,及存放位置 1.将phpcms放在www目录下的phpcms,并解压 其中,readme 没什么用,重要的是install_package; 2.打开install_p ...
- [转] 传说中的WCF(2):服务协定的那些事儿
上一篇文章中,我们抛出了N个问题:WCF到底难不难学?复杂吗?如果复杂,可以化繁为简吗? 其实,这些问题的答案全取决于你的心态,都说“态度决定一切”,这句话,不知道各位信不信,反正我是信了.首先,敢于 ...
- python 打印文件里的内容
>>> import os >>> os.chdir ('e:/')>>> data=open('text.txt')>>> f ...