1.简介

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

1.1 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阶段)

1.2 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的日志接口;

2. Slf4j+Logback的快速实践

2.1 资源准备

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

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

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

2.2 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>

另一个更简单的:

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

<configuration debug="true" scan="false" 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>
</encoder>
</appender> <!-- 按日期区分的滚动日志 -->
<appender name="APP" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>logs/app.log</file> <encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss} [%class:%line] - %m%n</pattern>
</encoder> <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>INFO</level>
</filter> <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- daily rollover -->
<fileNamePattern>app.%d{yyyy-MM-dd}.log</fileNamePattern> <!-- keep 30 days' worth of history -->
<maxHistory>30</maxHistory>
</rollingPolicy>
</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>30MB</maxFileSize> </timeBasedFileNamingAndTriggeringPolicy>
</rollingPolicy> </appender> <root level="debug">
<appender-ref ref="STDOUT" />
<appender-ref ref="APP" />
<appender-ref ref="DEBUG-OUT" />
</root>
</configuration>

2.3 示例

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);
}
} }

输出:

-- :: [DEBUG] - Test the MessageFormat for  to  endTo
-- :: [INFO] - Test the MessageFormat for to endTo
-- :: [ERROR] - Test the MessageFormat for to endTo
-- :: [ERROR] - try to throw an Exception
java.lang.IllegalStateException: try to throw an Exception
at logs.Slf4jTest.testLogBack(Slf4jTest.java:) ~[bin/:na]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.6.0_18]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:) ~[na:1.6.0_18]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:) ~[na:1.6.0_18]
at java.lang.reflect.Method.invoke(Method.java:) ~[na:1.6.0_18]
at org.junit.runners.model.FrameworkMethod$.runReflectiveCall(FrameworkMethod.java:) [junit.jar:na]
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:) [junit.jar:na]
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:) [junit.jar:na]
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:) [junit.jar:na]
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:) [junit.jar:na]
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:) [junit.jar:na]
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:) [junit.jar:na]
at org.junit.runners.ParentRunner$.run(ParentRunner.java:) [junit.jar:na]
at org.junit.runners.ParentRunner$.schedule(ParentRunner.java:) [junit.jar:na]
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:) [junit.jar:na]
at org.junit.runners.ParentRunner.access$(ParentRunner.java:) [junit.jar:na]
at org.junit.runners.ParentRunner$.evaluate(ParentRunner.java:) [junit.jar:na]
at org.junit.runners.ParentRunner.run(ParentRunner.java:) [junit.jar:na]
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:) [.cp/:na]
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:) [.cp/:na]
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:) [.cp/:na]
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:) [.cp/:na]
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:) [.cp/:na]
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:) [.cp/:na]

