各个日志框架的简介以及使用规范

各个日志框架的简介以及使用规范

目的

规范java程序员对于日志的使用规范

背景

首先看下我们现在的项目使用日志的状况

引入的依赖

使用方式

      
      
1
2
3
4
5
6
      
      
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
private Log log = LogFactory.getLog(getClass());
log.info( "【PUSH-mongodb】查询一周未读消息成功对应的userId="+appPushMessage.getUserId());
      
      
1
2
3
4
5
      
      
import org.apache.log4j.Logger;
private Logger communityLog = Logger.getLogger( "communityLog");
communityLog.info( "【xx】用户:" + communityStory.getUserId() + "xxxxxx:" + JSONObject.toJSONString(communityStory));

可见,我们引入的日志框架很多,然而却基本都没用起来,而且日志打印可读性比较低

日志框架的分类

基于API的日志框架

  • slf4j
  • common-logging

基于实现的日志框架

  • jdk-logging
  • log4j
  • logback
  • log4j 2

各个日志框架的简介

common-logging

common-logging是apache提供的一个通用的日志接口。用户可以自由选择第三方的日志组件作为具体实现,像 log4j,或者jdk自带的logging, common-logging会通过动态查找的机制,在程序运行时自动找出真正使用的日志库。使用它的好处就是,代码依赖是common-logging而非log4j, 避免了和具体的日志方案直接耦合。

      
      
1
2
3
4
5
6
      
      
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
public class A {
private static Log logger = LogFactory.getLog( "log");
}

动态查找原理

Log 是一个接口声明。LogFactory 的内部会去装载具体的日志系统,并获得实现该Log 接口的实现类。

LogFactory 内部装载日志系统的流程如下:
  1. 首先,寻找org.apache.commons.logging.LogFactory 属性配置。
  2. 否则,利用JDK1.3 开始提供的service 发现机制,会扫描classpah 下的META-INF/services/org.apache.commons.logging.LogFactory文件,若找到则装载里面的配置,使用里面的配置。
  3. 否则,从Classpath 里寻找commons-logging.properties ,找到则根据里面的配置加载。
  4. 否则,使用默认的配置:如果能找到Log4j 则默认使用log4j 实现,如果没有则使用JDK14Logger 实现,
    再没有则使用commons-logging 内部提供的SimpleLog 实现。

从上述加载流程来看,只要引入了log4j 并在classpath 配置了log4j的配置 ,则commons-logging 就会使log4j 使用正常,而代码里不需要依赖任何log4j 的代码。

slf4j

slf4j全称为Simple Logging Facade for JAVA,java简单日志门面。类似于Apache Common-Logging,是对不同日志框架提供的一个门面封装,可以在部署的时候不修改任何配置即可接入一种日志实现方案。但是,他在编译时静态绑定真正的Log库。使用slf4j时,如果你需要使用某一种日志实现,那么你必须选择正确的slf4j的jar包的集合(各种桥接包)。

      
      
1
2
3
4
5
6
      
      
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class A {
private static Logger logger = LoggerFactory.getLogger( "log");
}
slf4j静态绑定原理

SLF4J 会在编译时会绑定import org.slf4j.impl.StaticLoggerBinder; 该类里面实现对具体日志方案的绑定接入。任何一种基于slf4j 的实现都要有一个这个类。如:org.slf4j.slf4j-log4j12-1.5.6: 提供对 log4j 的一种适配实现。注意:如果有任意两个实现slf4j 的包同时出现,那么就可能出现问题。

slf4j 与 common-logging 比较

common-logging通过动态查找的机制,在程序运行时自动找出真正使用的日志库。由于它使用了ClassLoader寻找和载入底层的日志库, 导致了象OSGI这样的框架无法正常工作,因为OSGI的不同的插件使用自己的ClassLoader。 OSGI的这种机制保证了插件互相独立,然而却使Apache Common-Logging无法工作。

slf4j在编译时静态绑定真正的Log库,因此可以再OSGI中使用。另外,slf4j 支持参数化的log字符串,避免了之前为了减少字符串拼接的性能损耗而不得不写的if(logger.isDebugEnable()),现在你可以直接写:logger.debug(“current user is: {}”, user)。拼装消息被推迟到了它能够确定是不是要显示这条消息的时候,但是获取参数的代价并没有幸免。

log4j

