Java中的日志框架

xiaoxiao2021-02-28  18

java中,比较常见的日志框架有slf4j log4j logback 以及common-logging。

 

slf4j:全称为Simple Logging Facade for JAVA,java简单日志门面。是对不同日志框架提供的一个门面封装,实现了日志框架一些通用的api.而log4j logback是具体实现了的日志框架,slf4j提供了日志的统一接口,而不用去考虑日志的具体实现,也就是说,使用slf4j,你可以随意的切换log的实现,可以是log4j logback,或者是jdk中的sun logger。可以在部署的时候不修改任何配置即可接入一种日志实现方案。但是,他在编译时静态绑定真正的Log库。使用SLF4J时,如果你需要使用某一种日志实现,那么你必须选择正确的SLF4J的jar包的集合(各种桥接包)。

使用slf4j的常见代码:

Log logger = LogFactory.getLog(this.getClass());  

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

 

log4j :是具体实现了的日志框架,是apache实现的一个开源日志组件,log4j不是对slf4j的原生实现,所以slf4j api在调用log4j时需要一个适配层

 

 

Logback:是由log4j创始人设计的又一个开源日志组件。logback当前分成三个模块:logback-core,logback- classic和logback-access。logback-core是其它两个模块的基础模块。logback-classic是log4j的一个 改良版本。此外logback-classic完整实现slf4,使你可以很方便地更换成其它日志系统

 

common-logging:common-logging类似于slf4j,不过common-logging只是对log4j 和sun logger的封装,common-logging只是对log4j 和sun logger的统一接口,可以支持切换具体的日志实现,但只能在log4j 和sun logger中切换。是apache提供的一个通用的日志接口。用户可以自由选择第三方的日志组件作为具体实现,像log4j,或者jdk自带的logging, common-logging会通过动态查找的机制,在程序运行时自动找出真正使用的日志库。当然,common-logging内部有一个Simple logger的简单实现,但是功能很弱。所以使用common-logging,通常都是配合着log4j来使用。使用它的好处就是,代码依赖是common-logging而非log4j, 避免了和具体的日志方案直接耦合,在有必要时,可以更改日志实现的第三方库。

使用common-logging的常见代码:

 Log logger = LogFactory.getLog(this.getClass())

动态查找原理: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.xml ,则commons-logging 就会使log4j 使用正常,而代码里不需要依赖任何log4j 的代码

 

Log4j LogBack 比较

在企业级开发中,大多使用logback来替换log4j,logback 重写了内部的实现,在某些特定的场景上面,比log4j效率要高很多。logback 是对于slf4j的原生实现。无论是选择log4j还是logback实现日志,在slf4j下,都不需要过多的配置,只需要在classpath路径下,存在相应的文件,就会自动加载对应的日志。

 

logback在spring mvc中的配置

 

<?xml version="1.0" encoding="UTF-8" ?>

<configuration scan="false">

<property name="LOG_HOME" value="/data/wwwroot/log"/>

<property name="app.name" value="***"/>

<contextName></contextName>

 

<!-- console -->

<appender name="console" class="ch.qos.logback.core.ConsoleAppender">

<encoder>

<pattern>%d{HH:mm:ss} [%thread] %-5level %logger{100} - %msg%n</pattern>

</encoder>

</appender>

 

<!-- communication log -->

<appender name="communicationRolling" class="ch.qos.logback.core.rolling.RollingFileAppender">

<file>${LOG_HOME_COMMUNICATION}.log</file>

<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">

<fileNamePattern>${LOG_HOME_COMMUNICATION}-%d{yyyy-MM-dd}.zip</fileNamePattern>

<maxHistory>30</maxHistory>

<!-- <TimeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">

<MaxFileSize>30MB</MaxFileSize>

</TimeBasedFileNamingAndTriggeringPolicy> -->

</rollingPolicy>

<encoder><pattern>%d{HH:mm:ss} %-5level %logger{100} - %msg%n</pattern></encoder>

</appender>

 

<!-- error -->

<appender name="errorRolling" class="ch.qos.logback.core.rolling.RollingFileAppender">

<filter class="ch.qos.logback.classic.filter.LevelFilter">

<level>ERROR</level>

<onMatch>ACCEPT</onMatch>

<onMismatch>DENY</onMismatch>

</filter>

<file>${LOG_HOME_ERROR}.log</file>

<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">

<fileNamePattern>${LOG_HOME_ERROR}-%d{yyyy-MM-dd}.zip</fileNamePattern>

<maxHistory>30</maxHistory>

</rollingPolicy>

<encoder><pattern>%d{HH:mm:ss} %-5level %logger{100} - %msg%n</pattern></encoder>

</appender>

 

<logger name="com.communication" level="DEBUG">

<appender-ref ref="communicationRolling"/>

</logger>

 

<root level="ERROR">

<appender-ref ref="errorRolling" />

</root>

</configuration>

 

在spring boot中,可以使用springProfile来依据运行环境,控制不同的输出,但是在spring mvc中不支持

<!-- dev environment -->

<springProfile name="dev">

<root level="INFO">

<appender-ref ref="console" />

</root>

</springProfile>

 

<!-- prod environment -->

<springProfile name="test,prod">

<root level="INFO">

<appender-ref ref="orderRolling" />

</root>

</springProfile>

 

转载请注明原文地址: https://www.6miu.com/read-2650057.html

最新回复(0)