揭秘java日志系统

概念

 

日志框架:是一种日志接口,不负责具体的日志输出形式(有点类似于JDBC),可以灵活的切换日志输出形式。常见的日志框架有slf4j、jcl,只提供Logger、LoggerFactory等接口

 

日志系统:是应用实际使用的日志工具,主要有log4j,jul,logback等。一般在程序中应该避免直接使用,可以保证程序具有一定的灵活性。

 

 

Logger:日志输出实例,包含Appender和Layout
Appender:日志输出目标,如控制台,文件,数据库等。多个Appender可以被关联到任何Logger上,所以可以到多个输出文件上记录相同的信息。
Layout:定义日志输出格式:时间戳、线程名称、日志级别、日志内容、对应输出该日志的类、对应输出该日志的方法、行号及MDC信息

 

Level : 日志级别,通过配置不同的日志界别来打印不同的日志信息。

 

 

历史

 

 

1996年早期,欧洲安全电子市场项目组决定编写它自己的程序跟踪API(Tracing API)。经过不断的完善,这个API终于成为一个十分受欢迎的Java日志软件包,即Log4j。后来Log4j成为Apache基金会项目中的一员。

期间Log4j近乎成了Java社区的日志标准。据说Apache基金会还曾经建议sun引入Log4j到java的标准库中,但Sun拒绝了。

2002年Java1.4发布,Sun推出了自己的日志库JUL(Java Util Logging),其实现基本模仿了Log4j的实现。在JUL出来以前,log4j就已经成为一项成熟的技术,使得log4j在选择上占据了一定的优势。

接着,Apache推出了Jakarta Commons Logging,JCL只是定义了一套日志接口(其内部也提供一个Simple Log的简单实现),支持运行时动态加载日志组件的实现,也就是说,在你应用代码里,只需调用Commons Logging的接口,底层实现可以是log4j,也可以是Java Util Logging。

后来(2006年),Ceki Gülcü不适应Apache的工作方式,离开了Apache。然后先后创建了slf4j(日志门面接口,类似于Commons Logging)和Logback(Slf4j的实现)两个项目,并回瑞典创建了QOS公司,QOS官网上是这样描述Logback的:The Generic,Reliable Fast&Flexible Logging Framework(一个通用,可靠,快速且灵活的日志框架),他们并不属于Apache组织,slf4j用来取代common logging,而logback用来取代log4j。      
log4j2 http://logging.apache.org/log4j/2.x/manual/index.html

 

 

现今,Java日志领域被划分为两大阵营:Commons Logging阵营和SLF4J阵营。Commons Logging在Apache大树的笼罩下,有很大的用户基数。但有证据表明,形式正在发生变化。2013年有人分析了GitHub上30000个项目,统计出了最流行的100个Libraries,发现slf4j的发展趋势更好.

 

 

 

原理

 

slf4j运行的时候,会在classpath中寻找org.slf4j.impl.StaticLoggerBinder类(slf4j-api包本身是没有这个类的),slf4j-simple,slf4j-log4j12或logback-classic都包含这个类。

 

 

 

 

Demo

 

Log4j

 

public class Test {
    private static Logger LOG = Logger.getLogger(Test.class);
    public static void main(String[] args) {
        LOG.debug("this is a debug message.");
        LOG.info("this is a info message");
        LOG.error("this is a error message");
    }
}

// log4j.xml
<?xml version="1.0" encoding="UTF-8"?>
<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/"
                     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                     xsi:schemaLocation="http://jakarta.apache.org/log4j/ ">
    <appender name="PROJECT" class="org.apache.log4j.ConsoleAppender">
        <param name="threshold" value="INFO"/>
        <layout class="org.apache.log4j.PatternLayout">
            <param name="ConversionPattern" value="%d %p %c{2} - %m%n"/>
        </layout>
    </appender>
    <root>
        <level value="INFO"/>
        <appender-ref ref="PROJECT"/>
    </root>
</log4j:configuration>

//Maven
<dependency>
    <groupId>log4j</groupId>
    <artifactId>log4j</artifactId>
    <version>1.2.17</version>
</dependency>

 

jul

 

import java.util.logging.Logger;
public class Test {
    public static void main(String[] args) {
        Logger logger = Logger.getLogger("");
        logger.info("this is a jul info message");
    }
}
//maven自行搜索

 

 

jcl + Log4j

 

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
public class Test {
    private static Log LOG = LogFactory.getLog(Test.class);
    public static void main(String[] args) {
        LOG.debug("this is a debug message.");
        LOG.info("this is a info message");
        LOG.error("this is a error message");
    }
}

<dependencies>
   <dependency>
        <groupId>log4j</groupId>
        <artifactId>log4j</artifactId>
        <version>1.2.17</version>
    </dependency>
    <dependency>
        <groupId>commons-logging</groupId>
        <artifactId>commons-logging</artifactId>
        <version>1.0.4</version>
    </dependency>
</dependencies>


jcl + jul

 

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
public class Test {
    public static void main(String[] args) {
        Log LOG = LogFactory.getLog(Test.class);
        LOG.info("this is a jul info message");
    }
}

//maven自行搜索


slf4j

 

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class Test {
    private  static Logger LOG = LoggerFactory.getLogger(Test.class);
    public static void main(String[] args) {
        LOG.info("this is a sl4j info message");
    }
}

<dependency>
    <groupId>org.slf4j</groupId>
    <artifactId>slf4j-api</artifactId>
    <version>1.7.6</version>
</dependency>


slf4j + logback

 

!-- slf4j-api -->
<dependency>
    <groupId>org.slf4j</groupId>
    <artifactId>slf4j-api</artifactId>
    <version>1.7.12</version>
</dependency>
<!-- logback -->
<dependency> 
    <groupId>ch.qos.logback</groupId> 
    <artifactId>logback-core</artifactId> 
    <version>1.1.3</version> 
</dependency> 
<dependency> 
    <groupId>ch.qos.logback</groupId> 
    <artifactId>logback-classic</artifactId> 
    <version>1.1.3</version> 
</dependency>


slf4j+log4j

 

slf4j-api
slf4j-log4j12//将slf4j绑定到了log4j输出
log4j

 

 

 

转换桥接

 

 

 

jcl转logback

 

 

如果应用的日志编码使用的是jcl接口,而想使用logback作为日志系统输出的话,则需要使用将jcl桥接到slf4j,然后再由slf4j+logback进行输出。解决方法是:
去掉commons-logging jar包(避免jar包冲突)
引入jcl-over-slf4j
slf4j + logback 的依赖文件

 

 

log4j 转 logback

 

 

如果想把log4j接口编码的应用,使用logback来进行日志输出,那么需要log4j-over-slf4j这个包将log4j桥接到slf4j,然后使用slf4j+logback进行输出:
引入log4j-over-slf4j
slf4j + logback 的依赖文件

 

 

jul 转logback

 

 

同理,如果需要将jul编码的应用转logback输出:
引入 jul-over-slf4j
使用slf4j + logback 的依赖文件

 

 

jcl+slf4j+log4j

 

 

 

这种情况下,应用日志代码使用commons-logging编码,同时将jcl桥接到了slf4j上,并使用log4j作为日志输出。与上文提到的jcl转logback类似,只是最后输出的方案是slf4j+log4j而不是slf4j+logback,所需要的jar包如下:
jcl-over-slf4j
slf4j-api
slf4j-log4j12
log4j

 

 

 

 

 

 

配置文件demo

https://blog.csdn.net/b2222505/article/details/83545868

 

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值