log4j很久没有更新了,现在国外基本是没有开发者用这个框架了,更重要的是原作者也早就已经不再护log4j,推出了logback以及log4j2为了与时俱进,我们也已经抛弃log4j,使用logback或者是log4j2

logback

Logback,一个“可靠、通用、快速而又灵活的Java日志框架”。logback当前分成三个模块:logback-corelogback- classiclogback-accesslogback-core是其它两个模块的基础模块。logback-classiclog4j的一个改良版本。此外logback-classic完整实现SLF4J API使你可以很方便地更换成其它日志系统如log4jJDK Logginglogback-access访问模块与Servlet容器集成提供通过Http来访问日志的功能。

选择logback的理由
  1. logback比log4j要快大约10倍,而且消耗更少的内存。
  2. logback-classic模块直接实现了SLF4J的接口,所以我们迁移到logback几乎是零开销的。
  3. logback不仅支持xml格式的配置文件,还支持groovy格式的配置文件。相比之下,Groovy风格的配置文件更加直观,简洁。
  4. logback-classic能够检测到配置文件的更新,并且自动重新加载配置文件。
  5. logback能够优雅的从I/O异常中恢复,从而我们不用重新启动应用程序来恢复logger。
  6. logback能够根据配置文件中设置的上限值,自动删除旧的日志文件。
  7. logback能够自动压缩日志文件。
  8. logback能够在配置文件中加入条件判断(if-then-else)。可以避免不同的开发环境(dev、test、uat…)的配置文件的重复。
  9. logback带来更多的filter。
  10. logback的stack trace中会包含详细的包信息。
  11. logback-access和Jetty、Tomcat集成提供了功能强大的HTTP-access日志。

log4j2

log4j2也是log4j的作者出的新的一种日志框架,log4j2在各个方面都与Logback非常相似,那么为什么我们还需要log4j2呢?

  1. 插件式结构。Log4j 2支持插件式结构。我们可以根据自己的需要自行扩展Log4j 2. 我们可以实现自己的appender、logger、filter。
  2. 配置文件优化。在配置文件中可以引用属性,还可以直接替代或传递到组件。而且支持json格式的配置文件。不像其他的日志框架,它在重新配置的时候不会丢失之前的日志文件。
  3. Java 5的并发性。Log4j 2利用Java 5中的并发特性支持,尽可能地执行最低层次的加锁。解决了在log4j 1.x中存留的死锁的问题。
  4. 异步logger。Log4j 2是基于LMAX Disruptor库的。在多线程的场景下,和已有的日志框架相比,异步的logger拥有10倍左右的效率提升。
      
    官方建议一般程序员查看的日志改成异步方式,一些运营日志改成同步。日志异步输出的好处在于,使用单独的进程来执行日志打印的功能,可以提高日志执行效率,减少日志功能对正常业务的影响。

基于以上,java后台日志规范如下:

使用框架

由于slf4j是编译时静态绑定,同时支持{}占位符进行日志打印,所以我们最终使用slf4jlog4j进行桥接的形式进行日志打印,后期甚至可以升级log4j至logback或者log4j2,就只需要修改下配置文件就OK了

使用规范

pom引入
      
      
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
      
      
<!-- slf4j -->
<dependency>
<groupId>org.slf4j </groupId>
<artifactId>slf4j-api </artifactId>
<version>1.7.12 </version>
</dependency>
<!-- slf4j-log4j -->
<dependency>
<groupId>org.slf4j </groupId>
<artifactId>slf4j-log4j12 </artifactId>
<version>1.7.12 </version>
</dependency>
<!-- log4j -->
<dependency>
<groupId>log4j </groupId>
<artifactId>log4j </artifactId>
<version>1.2.17 </version>
</dependency>
日志打印
      
      
1
2
3
4
5
6
7
8
9
10
11
12
13
      
      
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@Component
public class CommunityBusinessImpl implements CommunityBusiness {
private Logger communityLog = LoggerFactory.getLogger( "communityLog");
@Override
public void sendStory() {
communityLog.info( "【xxx】【xxxx】【用户id:{}】【动态id:{}】", communityStory.getUserId(), communityStory.getId());
}
}
打印规范

info日志

      
      
1
      
      
log.info( "【业务】【功能】【功能标识位:{}】日志信息", "占位的值");

error

      
      
1
      
      
log.error( "【业务】【功能】【功能标识位:{}】错误信息", "占位的值", e)


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值