文档章节

Java日志那点儿事儿

路小磊
 路小磊
发布于 2015/12/11 21:07
字数 1628
阅读 450
收藏 20
点赞 1
评论 6

##前言

日志这东西在语言里算基础组件了吧,可惜Java界第三方框架向来比原生组件好用也是事实,缺点是框架太多混战江湖,今天我们就理一理这些日志框架。Java的日志框架分为门面(Facade),或者叫通用日志接口,还有日志实现。日志接口不用说,就是定下的日志方法规范,需要具体日志组件去实现的(为啥Sun当年没有定义这东西,看看JPA、JDBC、JMS这些规范定义的多好,或者定义了被抛弃了?)。日志实现就是具体的日志组件了,可以实现日志打印到控制台、文件、数据库等等。下面咱们就具体说说这些东西。

Java日志框架分类

日志门面(Facade)

  • Slf4j

全称Simple Logging Facade for JAVA,真正的日志门面,只提供接口方法,当配合特定的日志实现时,需要引入相应的桥接包

  • Common-logging

Apache提供的一个通用的日志接口,common-logging会通过动态查找的机制,在程序运行时自动找出真正使用的日志库,自己也自带一个功能很弱的日志实现。

差别:

  1. Common-logging动态查找日志实现(程序运行时找出日志实现),Slf4j则是静态绑定(编译时找到实现),动态绑定因为依赖ClassLoader寻找和载入日志实现,因此类似于OSGI那种使用独立ClassLoader就会造成无法使用的情况。(呵呵,我一个插件用一个日志框架不行啊,土豪多任性,不过说实话,没用过OSGI,这个我还真没有概念)
  2. Slf4j支持参数化的log字符串,避免了之前为了减少字符串拼接的性能损耗而不得不写的if(logger.isDebugEnable()),现在你可以直接写:logger.debug(“current user is: {}”, user)。

日志实现

  • Log4j

Log4j可能是Java世界里最出名的日志框架了,支持各种目的地各种级别的日志输出,从我刚接触日志就知道这个框架(呵呵,我一直不知道还有JDK Logging这个东西)。最近(也不近了……)Log4j2发布正式版了,没看到谁用,听说也很不错。

  • LogBack

Log4j作者的又一力作(听说是受不了收费文档搞了个开源的,不需要桥接包完美适配Slf4j),个人感觉迄今为止最棒的日志框架了,一直都在用,配置文件够简洁,性能足够好(估计是看自己的Log4j代码差劲了,更新不能解决问题,直接重构了)。

  • JDK Logging 从JDK1.4开始引入,不得不说,你去Google下这个JDK自带的日志组件,并不如Log4j和LogBack之类好用,木有配置文件,日志级别不好理解,想顺心的用估计还得自己封装下,总之大家已经被Log4j惯坏了,JDK的设计并不能被大家认同,唯一的优点我想就是不用引入新额jar包了。

为什么会有门面

看了以上介绍,如果你不是混迹(深陷)Java多年的老手,估计会蒙圈儿了吧,那你肯定会问,要门面干嘛。有了手机就有手机壳、手机膜,框架也一样,门面的作用更多的还是三个字:解耦合。说白了,加入一个项目用了一个日志框架,想换咋整啊?那就一行一行的找日志改呗,想想都是噩梦。于是,门面出来了,门面说啦, 你用我的格式写日志,把日志想写哪儿写哪儿,例如Slf4j-api加上后,想换日志框架,直接把桥接包一换就行。方便极了。

说实话,现在Slf4j基本可以是Java日志的一个标准了,按照它写基本可以实现所有日志实现通吃,但是就有人不服,还写了门面的门面(没错,这个人就是我)。

门面的门面

如果你看过Netty的源码,推荐你看下io.netty.util.internal.logging这个包里内容,会发现Netty又对日志封装了一层,于是灵感来源于此,我也对各大日志框架和门面做了封装。

Hutool-log模块

无论是Netty的日志模块还是我的Hutool-log模块,思想类似于Common Logging,做动态日志实现查找,然后找到相应的日志实现来写入日志,核心代码如下:

/**

 * 决定日志实现

 * @return 日志实现类

 */