LogBack简易教程的更多相关文章

  1. Java Logback简易教程

    本作品采用知识共享署名-非商业性使用 4.0 国际许可协议进行许可. 一.前言 本文以一个简单的项目为例,一步步展示logback的同步和异步配置方法,并且配置的日志要求满足阿里巴巴Java开发手册- ...

  2. 生活科技两相宜:(一)Win7使用微软SkyDrive网盘简易教程

    今天得写一个Win7使用微软SkyDrive网盘的简易教程,主要是给我老婆看,顺便贴出来给大家共享一下:)    使用微软SkyDrive网盘有两个层次.一个是使用网页版,这个跟使用163或者QQ网盘 ...

  3. JavaScript简易教程(转)

    原文:http://www.cnblogs.com/yanhaijing/p/3685304.html 这是我所知道的最完整最简洁的JavaScript基础教程. 这篇文章带你尽快走进JavaScri ...

  4. Emacs简易教程

    Emacs简易教程阅读: 命令: $emacs 进入之后,输入: C-h t 这里,C-h表示按住[Ctrl]键的同时按h ####### 20090620 *退出: 输入“C-x C-c” *撤销: ...

  5. 文件上传利器SWFUpload入门简易教程

    凡做过网站开发的都应该知道表单file的确鸡肋. Ajax解决了不刷新页面提交表单,但是却没有解决文件上传不刷新页面,当然也有其它技术让不刷新页面而提交文件,该技术主要是利用隐藏的iFrame, 较A ...

  6. 【转】Delphi内嵌ASM简易教程

    Delphi内嵌ASM简易教程 作者:heiying2006-03-19 18:33分类:默认分类标签: 前言 Delphi作为一个快速高效的开发平台,使用的人越来越多,但熟悉在Delphi代码中嵌入 ...

  7. Ant 简易教程

    转载:http://www.cnblogs.com/jingmoxukong/p/4433945.html Ant 简易教程 Apache Ant,是一个将软件编译.测试.部署等步骤联系在一起加以自动 ...

  8. Intellj IDEA 简易教程

    Intellj IDEA 简易教程 目录 JDK 安装测试 IDEA 安装测试 调试 单元测试 重构 Git Android 其他 参考资料 Java开发IDE(Integrated Developm ...

  9. MetaProducts Offline Explorer使用简易教程

    MetaProducts Offline Explorer使用简易教程 by windtrace  20170419 最近想下载一个网站上的内容打包成chm文件,以便离线浏览,webzip太长时间不更 ...

随机推荐

  1. 【JQ基础】数组

    each() 方法规定为每个匹配元素规定运行的函数.

  2. 报错:You need to use a Theme.AppCompat theme (or descendant) with this activity.

    学习 Activity 生命周期时希望通过 Dialog 主题测试 onPause() 和 onStop() 的区别,点击按钮跳转 Activity 时报错: E/AndroidRuntime: FA ...

  3. [OC] NSURLSession

    有的程序员老了,还没听过NSURLSession 有的程序员还嫩,没用过NSURLConnection 有的程序员很单纯,他只知道AFN. NSURLConnection在iOS9被宣布弃用,NSUR ...

  4. 开源 iOS 项目分类索引大全 - 待整理

    开源 iOS 项目分类索引大全 GitHub 上大概600个开源 iOS 项目的分类和介绍,对于你挑选和使用开源项目应该有帮助 系统基础库 Category/Util sstoolkit 一套Cate ...

  5. 15个C++项目列表

    实验楼上有很多C++的实战项目,从简单到进阶,学习每个项目都可以掌握相应的知识点. 如果你还是C++新手的话,那么这个C++的项目列表你可以拿去练手实战开发,毕竟学编程动手实践是少不了的! 如果你不知 ...

  6. 写个Fragment方便的抽象基类 BaseFragment

    package com.zb.zhihuianyang.base; import android.app.Activity; import android.os.Bundle; import andr ...

  7. 作为前端er,写在年末的一些话

    写惯了技术类的文章,这种总结和唠嗑型的我基本也就在年末才来一篇.说实话,这种轻松类的文章往往比技术类的要受欢迎的多,因为其受众更广,看起来也不烧脑. 说来愧疚,这一年其实产出有点低,大致就写了不到二十 ...

  8. Java泛型的历史

    为什么Java泛型会有当前的缺陷? 之前的章节里已经说明了Java泛型擦除会导致的问题,C++和C#的泛型都是在运行时存在的,难道Java天然不支持“真正的泛型”吗? 事实上,在Java1.5在200 ...

  9. 用lucene替代mysql读库的尝试

    采用lucene对mysql中的表建索引,并替代全文检索操作. 备注:代码临时梳理很粗糙,后续修改. import java.io.File; import java.io.IOException; ...

  10. 淘宝UWP中的100个为什么

    从淘宝UWP第一版发布到现在,已经有十个月了,期间收到了用户各种各样的反馈,感谢这些用户的反馈,指导我们不断的修正.完善应用.但是也有一部分需求或建议,由于资源或技术的限制,目前确实无法做到,只能对广 ...