转载自:http://www.cnblogs.com/mailingfeng/p/3499436.html

上次我们讨论了如何选择一个好的开源日志系统方案,其中的结论是:使用 SLF4J + LogBack 是一个很好的选择。这篇文章就来讲讲如何快速地搭建起这套日志系统。

一、简介

LogBack是一个日志框架,它与Log4j可以说是同出一源,都出自Ceki Gülcü之手。(log4j的原型是早前由Ceki Gülcü贡献给Apache基金会的)

LogBack、Slf4j、Log4j 之间的关系

Slf4j是The Simple Logging Facade for Java的简称,是一个简单日志门面抽象框架,它本身只提供了日志Facade API和一个简单的日志类实现,一般常配合Log4j,LogBack,java.util.logging使用。Slf4j作为应用层的Log接入时,程序可以根据实际应用场景动态调整底层的日志实现框架(Log4j/LogBack/JdkLog...)。

LogBack和Log4j都是开源日记工具库,LogBack是Log4j的改良版本,比Log4j拥有更多的特性,同时也带来很大性能提升。详细数据可参照下面地址:Reasons to prefer logback over log4j

LogBack官方建议配合Slf4j使用,这样可以灵活地替换底层日志框架。

NOTE:为了优化log4j,以及更大性能的提升,Apache基金会已经着手开发了log4j 2.0, 其中也借鉴和吸收了logback的一些先进特性,目前log4j2还处于beta阶段。

LogBack 的结构

LogBack被分为3个组件,logback-core, logback-classic 和 logback-access。

其中logback-core提供了LogBack的核心功能,是另外两个组件的基础。

logback-classic则实现了Slf4j的API,所以当想配合Slf4j使用时,需要将logback-classic加入classpath。

logback-access是为了集成Servlet环境而准备的,可提供HTTP-access的日志接口。

二、Slf4j + Logback 快速实践

资源准备

现在常用的是将slf4j+Logback进行配套使用,所以需要将slf4j-api.jar, logback-core.jar, log-classic.jar加入classpath.

之后编写logback.xml配置文件,同样该文件要加入classpath中,这样LogBack启动的时候会自动扫描到并加载。

NOTE:若LogBack无法检索到相关的配置文件,则会启用默认配置,将日志按照默认格式输出于控制台。

logback.xml 配置

LogBack的配置大概包括3部分,Appender,Logger,Root的配置。

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