public static Class<? extends AbstractLog> detectLog(){
	List<Class<? extends AbstractLog>> logClassList = Arrays.asList(
			Slf4jLog.class,
			Log4jLog.class, 
			Log4j2Log.class, 
			ApacheCommonsLog.class, 
			JdkLog.class
	);
	
	for (Class<? extends AbstractLog> clazz : logClassList) {
		try {
			clazz.getConstructor(Class.class).newInstance(LogFactory.class).info("Use Log Framework: [{}]", clazz.getSimpleName());
			return clazz;
		} catch (Error | Exception e) {
			continue;
		}
	}
	return JdkLog.class;
}

详细代码可以看这里

说白了非常简单,按顺序实例化相应的日志实现,如果实例化失败(一般是ClassNotFoundException),说明jar不存在,那实例化下一个,通过不停的尝试,最终如果没有引入日志框架,那使用JDK Logging(这个肯定会有的),当然这种方式也和Common-logging存在类似问题,不过不用到跨ClassLoader还是很好用的。

对于JDK Logging,我也做了一些适配,使之可以与Slf4j的日志级别做对应,这样就将各个日志框架差异化降到最小。另一方面,如果你看过我的这篇日志,那你一定了解了我的类名自动识别功能,这样大家在复制类名的时候,就不用修改日志的那一行代码了,在所有类中,日志的初始化只有这一句:

Log log = LogFactory.get();

是不是简洁简洁又简洁?实现方式也很简单:

/**
 * @return 获得调用者的日志
 */
public static Log get() {
	return getLog(new Exception().getStackTrace()[1].getClassName());
}

通过堆栈引用获得当前类名。

作为一个强迫症患者,日志接口我也会定义的非常处女座:

/**
 * 日志统一接口
 * 
 * @author Looly
 *
 */
public interface Log extends TraceLog, DebugLog, InfoLog, WarnLog, ErrorLog

这样就实现了单一使用,各个日志框架灵活引用的作用了。好了,今天就到这里了,有问题或者吐槽都已给我留言~~

© 著作权归作者所有

共有 人打赏支持
路小磊

路小磊

粉丝 279
博文 53
码字总数 39918
作品 5
乌海
程序员
加载中

评论(6)

紫泉-kwer
紫泉-kwer
眼前一亮 非常感谢
J-Fla
J-Fla

引用来自“路小磊”的评论

引用来自“开源中国大Boss”的评论

qq

做个备注
路小磊
路小磊

引用来自“开源中国大Boss”的评论

qq

J-Fla
J-Fla
qq
路小磊
路小磊

引用来自“汪林”的评论

1379
汪林
汪林
1379
java.lang.OutOfMemoryError: Java heap space

Exception in thread "main" java.lang.OutOfMemoryError: Java heap space 今天我想说说这个有趣的问题,这的确是个让人费解的是error 问题来源: 这个问题一般会出在myecplise 和ecplise ,...

soul_mate
2014/05/03
0
0
毕业设计记录(一)配置web开发环境(java)

本打算跟着总结,写好日志。但是真正忙的时候没有时间总结,有空时又爱玩,只能抽空总结。今天是毕业设计做了一小部分,不知道下一阶段咋整了,所以总结。 首先毕业设计做的事web应用,用的j...

jiler
2014/05/08
0
0
5年时间,Java程序员如何从小白晋升为大牛

程序员之言 2018-06-25 在程序界流行着一种默认的说法叫“黄金5年”,也就是一个程序员从入职的时候算起,前五年的选择直接影响着整个职业生涯中的职业发展方向和薪资走向。 因此如何走好这5...

ydx20151111
06/25
0
0
IBM和SAP开源其JVM诊断工具

IBM最近发布了其Java诊断工具套件,该套件包含如下工具:面向Java的产品转储分析器(Dump Analyzer)、处理垃圾收集(GC,即Garbage Collection)的Extensible Verbose Toolkit和Java锁分析器...

JavaGG
2010/03/24
0
0
【转】Java Crash原因汇总

如果是Java进程不知道什么原因退出或被杀死,想要分析具体原因,一般来说分下面几步: 1. 拿到Java应用程序的日志文件 2. 查找JVM的致命错误日志 3. 查找操作系统的core dump文件 4. 使用Dtr...

mj4738
2011/12/04
0
0
数据库中间件 Sharding-JDBC 源码分析 —— 分布式事务(一)之最大努力型

摘要: 原创出处 http://www.iocoder.cn/Sharding-JDBC/transaction-bed/ 「芋道源码」欢迎转载,保留摘要,谢谢! 本文主要基于 Sharding-JDBC 1.5.0 正式版 1. 概述 2. 最大努力送达型 3. 柔...

