LogBack 入門實踐

一、簡介

前些天發現了一個巨牛的人工智能學習網站,通俗易懂,風趣幽默,忍不住分享一下給大家。點擊跳轉到教程。

LogBack是一個日志框架,它是Log4j作者Ceki的又一個日志組件。

LogBack,Slf4j,Log4j之間的關系

slf4j是The Simple Logging Facade for Java的簡稱,是一個簡單日志門面抽象框架,它本身只提供了日志Facade API和一個簡單的日志類實現,一般常配合Log4jLogBackjava.util.logging使用。Slf4j作為應用層的Log接入時,程序可以根據實際應用場景動態調整底層的日志實現框架(Log4j/LogBack/JdkLog...);

LogBack和Log4j都是開源日記工具庫,LogBack是Log4j的改良版本,比Log4j擁有更多的特性,同時也帶來很大性能提升。

LogBack官方建議配合Slf4j使用,這樣可以靈活地替換底層日志框架。

LogBack的結構
LogBack分為3個組件,logback-core, logback-classic 和 logback-access。
其中logback-core提供了LogBack的核心功能,是另外兩個組件的基礎。
logback-classic則實現了Slf4j的API,所以當想配合Slf4j使用時,則需要引入這個包。
logback-access是為了集成Servlet環境而準備的,可提供HTTP-access的日志接口。

Log的行為級別:

OFF
FATAL
ERROR
WARN
INFO
DEBUG
ALL
從下向上,當選擇了其中一個級別,則該級別向下的行為是不會被打印出來。
舉個例子,當選擇了INFO級別,則INFO以下的行為則不會被打印出來。

二、slf4j與logback結合使用原理

我們從java代碼最簡單的獲取logger開始

Logger logger = LoggerFactory.getLogger(xxx.class.getName());

LoggerFactory是slf4j的日志工廠,獲取logger方法就來自這里。

public static Logger getLogger(String name) {ILoggerFactory iLoggerFactory = getILoggerFactory();return iLoggerFactory.getLogger(name);
}

這個方法里面有分為兩個過程。第一個過程是獲取ILoggerFactory,就是真正的日志工廠。第二個過程就是從真正的日志工廠中獲取logger。
第一個過程又分為三個部分。

第一個部分加載org/slf4j/impl/StaticLoggerBinder.class文件

paths = ClassLoader.getSystemResources(STATIC_LOGGER_BINDER_PATH);//STATIC_LOGGER_BINDER_PATH = "org/slf4j/impl/StaticLoggerBinder.class"

第二部分隨機選取一個StaticLoggerBinder.class來創建一個單例
當項目中存在多個StaticLoggerBinder.class文件時,運行項目會出現以下日志:

SLF4J: Class path contains multiple SLF4J bindings.
SLF4J: Found binding in [jar:file:/C:/Users/jiangmitiao/.m2/repository/ch/qos/logback/logback-classic/1.1.3/logback-classic-1.1.3.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: Found binding in [jar:file:/C:/Users/jiangmitiao/.m2/repository/org/slf4j/slf4j-log4j12/1.7.12/slf4j-log4j12-1.7.12.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: See http://www.slf4j.org/codes.html#multiple_bindings for an explanation.
SLF4J: Actual binding is of type [ch.qos.logback.classic.util.ContextSelectorStaticBinder]

最后會隨機選擇一個StaticLoggerBinder.class來創建一個單例

StaticLoggerBinder.getSingleton()

第三部分返回一個ILoggerFactory實例

StaticLoggerBinder.getSingleton().getLoggerFactory();

所以slf4j與其他實際的日志框架的集成jar包中,都會含有這樣的一個org/slf4j/impl/StaticLoggerBinder.class類文件,并且提供一個ILoggerFactory的實現。

第二個過程就是每一個和slf4j集成的日志框架中實現ILoggerFactory方法getLogger()的實例所做的事了。

三、slf4j與logback結合使用實踐

第一步引入jar包
slf4j-api
logback-core
logback-classic(含有對slf4j的集成包)

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

第二步編寫簡單的logback配置文件

<?xml version="1.0" encoding="UTF-8"?>
<configuration><appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"><encoder><pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern></encoder></appender><root level="DEBUG">          <appender-ref ref="STDOUT" /></root>  
</configuration>

文件位置位于src/main/resources下,名字默認為logback.xml
當然,logback也支持groovy格式的配置文件,如果你會用那更好。
接下來,自己隨便寫一個類調用一下logger

package log.test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/*** @author jiangmitiao* @date 2016/3/24* @description TODO*/
public class Foo {public static void doIt(){Logger logger = LoggerFactory.getLogger(Foo.class.getName());logger.debug("let`s do it");}
}package log.test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/*** @author jiangmitiao* @date 2016/3/24* @description TODO*/
public class MyApp1 {public static void main(String[] args) {Logger logger = LoggerFactory.getLogger(MyApp1.class.getName());logger.info("before");Foo.doIt();logger.info("after");try {int i = 10 / 0;} catch (Exception e) {logger.error("errorTest",e);}}
}

最后的結果是:

16:22:13.459 [main] INFO  log.test.MyApp1 - before
16:22:13.463 [main] DEBUG log.test.Foo - let`s do it
16:22:13.463 [main] INFO  log.test.MyApp1 - after
16:22:13.466 [main] ERROR log.test.MyApp1 - errorTest
java.lang.ArithmeticException: / by zeroat log.test.MyApp1.main(MyApp1.java:19) ~[classes/:na]at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.6.0_25]at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) ~[na:1.6.0_25]at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) ~[na:1.6.0_25]at java.lang.reflect.Method.invoke(Method.java:597) ~[na:1.6.0_25]at com.intellij.rt.execution.application.AppMain.main(AppMain.java:140) [idea_rt.jar:na]

這么簡單的配置當然是沒有用的,下面這個就能夠說明logback配置文件的編寫規則了。

<!-- scan 是否定期掃描xml文件, scanPeriod是說掃描周期是30秒-->
<configuration scan="true" scanPeriod="30 seconds" debug="false" packagingData="true"><!-- 項目名稱 --><contextName>myApp1 contextName</contextName><!-- 屬性 --><property name="USER_HOME" value="./log"/><!-- Insert the current time formatted as "yyyyMMdd'T'HHmmss" underthe key "bySecond" into the logger context. This value will beavailable to all subsequent configuration elements. --><timestamp key="bySecond" datePattern="yyyyMMdd" timeReference="contextBirth"/><!-- appender很重要,一個配置文件會有多個appender --><!-- ConsoleApperder意思是從console中打印出來 --><appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"><!-- 過濾器,一個appender可以有多個 --><!-- 閾值過濾,就是log行為級別過濾,debug及debug以上的信息會被打印出來 --><filter class="ch.qos.logback.classic.filter.ThresholdFilter"><level>debug</level></filter><!-- encoders are assigned the typech.qos.logback.classic.encoder.PatternLayoutEncoder by default --><!-- encoder編碼規則 --><encoder><!--<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>--><!--<pattern>%d %contextName %msg%n</pattern>--><!-- pattern模式 %d時間 %thread 線程名 %level行為級別 %logger logger名稱 %method 方法名稱 %message 調用方法的入參消息 --><pattern>%-4d [%thread] %highlight%-5level %cyan%logger.%-10method - %message%n</pattern></encoder></appender><!-- FileAppender 輸出到文件 --><appender name="FILE" class="ch.qos.logback.core.FileAppender"><!-- 文件存放位置 %{xxx} 就是之前定義的屬性xxx --><file>${USER_HOME}/myApp1log-${bySecond}.log</file><encoder><!-- %date和%d是一個意思 %file是所在文件 %line是所在行 --><pattern>%date %level [%thread] %logger{30} [%file:%line] %msg%n</pattern></encoder></appender><!-- 輸出到HTML格式的文件 --><appender name="HTMLFILE" class="ch.qos.logback.core.FileAppender"><!-- 過濾器,這個過濾器是行為過濾器,直接過濾掉了除debug外所有的行為信息 --><filter class="ch.qos.logback.classic.filter.LevelFilter"><level>debug</level><onMatch>ACCEPT</onMatch><onMismatch>DENY</onMismatch></filter><encoder class="ch.qos.logback.core.encoder.LayoutWrappingEncoder"><!-- HTML輸出格式 可以和上邊差不多 --><layout class="ch.qos.logback.classic.html.HTMLLayout"><pattern>%relative%thread%mdc%level%logger%msg</pattern></layout></encoder><file>${USER_HOME}/test.html</file></appender><!-- 滾動日志文件,這個比較常用 --><appender name="ROLLINGFILE" class="ch.qos.logback.core.rolling.RollingFileAppender"><!-- 當project等于true的時候file就不會起效果--><prudent>true</prudent><!--<file>${USER_HOME}/logFile.log</file>--><!-- 按天新建log日志 --><rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"><!-- daily rollover --><fileNamePattern>${USER_HOME}/logFile.%d{yyyy-MM-dd}_%i.log</fileNamePattern><!-- 保留30天的歷史日志 --><maxHistory>30</maxHistory><!-- 基于大小和時間,這個可以有,可以沒有 --><timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP"><!-- or whenever the file size reaches 100MB --><!-- 當一個日志大小大于10KB,則換一個新的日志。日志名的%i從0開始,自動遞增 --><maxFileSize>10KB</maxFileSize></timeBasedFileNamingAndTriggeringPolicy></rollingPolicy><encoder><!-- %ex就是指拋出的異常,full是顯示全部,如果在{}中寫入數字,則表示展示多少行 --><pattern>%-4date [%thread] %-5level %logger{35} - %msg%n%ex{full, DISPLAY_EX_EVAL}</pattern></encoder></appender><!-- 重點來了,上邊都是appender輸出源。這里開始就是looger了 --><!-- name意思是這個logger管的哪一片,像下面這個管的就是log/test包下的所有文件 level是只展示什么行為信息級別以上的,類似閾值過濾器 additivity表示是否再拋出事件,就是說如果有一個logger的name是log,如果這個屬性是true,另一個logger就會在這個logger處理完后接著繼續處理 --><logger name="log.test" level="INFO" additivity="false"><!-- 連接輸出源,也就是上邊那幾個輸出源 ,你可以隨便選幾個appender--><appender-ref ref="STDOUT"/><appender-ref ref="ROLLINGFILE"/><appender-ref ref="HTMLFILE"/></logger><!-- 這個logger詳細到了類 --><logger name="log.test.Foo" level="debug" additivity="false"><appender-ref ref="STDOUT"/><appender-ref ref="ROLLINGFILE"/><appender-ref ref="HTMLFILE"/></logger><!-- Strictly speaking, the level attribute is not necessary since --><!-- the level of the root level is set to DEBUG by default.       --><!-- 這就是上邊logger沒有管到的情況下 root默認接管所有logger --><root level="debug"><appender-ref ref="STDOUT"/></root>
</configuration>

四、過濾器的一些疑問

Logback的過濾器基于三值邏輯,允許把它們組裝或成鏈,從而組成任意的復合過濾策略。過濾器很大程度上受到Linux的iptables啟發。這里的所謂三值邏輯是說,過濾器的返回值只能是ACCEPT、DENY和NEUTRAL的其中一個。
如果返回DENY,那么記錄事件立即被拋棄,不再經過剩余過濾器;
如果返回NEUTRAL,那么有序列表里的下一個過濾器會接著處理記錄事件;
如果返回ACCEPT,那么記錄事件被立即處理,不再經過剩余過濾器。
寫一個簡單的過濾器大家就明白了。

package log.test;import ch.qos.logback.classic.spi.ILoggingEvent;
import ch.qos.logback.core.filter.Filter;
import ch.qos.logback.core.spi.FilterReply;public class SampleFilter extends Filter<ILoggingEvent> {@Overridepublic FilterReply decide(ILoggingEvent event) {    if (event.getMessage().contains("let")) {return FilterReply.ACCEPT;} else {return FilterReply.DENY;}}
}

可以選擇任意幾個輸出源加入這個filter

<filter?class="log.test.SampleFilter"?/>

最后的結果是,加入該filter的輸出源只能輸出Foo.doIt()中的日志了。

五、總結

LogBack配置比較簡單,官網手冊也是比較容易看懂的。除上邊幾種輸出源之外,logback還支持輸出到遠程套接字服務器、 MySQL、 PostreSQL、Oracle和其他數據庫、 JMS和遠程UNIX Syslog守護進程等等。
第一次學習log方面的知識,如有錯誤,請不吝賜教。
相關資源:
官方手冊
LogBack簡易教程
實際的xml配置
Logback淺析
logback 配置詳解(一)

轉自:https://segmentfault.com/a/1190000004693427

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/448750.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/448750.shtml
英文地址,請注明出處:http://en.pswp.cn/news/448750.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

20個公司絕對不會告訴你的潛規則

1.入職時的工資高低不重要&#xff0c;只要你努力工作你會得到相應待遇的    我估計幾乎找過工作的人都聽過這句話&#xff0c;當我們確定被聘用跟公司談工資時&#xff0c;他們都會說“如果以后你業績突出、努力工作&#xff0c;你的報酬也會相應增加的”&#xff0c;特別是…

java 復制文件

2019獨角獸企業重金招聘Python工程師標準>>> public class copyFIle { public static void main(String[] args) throws IOException { File source new File("d:/test/1.xml");File des new File("d:/test/ma.txt");InputStream input null;…

Quartz學習資料地址記錄 、Quartz 學習的博客地址記錄

Quartz專欄系列 前些天發現了一個巨牛的人工智能學習網站&#xff0c;通俗易懂&#xff0c;風趣幽默&#xff0c;忍不住分享一下給大家。點擊跳轉到教程。 1.Quartz學習——Quartz大致介紹&#xff08;一&#xff09; 2.Quartz學習——Quartz簡單入門Demo&#xff08;二&#…

民間75個不傳之密 ,醫院都不知道的秘密

1、頭痛&#xff08;各種頭痛均可&#xff09;&#xff1a; 生白蘿卜汁&#xff0c;每次滴鼻孔兩滴(兩鼻孔都滴)&#xff0c;一日兩次&#xff0c;連用4-5天&#xff0c;可除根。忌吃花椒、胡椒。 2、頭暈&#xff08;頭昏眼花、暈眩&#xff09;&#xff1a; 鴨蛋一個、赤豆2…

Docker最全教程之MySQL容器化 (二十四)

Docker最全教程之MySQL容器化 &#xff08;二十四&#xff09; 原文:Docker最全教程之MySQL容器化 &#xff08;二十四&#xff09;前言 MySQL是目前最流行的開源的關系型數據庫&#xff0c;MySQL的容器化之前有朋友投稿并且寫過此塊&#xff0c;本篇僅從筆者角…

CODING 受邀參加《騰訊全球數字生態大會》

近日&#xff0c;騰訊全年最重要的一場活動——《騰訊全球數字生態大會》于昆明滇池國際會展中心正式舉辦。此次全球數字生態大會是騰訊戰略升級后&#xff0c;整合互聯網數字經濟峰會、云未來峰會、騰訊全球合作伙伴三大行業大會&#xff0c;全新升級打造的行業創新大會。大會…

解決 dockerfile 構建鏡像報錯: [WARNING]: Empty continuation lines will become errors in a future release.

前些天發現了一個巨牛的人工智能學習網站&#xff0c;通俗易懂&#xff0c;風趣幽默&#xff0c;忍不住分享一下給大家。點擊跳轉到教程。 1. 只是想自己寫個 dockerfile 用 docker 來部署 rocketmq 的服務。 dockerfile 中要運行多行命令 于是我寫成 RUN 命令a \&&…

第二章:08運算符[比較運算符]

①比較運算符②實例/* 運算符之三&#xff1a;比較運算符 ! > < > < instanceof 結論&#xff1a; 1.比較運算符的結果是boolean類型 2.區分 和 */ class CompareTest { public static void main(String[] args) { int i 10; int j 20; System.out.pr…

Apache版本兼容性問題

Apache 版本2.2.31 版本對于谷歌瀏覽器不兼容、IE8版本可以正常使用 當使用了Apache 高版本的話就解決了 出現以下現象 轉載于:https://www.cnblogs.com/tzhyy/p/10931084.html

王淮經驗談:我的碼農原則

摘要&#xff1a;王淮是Facebook第二位中國籍工程師&#xff0c;也是第一位中國籍研發經理&#xff0c;他一手開創了Facebook的支付安全和客服工具領域。2011年他離開Facebook&#xff0c;回國成為天使投資人。本文是王淮以前寫代碼和做代碼審查時候的一些原則&#xff0c;供大…

centos uwsgi自動調用python2環境,指定uwsgi調用版本

將自己開發好的django項目用uwsgi部署到Linux服務器、當運行uwsgi時出現了uwsgi選擇python版本的問題。因為本機器是在原來的機器上安裝了python3環境和pip3&#xff0c; 使用命令安裝uwsgi: pip3 install uwsgi 一點問題也沒有&#xff0c;使用uwsgi部署項目時 uwsgi --http :…

docker build Dockfile ---- RUN 中 cd 切換路徑失敗 的原因、解決

前些天發現了一個巨牛的人工智能學習網站&#xff0c;通俗易懂&#xff0c;風趣幽默&#xff0c;忍不住分享一下給大家。點擊跳轉到教程。 1. 我只是想 直接切換到對應目錄下 執行后續命令。 ?????寫法如下&#xff1a; FROM openjdk:8-jre-alpineMAINTAINER JiangYuRU…

米爾電子Zynq UltraScale MPSoC核心板資料介紹

米爾Zynq UltraScale MPSoC核心板&#xff08;MYC-CZU3EG&#xff09;是采用Xilinx新一代Zynq處理器。該核心板是業界最小尺寸Zynq UltraScale 核心板&#xff0c;采用16納米制程&#xff0c;相比Znyq7000系列每瓦性能提升5倍&#xff0c;且單芯片融合4核心Cortex-A53&#xff…

幸福秘訣 男女必須要看哦

女人說&#xff1a;這一輩子最大的成功是什么?我認為是找到一個真正疼自己的老公,有了老公的支持才可以把事業做得有聲有色,有一個幸福的家和一個可愛的寶寶。 男人說&#xff1a;我的成功是在我的人生之中&#xff0c;是妻子和我形影相隨&#xff0c;朝夕相伴。她是我身邊…

解決:If the number of processors is expected to increase from one, then you should configure the numbe

前些天發現了一個巨牛的人工智能學習網站&#xff0c;通俗易懂&#xff0c;風趣幽默&#xff0c;忍不住分享一下給大家。點擊跳轉到教程。 1. 按官方說明用 docker 部署 rocketmq ,啟動 broker 報錯&#xff1a; OpenJDK 64-Bit Server VM warning: If the number of processo…

JAVA-緩存機制

本地緩存 繼承AbstractBaseLocalCache&#xff0c;并實現相應的抽象方法&#xff1b;適用于單實例項目或不會經常變化的數據&#xff1b;代碼示例&#xff1a;/*** 倉庫信息緩存類*/ Service public class WarehouseCache extends AbstractBaseLocalCache<Long, Warehouse&g…

騰訊QQ團隊開源分布式后臺毫秒服務引擎全解析:引擎架構、RPC、灰度……

騰訊QQ團隊將于12月4日開源一個服務開發運營框架&#xff0c;叫做毫秒服務引擎&#xff08;Mass Service Engine in Cluster&#xff0c;MSEC&#xff09;&#xff0c;它集RPC、名字發現服務、負載均衡、業務監控、灰度發布、容量管理、日志管理、Key-Value存儲于一體&#xff…

古代隱士如何忙衣食

三歲娃兒都曉得&#xff0c;吃飯穿衣是維持生命的基本條件&#xff0c;想瀟灑地“舊山歸隱浪搖青&#xff0c;綠鬢山童一帙經”&#xff0c;就得準備足夠的柴米油鹽。 所謂隱士&#xff0c;須得強調是“士”&#xff0c;即讀書人。手無縛雞之力&#xff0c;不仕就無俸祿&…

一個秘密

前些天發現了一個巨牛的人工智能學習網站&#xff0c;通俗易懂&#xff0c;風趣幽默&#xff0c;忍不住分享一下給大家。點擊跳轉到教程。 這是一個秘密&#xff0c; 一個不想說出來&#xff0c;卻真實的秘密&#xff1a; --- --- 本來我不想說&#xff0c; 可是最近的一切…

程序員如何在大公司做管理

本文被記錄的最大初衷在于從創業公司的CEO轉變成阿里巴巴的一名開發專家&#xff0c;打心底觸動了心靈最深處的一次學習經歷&#xff0c;無論成長、挫折、困難、收獲都烙在心里。 寫文章的思路&#xff1a; 背景&#xff08;認清現狀&#xff09;管理&#xff08;闡述自己的理解…