<configuration debug="true" scan="true" scanPeriod="30 seconds"> 

  <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
    <!-- encoders are  by default assigned the type
         ch.qos.logback.classic.encoder.PatternLayoutEncoder -->
    <encoder>
        <pattern>%d{yyyy-MM-dd HH:mm:ss} [%level] - %m%n</pattern>

        <!-- 常用的Pattern变量,大家可打开该pattern进行输出观察 -->
        <!--
          <pattern>
              %d{yyyy-MM-dd HH:mm:ss} [%level] - %msg%n
              Logger: %logger
              Class: %class
              File: %file
              Caller: %caller
              Line: %line
              Message: %m
              Method: %M
              Relative: %relative
              Thread: %thread
              Exception: %ex
              xException: %xEx
              nopException: %nopex
              rException: %rEx
              Marker: %marker
              %n

          </pattern>
           -->
    </encoder>
  </appender>

  <!-- 按日期区分的滚动日志 -->
  <appender name="ERROR-OUT" class="ch.qos.logback.core.rolling.RollingFileAppender">
      <file>logs/error.log</file>

    <encoder>
        <pattern>%d{yyyy-MM-dd HH:mm:ss} [%class:%line] - %m%n</pattern>
    </encoder>

      <filter class="ch.qos.logback.classic.filter.LevelFilter">
      <level>ERROR</level>
      <onMatch>ACCEPT</onMatch>
      <onMismatch>DENY</onMismatch>
    </filter>

      <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
      <!-- daily rollover -->
      <fileNamePattern>error.%d{yyyy-MM-dd}.log.zip</fileNamePattern>

      <!-- keep 30 days' worth of history -->
      <maxHistory>30</maxHistory>
    </rollingPolicy>
  </appender>

  <!-- 按文件大小区分的滚动日志 -->
  <appender name="INFO-OUT" class="ch.qos.logback.core.rolling.RollingFileAppender">
      <file>logs/info.log</file>

    <encoder>
        <pattern>%d{yyyy-MM-dd HH:mm:ss} [%class:%line] - %m%n</pattern>
    </encoder>

      <filter class="ch.qos.logback.classic.filter.LevelFilter">
      <level>INFO</level>
      <onMatch>ACCEPT</onMatch>
      <onMismatch>DENY</onMismatch>
    </filter>

      <rollingPolicy class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy">
      <fileNamePattern>info.%i.log</fileNamePattern>
      <minIndex>1</minIndex>
      <maxIndex>3</maxIndex>
    </rollingPolicy>

    <triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
      <maxFileSize>5MB</maxFileSize>
    </triggeringPolicy>

  </appender>

  <!-- 按日期和大小区分的滚动日志 -->
  <appender name="DEBUG-OUT" class="ch.qos.logback.core.rolling.RollingFileAppender">
      <file>logs/debug.log</file>

    <encoder>
        <pattern>%d{yyyy-MM-dd HH:mm:ss} [%class:%line] - %m%n</pattern>
    </encoder>

      <filter class="ch.qos.logback.classic.filter.LevelFilter">
      <level>DEBUG</level>
      <onMatch>ACCEPT</onMatch>
      <onMismatch>DENY</onMismatch>
    </filter>

      <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
      <!-- rollover daily -->
      <fileNamePattern>debug-%d{yyyy-MM-dd}.%i.log</fileNamePattern>

      <timeBasedFileNamingAndTriggeringPolicy
            class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
        <!-- or whenever the file size reaches 100MB -->
        <maxFileSize>100MB</maxFileSize>
      </timeBasedFileNamingAndTriggeringPolicy>

    </rollingPolicy>

  </appender>

   <!-- 级别阀值过滤 -->
  <appender name="SUM-OUT" class="ch.qos.logback.core.rolling.RollingFileAppender">
      <file>logs/sum.log</file>

    <encoder>
        <pattern>%d{yyyy-MM-dd HH:mm:ss} [%class:%line] - %m%n</pattern>
    </encoder>

    <!-- deny all events with a level below INFO, that is TRACE and DEBUG -->
    <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
      <level>INFO</level>
    </filter>

      <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
      <!-- rollover daily -->
      <fileNamePattern>debug-%d{yyyy-MM-dd}.%i.log</fileNamePattern>

      <timeBasedFileNamingAndTriggeringPolicy
            class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
        <!-- or whenever the file size reaches 100MB -->
        <maxFileSize>100MB</maxFileSize>
      </timeBasedFileNamingAndTriggeringPolicy>

    </rollingPolicy>

  </appender>

  <root level="debug">
    <appender-ref ref="STDOUT" />
    <appender-ref ref="ERROR-OUT" />
    <appender-ref ref="INFO-OUT" />
    <appender-ref ref="DEBUG-OUT" />
    <appender-ref ref="SUM-OUT" />
  </root>
</configuration>

示例

public class Slf4jTest {

    private static Logger Log = LoggerFactory.getLogger(Slf4jTest.class);

    @Test
    public void testLogBack(){

        Log.debug("Test the MessageFormat for {} to {} endTo {}", 1,2,3);
        Log.info("Test the MessageFormat for {} to {} endTo {}", 1,2,3);
        Log.error("Test the MessageFormat for {} to {} endTo {}", 1,2,3);

        try{
            throw new IllegalStateException("try to throw an Exception");
        }catch(Exception e){
            Log.error(e.getMessage(),e);
        }
    }

}

输出:

2013-12-30 21:37:18 [DEBUG] - Test the MessageFormat for 1 to 2 endTo 3
2013-12-30 21:37:18 [INFO] - Test the MessageFormat for 1 to 2 endTo 3
2013-12-30 21:37:18 [ERROR] - Test the MessageFormat for 1 to 2 endTo 3
2013-12-30 21:37:18 [ERROR] - try to throw an Exception
java.lang.IllegalStateException: try to throw an Exception
    at logs.Slf4jTest.testLogBack(Slf4jTest.java:19) ~[bin/:na]
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.6.0_18]
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) ~[na:1.6.0_18]
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) ~[na:1.6.0_18]
    at java.lang.reflect.Method.invoke(Method.java:597) ~[na:1.6.0_18]
    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:47) [junit.jar:na]
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12) [junit.jar:na]
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:44) [junit.jar:na]
    at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17) [junit.jar:na]
    at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:271) [junit.jar:na]
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:70) [junit.jar:na]
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50) [junit.jar:na]
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238) [junit.jar:na]
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63) [junit.jar:na]
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236) [junit.jar:na]
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53) [junit.jar:na]
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229) [junit.jar:na]
    at org.junit.runners.ParentRunner.run(ParentRunner.java:309) [junit.jar:na]
    at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50) [.cp/:na]
    at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38) [.cp/:na]
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467) [.cp/:na]
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683) [.cp/:na]
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390) [.cp/:na]
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197) [.cp/:na]

简易教程基本到这里就差不多了,希望大家都能很快上手。

想了解更多的信息,可访问下面地址:

http://logback.qos.ch

http://www.slf4j.org