芋道源码
2017/11/05
0
1
Tomcat介绍,安装jdk,安装tomcat,配置Tomcat监听80端口

Tomcat介绍 Tomcat是Apache软件基金会(Apache Software Foundation)的Jakarta项目中的一个核心项目,由Apache、Sun和其他一些公司及个人共同开发而成。 java程序写的网站用tomcat+jdk来运行...

TaoXu
昨天
0
0
ThreadLocal的那些事儿

什么是ThreadLocal? 顾名思义它是local variable(线程局部变量)。 它的功用非常简单,就是为每一个使用该变量的线程都提供一个变量值的副本,是每一个线程都可以独立地改变自己的副本,而...

陶邦仁
2012/09/07
0
2
Was(WebSphere)不能正常打印程序日志问题

【was日志配置】 服务器 -- 服务器类型 ——webSphere Appliaction server -- 选择sever -- java和进程管理 -- 进程定义 -- java虚拟机 ,调整“通用JVM参数”。 例如Log4j日志变量名称为:打...

gerry_pang
2014/01/09
0
0
Linux后台运行java -jar

问题描述 我打好的jar包,放在服务器上之后,在windows里面用xshell打开一个连接,然后运行java -jar 。。。。执行这个jar文件,当我关闭这个链接的时候为什么程序停止了呢? 打开XShell连接...

汪纬
04/12
0
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

实现异步有哪些方法

有哪些方法可以实现异步呢? 方式一:java 线程池 示例: @Test public final void test_ThreadPool() throws InterruptedException { ScheduledThreadPoolExecutor scheduledThre......

黄威
今天
0
0
linux服务器修改mtu值优化cpu

一、jumbo frames 相关 1、什么是jumbo frames Jumbo frames 是指比标准Ethernet Frames长的frame,即比1518/1522 bit大的frames,Jumbo frame的大小是每个设备厂商规定的,不属于IEEE标准;...

六库科技
今天
0
0
牛客网刷题

1. 二维数组中的查找(难度:易) 题目描述 在一个二维数组中(每个一维数组的长度相同),每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个函数,输入...

大不了敲一辈子代码
今天
0
0
linux系统的任务计划、服务管理

linux任务计划cron 在linux下,有时候要在我们不在的时候执行一项命令,或启动一个脚本,可以使用任务计划cron功能。 任务计划要用crontab命令完成 选项: -u 指定某个用户,不加-u表示当前用...

黄昏残影
昨天
0
0
设计模式:单例模式

单例模式的定义是确保某个类在任何情况下都只有一个实例,并且需要提供一个全局的访问点供调用者访问该实例的一种模式。 实现以上模式基于以下必须遵守的两点: 1.构造方法私有化 2.提供一个...

人觉非常君
昨天
0
0
《Linux Perf Master》Edition 0.4 发布

在线阅读:https://riboseyim.gitbook.io/perf 在线阅读:https://www.gitbook.com/book/riboseyim/linux-perf-master/details 百度网盘【pdf、mobi、ePub】:https://pan.baidu.com/s/1C20T......

RiboseYim
昨天
1
0
conda 换源

https://mirrors.tuna.tsinghua.edu.cn/help/anaconda/ conda config --add channels https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/free/conda config --add channels https://mir......

阿豪boy
昨天
1
0
Confluence 6 安装补丁类文件

Atlassian 支持或者 Atlassian 缺陷修复小组可能针对有一些关键问题会提供补丁来解决这些问题,但是这些问题还没有放到下一个更新版本中。这些问题将会使用 Class 类文件同时在官方 Jira bug...

honeymose
昨天
0
0
非常实用的IDEA插件之总结

1、Alibaba Java Coding Guidelines 经过247天的持续研发,阿里巴巴于10月14日在杭州云栖大会上,正式发布众所期待的《阿里巴巴Java开发规约》扫描插件!该插件由阿里巴巴P3C项目组研发。P3C...

Gibbons
昨天
1
0
Tomcat介绍,安装jdk,安装tomcat,配置Tomcat监听80端口

Tomcat介绍 Tomcat是Apache软件基金会(Apache Software Foundation)的Jakarta项目中的一个核心项目,由Apache、Sun和其他一些公司及个人共同开发而成。 java程序写的网站用tomcat+jdk来运行...

TaoXu
昨天
0
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部