LogBack简易教程
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简易教程的更多相关文章
- Java Logback简易教程
本作品采用知识共享署名-非商业性使用 4.0 国际许可协议进行许可. 一.前言 本文以一个简单的项目为例,一步步展示logback的同步和异步配置方法,并且配置的日志要求满足阿里巴巴Java开发手册- ...
- 生活科技两相宜:(一)Win7使用微软SkyDrive网盘简易教程
今天得写一个Win7使用微软SkyDrive网盘的简易教程,主要是给我老婆看,顺便贴出来给大家共享一下:) 使用微软SkyDrive网盘有两个层次.一个是使用网页版,这个跟使用163或者QQ网盘 ...
- JavaScript简易教程(转)
原文:http://www.cnblogs.com/yanhaijing/p/3685304.html 这是我所知道的最完整最简洁的JavaScript基础教程. 这篇文章带你尽快走进JavaScri ...
- Emacs简易教程
Emacs简易教程阅读: 命令: $emacs 进入之后,输入: C-h t 这里,C-h表示按住[Ctrl]键的同时按h ####### 20090620 *退出: 输入“C-x C-c” *撤销: ...
- 文件上传利器SWFUpload入门简易教程
凡做过网站开发的都应该知道表单file的确鸡肋. Ajax解决了不刷新页面提交表单,但是却没有解决文件上传不刷新页面,当然也有其它技术让不刷新页面而提交文件,该技术主要是利用隐藏的iFrame, 较A ...
- 【转】Delphi内嵌ASM简易教程
Delphi内嵌ASM简易教程 作者:heiying2006-03-19 18:33分类:默认分类标签: 前言 Delphi作为一个快速高效的开发平台,使用的人越来越多,但熟悉在Delphi代码中嵌入 ...
- Ant 简易教程
转载:http://www.cnblogs.com/jingmoxukong/p/4433945.html Ant 简易教程 Apache Ant,是一个将软件编译.测试.部署等步骤联系在一起加以自动 ...
- Intellj IDEA 简易教程
Intellj IDEA 简易教程 目录 JDK 安装测试 IDEA 安装测试 调试 单元测试 重构 Git Android 其他 参考资料 Java开发IDE(Integrated Developm ...
- MetaProducts Offline Explorer使用简易教程
MetaProducts Offline Explorer使用简易教程 by windtrace 20170419 最近想下载一个网站上的内容打包成chm文件,以便离线浏览,webzip太长时间不更 ...
随机推荐
- TFS 2015 敏捷开发实践 – 看板的使用
看板在现代应用开发过程中使用非常广泛,不管是使用传统的瀑布式开发还是敏捷开发,都可以使用看板管理.因为看板拥有简单的管理方法,直观的显示方式,所以很多软件开发团队选择使用看板进行软件开发管理.本文不在 ...
- Oracle中的commit详解
本文转自 : http://blog.csdn.net/hzhsan/article/details/9719307 它执行的时候,你不会有什么感觉.commit在数据库编程的时候很常用,当你执行DM ...
- 两个变量交换的四种方法(Java)
对于两种变量的交换,我发现四种方法,下面我用Java来演示一下. 1.利用第三个变量交换数值,简单的方法. (代码演示一下) class TestEV //创建一个类 { public static ...
- Spark Streaming+Kafka
Spark Streaming+Kafka 前言 在WeTest舆情项目中,需要对每天千万级的游戏评论信息进行词频统计,在生产者一端,我们将数据按照每天的拉取时间存入了Kafka当中,而在消费者一端, ...
- 【腾讯优测干货分享】如何降低App的待机内存(四)——进阶:内存原理
本文来自于腾讯优测公众号(wxutest),未经作者同意,请勿转载,原文地址:http://mp.weixin.qq.com/s/3FTPFvZRqyAQnU047kmWJQ 1.4进阶:内存原理 在 ...
- ASP.NET MVC Model绑定(三)
ASP.NET MVC Model绑定(三) 前言 看过前两篇的朋友想必对Model绑定有个大概的了解,然而MVC框架给我们提供了更高的可扩展性的提供程序编程模式,也就是本篇的主题了,会讲解一下Mod ...
- ABP(现代ASP.NET样板开发框架)系列之20、ABP展现层——动态生成WebApi
点这里进入ABP系列文章总目录 ABP(现代ASP.NET样板开发框架)系列之20.ABP展现层——动态生成WebApi ABP是“ASP.NET Boilerplate Project (ASP.N ...
- TODO:这是一个我的自媒体
TODO:这是一个我的自媒体 自媒体(外文名:We Media)又称"公民媒体"或"个人媒体",是指私人化.平民化.普泛化.自主化的传播者,以现代化.电子化的手 ...
- 对jquery操作复选框
摘要:jquery操作复选框.使用更简洁易懂,思路清晰,逻辑更明了,很实用 <!DOCTYPE html> <html> <head> <meta chars ...
- AngularJS_01之基础概述、设计原则及MVC设计模式
1.AngularJS: 开源的JS框架,用来开发单一页面应用,以及数据操作频繁的场景:2.设计原则: ①YAGNI原则:You Aren't Gonna Need It! 不要写不需要的代码! ②K ...