使用 SLF4J + LogBack 构建日志系统(转)的更多相关文章

  1. 日志框架之2 slf4j+logback实现日志架构 · 远观钱途

    如何从缤纷复杂的日志系统世界筛选出适合自己的日志框架以及slf4j+logback的组合美妙之处?此文可能有帮助 logback介绍 Logback是由log4j创始人设计的另一个开源日志组件,官方网 ...

  2. 用SLF4j/Logback打印日志-3

    在 用SLF4j/Logback打印日志-1 和 用SLF4j/Logback打印日志-2 中分别介绍了Logback记录日志的基本原理并重点介绍了输出源配置.本篇介绍一些性能和技巧性的东西. 性能 ...

  3. slf4j/logback: logging日志的配置

    slf4j/logback: logging日志的配置 import依赖: import org.slf4j.Logger;import org.slf4j.LoggerFactory;private ...

  4. Slf4j与其他日志系统兼容的使用

    java生产的各种框架(如spring等)里各个框架会使用不同的日志体系,多个不同日志在一个jvm里混搭会出现一定问题 ,这里梳理一下java体系里常见的日志框架,以SFL4j为中心介绍下跟各个日志框 ...

  5. 用SLF4j/Logback打印日志-1

    在 浅谈后端日志系统 中已经写了很多日志方面的零散的非技术的东西.本篇更像一份入门说明,讲解一下SLF4j/Logback.SLF4J是一套抽象的日志API接口,logback它是的底层实现,所以在这 ...

  6. 用SLF4j/Logback打印日志-2

    本篇主要介绍logback的输出源配置,logback默认提供了很多输出源,但是用的最多的是这几种: OutputStreamAppender 日志输出到一个二进制流,可以通过 <encoder ...

  7. (转)slf4j+logback将日志输出到控制台

    因为博主不允许转载...这边做链接记录 http://blog.csdn.net/gsycwh/article/details/52972946

  8. SpringBoot日志logback-spring.xml分环境log4j logback slf4j区别 springboot日志设置

    转载. https://blog.csdn.net/qianyiyiding/article/details/76565810 springboot按照profile进行打印日志log4j logba ...

  9. spring boot 使用logback日志系统的详细说明

    springboot按照profile进行打印日志 log4j logback slf4j区别? 首先谈到日志,我们可能听过log4j logback slf4j这三个名词,那么它们之间的关系是怎么样 ...

随机推荐

  1. 随机生成并排序 C,去同,有序数组合并排序

    #include<iostream> #include<stdlib.h> #include<time.h> using namespace std; int ma ...

  2. TCP协议详解

    TCP协议详解 一.TCP协议 1.TCP 通过以下方式提供可靠性: ·  ◆ 应用程序分割为TCP认为最合适发送的数据块.由TCP传递给IP的信息单位叫做报文段. ·  ◆ 当TCP发出一个报文段后 ...

  3. Pangolin的使用

    Pangolin 是一个可用于SLAM可视化的openGL库.目前有很多SLAM系统都用它作为可视化的工具.它的编译与安装过程问题不大,依赖也比较少.但最近我在单独使用它的时候,碰到了很奇怪的现象:我 ...

  4. angular : direative : autoResize textarea auto resize

    今天为大家推出自己的auto resize 指令功能. 目的:解决textarea在给height的问题. 参考源码:http://monospaced.github.io/angular-elast ...

  5. 转:Apache 与 Nginx 比较

    Nginx 轻量级,采用 C 进行编写,同样的 web 服务,会占用更少的内存及资源 抗并发,nginx 以 epoll and kqueue 作为开发模型,处理请求是异步非阻塞的,负载能力比 apa ...

  6. Lambda表达式和Java集合框架

    本文github地址 前言 我们先从最熟悉的Java集合框架(Java Collections Framework, JCF)开始说起. 为引入Lambda表达式,Java8新增了java.util. ...

  7. ERP管理员培训报道

    金秋十月,丹桂飘香,为期三天的“201610管理员培训”活动于2016年10月19日在苏州总部成功举行.参与本次培训活动的有浙江卡迪夫电缆有限公司.上海华源瓷业股份有限公司.江苏牛牌纺织机械有限公司. ...

  8. js substr和substring的区别

    在js中substring和substr都是用来截取字符串的,substr函数和substring函数都是用来从某个“母字符串”中提取“子字符串”的函数.但用法有些差别,下面分别介绍但是它们还是有区别 ...

  9. javascript作用域和闭包之我见

    javascript作用域和闭包之我见 看了<你不知道的JavaScript(上卷)>的第一部分--作用域和闭包,感受颇深,遂写一篇读书笔记加深印象.路过的大牛欢迎指点,对这方面不懂的同学 ...

  10. 解决https证书验证不通过的问题

    1.报错信息 java.security.cert.CertificateException: No name matching api.weibo.com found; nested excepti ...