您好,登錄后才能下訂單哦!
本篇內容介紹了“Log配置教程及框架性能比較是什么”的有關知識,在實際案例的操作過程中,不少人都會遇到這樣的困境,接下來就讓小編帶領大家學習一下如何處理這些情況吧!希望大家仔細閱讀,能夠學有所成!
一、摘要
不管是使用何種編程語言,何種框架,日志輸出幾乎無處不再,也是任何商業軟件中必不可少的一部分。
總結起來,日志的用途大致可以歸納成以下三種:
問題追蹤:通過日志不僅僅包括我們程序的一些bug,也可以在安裝配置時,通過日志可以發現問題。
狀態監控:通過實時分析日志,可以監控系統的運行狀態,做到早發現問題、早處理問題。
安全審計:審計主要體現在安全上,通過對日志進行分析,可以發現是否存在非授權的操作。
以 Java 編程語言為例,打印日志的方式有很多,例如通過System.out.print()方法將關鍵信息輸出到控制臺,也可以通過 JDK 自帶的日志Logger類輸出,雖然 JDK 從1.4開始支持日志輸出,但是功能單一,無法更好的滿足商業要求,于是誕生了很多第三方日志庫,像我們所熟悉的主流框架log4j、log4j2、logback等,提供的 API 功能都遠勝 JDK 提供的Logger。
二、Log4j
2.1、介紹
Log4j 是一種非常流行的日志框架,由Ceki Gülcü首創,之后將其開源貢獻給 Apache 軟件基金會。
Log4j 有三個主要的組件:Loggers(記錄器),Appenders (輸出源)和Layouts(布局)。這里可簡單理解為日志類別、日志要輸出的地方和日志以何種形式輸出。
綜合使用這三個組件可以輕松地記錄信息的類型和級別,并可以在運行時控制日志輸出的樣式和位置。
Log4j 的架構大致如下:
當我們使用 Log4j 輸出一條日志時,Log4j 自動通過不同的Appender(輸出源)把同一條日志輸出到不同的目的地。例如:
console:輸出到屏幕;
file:輸出到文件;
socket:通過網絡輸出到遠程計算機;
jdbc:輸出到數據庫
在輸出日志的過程中,通過Filter來過濾哪些log需要被輸出,哪些log不需要被輸出。
在Loggers(記錄器)組件中,級別分五種:DEBUG、INFO、WARN、ERROR和FATAL。
這五個級別是有順序的,DEBUG < INFO < WARN < ERROR < FATAL,分別用來指定這條日志信息的重要程度,明白這一點很重要,Log4j有一個規則:只輸出級別不低于設定級別的日志信息。
假設Loggers級別設定為INFO,則INFO、WARN、ERROR和FATAL級別的日志信息都會輸出,而級別比INFO低的DEBUG則不會輸出。
最后,通過Layout來格式化日志信息,例如,自動添加日期、時間、方法名稱等信息。
具體輸出樣式配置,可以參考如下內容Log4j2 - Layouts布局介紹
2.2、項目應用
以 Java 項目為例,在 Maven 的pom.xml中添加如下依賴!
2.2.1、添加 maven 依賴
<dependencies> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> <version>1.6.6</version> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-log4j12</artifactId> <version>1.6.6</version> </dependency> <dependency> <groupId>log4j</groupId> <artifactId>log4j</artifactId> <version>1.2.17</version> </dependency> </dependencies>
2.2.2、創建log4j配置
在實際應用中,要使Log4j在系統中運行須事先設定配置文件。
配置文件實際上也就是對Logger、Appender及Layout進行相應設定。
Log4j支持兩種配置文件格式,一種是XML格式的文件,一種是properties屬性文件,二選一。
創建一個log4j.xml或者log4j.properties,將其放入項目根目錄下。
1、XML格式
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE log4j:configuration PUBLIC "-//APACHE//DTD LOG4J 1.2//EN" "log4j.dtd"> <log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/"> <!-- 控制臺輸出配置 --> <appender name="console" class="org.apache.log4j.ConsoleAppender"> <!-- 目標為控制臺 --> <param name="Target" value="System.out" /> <layout class="org.apache.log4j.PatternLayout"> <!-- 輸出格式 --> <param name="ConversionPattern" value="%d{yyyy-MM-dd HH:mm:ss} [%t] %-5p %l %m%n" /> </layout> </appender> <!-- 文件輸出配置 --> <appender name="log_file" class="org.apache.log4j.DailyRollingFileAppender"> <!-- 目標為文件 --> <param name="File" value="/logs/log/file.log" /> <!-- 向文件追加輸出 --> <param name="Append" value="true" /> <!-- 每個小時生成一個log --> <param name="DatePattern" value="'.'yyyy-MM-dd-HH" /> <layout class="org.apache.log4j.PatternLayout"> <!-- 輸出格式 --> <param name="ConversionPattern" value="%d{yyyy-MM-dd HH:mm:ss} [%t] %-5p %l %m%n" /> </layout> </appender> <!-- Application Loggers --> <logger name="org.example"> <level value="info" /> </logger> <!-- 根目錄 --> <!-- Root Logger --> <root> <priority value="info" /> <appender-ref ref="console" /> <appender-ref ref="log_file" /> </root> </log4j:configuration>
2、XML格式
log4j.rootLogger=INFO,M,C,E log4j.additivity.monitorLogger=false # INFO級別文件輸出配置 log4j.appender.M=org.apache.log4j.DailyRollingFileAppender log4j.appender.M.File=/logs/info.log log4j.appender.M.ImmediateFlush=false log4j.appender.M.BufferedIO=true log4j.appender.M.BufferSize=16384 log4j.appender.M.Append=true log4j.appender.M.Threshold=INFO log4j.appender.M.DatePattern='.'yyyy-MM-dd log4j.appender.M.layout=org.apache.log4j.PatternLayout log4j.appender.M.layout.ConversionPattern=%-d{yyyy-MM-dd HH:mm:ss} %p %l %m %n # ERROR級別文件輸出配置 log4j.appender.E=org.apache.log4j.DailyRollingFileAppender log4j.appender.E.File=/logs/error.log log4j.appender.E.ImmediateFlush=true log4j.appender.E.Append=true log4j.appender.E.Threshold=ERROR log4j.appender.E.DatePattern='.'yyyy-MM-dd log4j.appender.E.layout=org.apache.log4j.PatternLayout log4j.appender.E.layout.ConversionPattern=%-d{yyyy-MM-dd HH:mm:ss} %p %l %m %n # 控制臺輸出配置 log4j.appender.C=org.apache.log4j.ConsoleAppender log4j.appender.C.Threshold=INFO log4j.appender.C.layout=org.apache.log4j.PatternLayout log4j.appender.C.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} [%t] %-5p %l %m %n
2.2.3、log4j使用
在需要打印日志的類中,引入Logger類,在需要的地方打印即可!
package org.example.log4j.service; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class LogPrintUtil { /**log靜態常量*/ private static final Logger logger = LoggerFactory.getLogger(LogPrintUtil.class); public static void main(String[] args){ logger.info("info信息"); logger.warn("warn信息"); logger.error("error信息"); } }
當然你還可以這樣寫
if(logger.isInfoEnabled()) { logger.info("info信息"); } if(logger.isWarnEnabled()) { logger.warn("warn信息"); }
2.2.4、isInfoEnabled()有何作用呢?
簡單來說,在某些場景下,用isInfoEnabled()方法判斷下是能提升性能的!
例如我們打印這段內容logger.info("User:" + userId + appId),程序在打印這行代碼時,先對內容("User:" + userId + appId)進行字符串拼接,然后再輸出。
如果當前配置文件中日志輸出級別是info,是直接輸出的,當日志輸出級別是error時,logger.info()的內容時不輸出的,但是我們卻進行了字符串拼接,如果加上if(logger.isInfoEnabled())進行一次判定,logger.info()就不會執行,從而更好的提升性能,這個尤其是在高并發和復雜log打印情況下提升非常顯著。
另外,ERROR及其以上級別的log信息是一定會被輸出的,所以只有logger.isDebugEnabled、logger.isInfoEnabled和logger.isWarnEnabled()方法,而沒有logger.isErrorEnabled方法。
三、Log4j2
3.1、介紹
log4j2 是 log4j 1.x 的升級版,參考了 logback 的一些優秀的設計,并且修復了一些問題,因此帶來了一些重大的提升,主要特點有:
異常處理:在logback中,Appender中的異常不會被應用感知到,但是在log4j2中,提供了一些異常處理機制。
性能提升, log4j2相較于log4j 1和logback都具有很明顯的性能提升,后面會有官方測試的數據。
自動重載配置:參考了logback的設計,當然會提供自動刷新參數配置,最實用的就是我們在生產上可以動態的修改日志的級別而不需要重啟應用——那對監控來說,是非常敏感的。
無垃圾機制:log4j2在大部分情況下,都可以使用其設計的一套無垃圾機制,避免頻繁的日志收集導致的jvm gc。
3.2、項目應用
3.2.1、添加 maven 依賴
<dependencies> <!-- slf4j核心包 --> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> <version>1.7.13</version> </dependency> <!--用于與common-log保持橋接 --> <dependency> <groupId>org.slf4j</groupId> <artifactId>jcl-over-slf4j</artifactId> <version>1.7.13</version> <scope>runtime</scope> </dependency> <!--核心log4j2jar包 --> <dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-api</artifactId> <version>2.4.1</version> </dependency> <dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-core</artifactId> <version>2.4.1</version> </dependency> <!--用于與slf4j保持橋接 --> <dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-slf4j-impl</artifactId> <version>2.4.1</version> </dependency> <!--需要使用log4j2的AsyncLogger需要包含disruptor --> <dependency> <groupId>com.lmax</groupId> <artifactId>disruptor</artifactId> <version>3.2.0</version> </dependency> </dependencies>
3.2.2、創建log4j2配置
在項目的根目錄下創建一個log4j2.xml的文件,與log4j相比,log4j2的異步輸出日志性能非常強勁,配置如下:
1、同步輸出日志
<?xml version="1.0" encoding="UTF-8"?> <!-- status : 這個用于設置log4j2自身內部的信息輸出,可以不設置,當設置成trace時。 注:本配置文件的目標是將不同級別的日志輸出到不同文件,最大1MB一個文件, 文件數據達到最大值時,舊數據會被壓縮并放進指定文件夾 ,最多存放20個文件--> <Configuration status="error"> <!-- 配置日志文件輸出目錄,此配置將日志輸出到根目錄下的指定文件夾 --> <Properties> <Property name="fileDir">/logs/log4j2</Property> <Property name="fileHistory">/logs/log4j2/history</Property> </Properties> <Appenders> <!-- 優先級從高到低分別是 OFF、FATAL、ERROR、WARN、INFO、DEBUG、ALL --> <!-- 單詞解釋:Match:匹配 DENY:拒絕 Mismatch:不匹配 ACCEPT:接受 --> <!-- DENY,日志將立即被拋棄不再經過其他過濾器;NEUTRAL,有序列表里的下個過濾器過接著處理日志;ACCEPT,日志會被立即處理,不再經過剩余過濾器。 --> <!--輸出日志的格式 %d{yyyy-MM-dd HH:mm:ss, SSS} : 日志生產時間 %t 輸出當前線程名稱 %-5level 輸出日志級別,-5表示左對齊并且固定輸出5個字符,如果不足在右邊補0 %logger 輸出logger名稱,因為Root Logger沒有名稱,所以沒有輸出 %msg 日志文本 %n 換行 其他常用的占位符有: %F 輸出所在的類文件名,如Client.java %L 輸出行號 %M 輸出所在方法名 %l 輸出語句所在的行數, 包括類名、方法名、文件名、行數 --> <!--這個輸出控制臺的配置,這里輸出all信息到System.out --> <console name="Console" target="SYSTEM_OUT"> <!-- 輸出日志的格式 --> <PatternLayout charset="UTF-8" pattern="%d{yyyy-MM-dd HH:mm:ss} [%t] %-5level %l %msg%n" /> </console> <!--這個輸出文件的配置,這里輸出info信息到junbao_info.log --> <RollingFile name="RollingFileInfo" fileName="${fileDir}/info.log" filePattern="${fileHistory}/info/%d{yyyy-MM-dd}-%i.log"> <!-- 此Filter意思是,只輸出info級別的數據 DENY,日志將立即被拋棄不再經過其他過濾器;NEUTRAL,有序列表里的下個過濾器過接著處理日志; ACCEPT,日志會被立即處理,不再經過剩余過濾器。 --> <ThresholdFilter level="info" onMatch="ACCEPT" onMismatch="DENY" /> <PatternLayout charset="UTF-8" pattern="%d{yyyy-MM-dd HH:mm:ss} [%t] %-5level %l %msg%n" /> <Policies> <!-- 如果啟用此配置,則日志會按文件名生成新文件, 即如果filePattern配置的日期格式為 %d{yyyy-MM-dd HH} ,則每小時生成一個壓縮文件, 如果filePattern配置的日期格式為 %d{yyyy-MM-dd} ,則天生成一個壓縮文件,默認為1 --> <TimeBasedTriggeringPolicy /> <!-- 每個日志文件最大1MB,超過1MB生產新的文件 ; --> <SizeBasedTriggeringPolicy size="100MB" /> </Policies> <!--文件夾下最多的文件個數--> <DefaultRolloverStrategy max="20" /> </RollingFile> <RollingFile name="RollingFileWarn" fileName="${fileDir}/warn.log" filePattern="${fileHistory}/warn/%d{yyyy-MM-dd}-%i.log"> <ThresholdFilter level="warn" onMatch="ACCEPT" onMismatch="DENY" /> <PatternLayout charset="UTF-8" pattern="%d{yyyy-MM-dd HH:mm:ss} [%t] %-5level %l %msg%n" /> <Policies> <TimeBasedTriggeringPolicy /> <SizeBasedTriggeringPolicy size="100MB" /> </Policies> <DefaultRolloverStrategy max="20" /> </RollingFile> <RollingFile name="RollingFileError" fileName="${fileDir}/error.log" filePattern="${fileHistory}/error/%d{yyyy-MM-dd}-%i.log"> <ThresholdFilter level="error" onMatch="ACCEPT" onMismatch="DENY" /> <PatternLayout charset="UTF-8" pattern="%d{yyyy-MM-dd HH:mm:ss} [%t] %-5level %l %msg%n" /> <Policies> <TimeBasedTriggeringPolicy /> <SizeBasedTriggeringPolicy size="100MB" /> </Policies> <DefaultRolloverStrategy max="20" /> </RollingFile> </Appenders> <!--然后定義logger,只有定義了logger并引入的appender,appender才會生效 --> <Loggers> <!--全異步輸出info級以上的日志信息--> <!-- <asyncRoot level="info" includeLocation="true"> <appender-ref ref="Console" /> <appender-ref ref="RollingFileInfo" /> </asyncRoot> --> <!--同步輸出info級以上的日志信息--> <root level="info" includeLocation="true"> <appender-ref ref="Console" /> </root> </Loggers> </Configuration>
2、異步輸出日志
<?xml version="1.0" encoding="UTF-8"?> <!-- status : 這個用于設置log4j2自身內部的信息輸出,可以不設置,當設置成trace時。 注:本配置文件的目標是將不同級別的日志輸出到不同文件,最大1MB一個文件, 文件數據達到最大值時,舊數據會被壓縮并放進指定文件夾 ,最多存放20個文件--> <Configuration status="error"> <!-- 配置日志文件輸出目錄,此配置將日志輸出到根目錄下的指定文件夾 --> <Properties> <Property name="fileDir">/logs/log4j2</Property> <Property name="fileHistory">/logs/log4j2/history</Property> </Properties> <Appenders> <!-- 優先級從高到低分別是 OFF、FATAL、ERROR、WARN、INFO、DEBUG、ALL --> <!-- 單詞解釋:Match:匹配 DENY:拒絕 Mismatch:不匹配 ACCEPT:接受 --> <!-- DENY,日志將立即被拋棄不再經過其他過濾器;NEUTRAL,有序列表里的下個過濾器過接著處理日志;ACCEPT,日志會被立即處理,不再經過剩余過濾器。 --> <!--輸出日志的格式 %d{yyyy-MM-dd HH:mm:ss, SSS} : 日志生產時間 %t 輸出當前線程名稱 %-5level 輸出日志級別,-5表示左對齊并且固定輸出5個字符,如果不足在右邊補0 %logger 輸出logger名稱,因為Root Logger沒有名稱,所以沒有輸出 %msg 日志文本 %n 換行 其他常用的占位符有: %F 輸出所在的類文件名,如Client.java %L 輸出行號 %M 輸出所在方法名 %l 輸出語句所在的行數, 包括類名、方法名、文件名、行數 --> <!--這個輸出控制臺的配置,這里輸出all信息到System.out --> <console name="Console" target="SYSTEM_OUT"> <!-- 輸出日志的格式 --> <PatternLayout charset="UTF-8" pattern="%d{yyyy-MM-dd HH:mm:ss} [%t] %-5level %l %msg%n" /> </console> <!--這個輸出文件的配置,這里輸出info信息到junbao_info.log --> <RollingFile name="RollingFileInfo" fileName="${fileDir}/info.log" filePattern="${fileHistory}/info/%d{yyyy-MM-dd}-%i.log"> <!-- 此Filter意思是,只輸出info級別的數據 DENY,日志將立即被拋棄不再經過其他過濾器;NEUTRAL,有序列表里的下個過濾器過接著處理日志; ACCEPT,日志會被立即處理,不再經過剩余過濾器。 --> <ThresholdFilter level="info" onMatch="ACCEPT" onMismatch="DENY" /> <PatternLayout charset="UTF-8" pattern="%d{yyyy-MM-dd HH:mm:ss} [%t] %-5level %l %msg%n" /> <Policies> <!-- 如果啟用此配置,則日志會按文件名生成新文件, 即如果filePattern配置的日期格式為 %d{yyyy-MM-dd HH} ,則每小時生成一個壓縮文件, 如果filePattern配置的日期格式為 %d{yyyy-MM-dd} ,則天生成一個壓縮文件,默認為1 --> <TimeBasedTriggeringPolicy /> <!-- 每個日志文件最大1MB,超過1MB生產新的文件 ; --> <SizeBasedTriggeringPolicy size="100MB" /> </Policies> <!--文件夾下最多的文件個數--> <DefaultRolloverStrategy max="20" /> </RollingFile> <RollingFile name="RollingFileWarn" fileName="${fileDir}/warn.log" filePattern="${fileHistory}/warn/%d{yyyy-MM-dd}-%i.log"> <ThresholdFilter level="warn" onMatch="ACCEPT" onMismatch="DENY" /> <PatternLayout charset="UTF-8" pattern="%d{yyyy-MM-dd HH:mm:ss} [%t] %-5level %l %msg%n" /> <Policies> <TimeBasedTriggeringPolicy /> <SizeBasedTriggeringPolicy size="100MB" /> </Policies> <DefaultRolloverStrategy max="20" /> </RollingFile> <RollingFile name="RollingFileError" fileName="${fileDir}/error.log" filePattern="${fileHistory}/error/%d{yyyy-MM-dd}-%i.log"> <ThresholdFilter level="error" onMatch="ACCEPT" onMismatch="DENY" /> <PatternLayout charset="UTF-8" pattern="%d{yyyy-MM-dd HH:mm:ss} [%t] %-5level %l %msg%n" /> <Policies> <TimeBasedTriggeringPolicy /> <SizeBasedTriggeringPolicy size="100MB" /> </Policies> <DefaultRolloverStrategy max="20" /> </RollingFile> </Appenders> <!--然后定義logger,只有定義了logger并引入的appender,appender才會生效 --> <Loggers> <!--全異步輸出info級以上的日志信息--> <asyncRoot level="info" includeLocation="true"> <appender-ref ref="Console" /> <appender-ref ref="RollingFileInfo" /> </asyncRoot> <!--同步輸出info級以上的日志信息--> <!-- <root level="info" includeLocation="true"> <appender-ref ref="Console" /> </root> --> </Loggers> </Configuration>
詳細 API 可以參考官方網站!
3.2.3、log4j2使用
與 log4j 類似,直接在需要位置打印日志即可
package org.example.log4j.service; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class LogPrintUtil { /**log靜態常量*/ private static final Logger logger = LoggerFactory.getLogger(LogPrintUtil.class); public static void main(String[] args){ logger.info("info信息"); logger.warn("warn信息"); logger.error("error信息"); } }
四、Logback
4.1、介紹
Logback 也是用 java 編寫一款非常熱門的日志開源框架,由 log4j 創始人寫的,性能比 log4j 要好!
logback 主要分為3個模塊:
logback-core:核心代碼模塊
logback-classic:log4j的一個改良版本,同時實現了slf4j的接口,這樣你如果之后要切換其他日志組件也是一件很容易的事
logback-access:訪問模塊與Servlet容器集成提供通過Http來訪問日志的功能
4.2、項目應用
4.2.1、添加 maven 依賴
<!--這個依賴直接包含了 logback-core 以及 slf4j-api的依賴--> <dependency> <groupId>ch.qos.logback</groupId> <artifactId>logback-classic</artifactId> <version>1.2.3</version> </dependency> <!-- 支持在xml中寫判斷標簽 --> <dependency> <groupId>org.codehaus.janino</groupId> <artifactId>janino</artifactId> <version>2.7.8</version> </dependency>
4.2.2、創建logback配置文件
1、配置說明
logback在啟動的時候,會按照下面的順序加載配置文件:
如果java程序啟動時指定了logback.configurationFile屬性,就用該屬性指定的配置文件。如java -Dlogback.configurationFile=/path/to/mylogback.xml Test,這樣執行Test類的時候就會加載/path/to/mylogback.xml配置
在classpath中查找logback.groovy文件
在classpath中查找logback-test.xml文件
在classpath中查找logback.xml文件
如果是jdk6+,那么會調用ServiceLoader查找 com.qos.logback.classic.spi.Configurator接口的第一個實現類
自動使用ch.qos.logback.classic.BasicConfigurator,在控制臺輸出日志
上面的順序表示優先級,使用java -D配置的優先級最高,只要獲取到配置后就不會再執行下面的流程。相關代碼可以看ContextInitializer#autoConfig()方法。
2、同步輸出日志
<?xml version="1.0" encoding="UTF-8"?> <!-- scan:當此屬性設置為true時,配置文件如果發生改變,將會被重新加載,默認值為true。scanPeriod:設置監測配置文件是否有修改的時間間隔,如果沒有給出時間單位,默認單位是毫秒。當scan為true時,此屬性生效。默認的時間間隔為1分鐘。 debug:當此屬性設置為true時,將打印出logback內部日志信息,實時查看logback運行狀態。默認值為false。 --> <configuration scan="true" scanPeriod="60 seconds" debug="false"> <!-- 運行環境,dev:開發,test:測試,pre:預生產,pro:生產 --> <property name="system_host" value="dev" /> <property file="system.properties" /> <!-- 上下文變量設置,用來定義變量值,其中name的值是變量的名稱,value的值時變量定義的值。 通過<property>定義的值會被插入到logger上下文中。定義變量后,可以使“${}”來使用變量。 --> <property name="CONTEXT_NAME" value="logback-test" /> <!-- 日志文件存放路徑設置,絕對路徑 --> <property name="logs.dir" value="/opt/logs" /> <!-- 日志文件存放路徑設置,tomcat路徑 --> <property name="logs.dir" value="${catalina.base}/logs" /> <!-- 定義日志文件 相對輸入位置 --> <property name="log_dir" value="log" /> <!-- 日志輸出格式設置 --> <!-- %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 newline:%n --> <property name="CUSTOM_LOG_PATTERN" value="%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{90} - %msg%n" /> <!-- 上下文名稱:<contextName>, 每個logger都關聯到logger上下文, 默認上下文名稱為“default”。但可以使用<contextName>設置成其他名字,用于區分不同應用程序的記錄。 一旦設置,不能修改。 --> <contextName>${CONTEXT_NAME}</contextName> <!-- <appender>是<configuration>的子節點,是負責寫日志的組件。 有兩個必要屬性name和class。name指定appender名稱, class指定appender的實現類。 --> <appender name="console" class="ch.qos.logback.core.ConsoleAppender"> <!-- 對日志進行格式化。 --> <encoder> <pattern>${CUSTOM_LOG_PATTERN}</pattern> <charset>UTF-8</charset> </encoder> </appender> <appender name="file" class="ch.qos.logback.core.rolling.RollingFileAppender"> <!-- 按天來回滾,如果需要按小時來回滾,則設置為{yyyy-MM-dd_HH} --> <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> <fileNamePattern>log/testC.%d{yyyy-MM-dd}.%i.log</fileNamePattern> <!-- 如果按天來回滾,則最大保存時間為30天,30天之前的都將被清理掉 --> <maxHistory>30</maxHistory> <!-- 按時間回滾的同時,按文件大小來回滾 --> <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP"> <maxFileSize>100MB</maxFileSize> </timeBasedFileNamingAndTriggeringPolicy> </rollingPolicy> <!-- 過濾器,只記錄WARN級別的日志 --> <!-- 果日志級別等于配置級別,過濾器會根據onMath 和 onMismatch接收或拒絕日志。 --> <filter class="ch.qos.logback.classic.filter.LevelFilter"> <!-- 設置過濾級別 --> <level>WARN</level> <!-- 用于配置符合過濾條件的操作 --> <onMatch>ACCEPT</onMatch> <!-- 用于配置不符合過濾條件的操作 --> <onMismatch>DENY</onMismatch> </filter> <!-- 日志輸出格式 --> <encoder> <pattern>${CUSTOM_LOG_PATTERN}</pattern> <charset>UTF-8</charset> </encoder> </appender> <appender name="log_file" class="ch.qos.logback.core.rolling.RollingFileAppender"> <!-- 被寫入的文件名,可以是相對目錄,也可以是絕對目錄,如果上級目錄不存在會自動創建,沒有默認值。 --> <file>${logs.dir}/logback-test.log</file> <!-- 按照固定窗口模式生成日志文件,當文件大于20MB時,生成新的日志文件。窗口大小是1到3,當保存了3個歸檔文件后,將覆蓋最早的日志 --> <rollingPolicy class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy"> <!-- 必須包含“%i”例如,假設最小值和最大值分別為1和2,命名模式為 mylog%i.log,會產生歸檔文件mylog1.log和mylog2.log。還可以指定文件壓縮選項,例如,mylog%i.log.gz 或者 沒有log%i.log.zip --> <FileNamePattern>${logs.dir}/logback-test.%i.log</FileNamePattern> <!-- 窗口索引最小值 --> <minIndex>1</minIndex> <!-- 窗口索引最大值 --> <maxIndex>3</maxIndex> </rollingPolicy> <!-- 日志級別過濾器 --> <filter class="ch.qos.logback.classic.filter.LevelFilter"> <!-- 日志級別過濾器 --> <level>INFO</level> <!-- 符合要求的日志級別,過濾,ACCEPT:接受 --> <onMatch>ACCEPT</onMatch> <!-- 不符合要求的日志級別,過濾,DENY:拒絕 --> <onMismatch>DENY</onMismatch> </filter> <!-- 激活滾動的條件。 --> <triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy"> <!-- 活動文件的大小,默認值是10MB --> <maxFileSize>30MB</maxFileSize> </triggeringPolicy> <!-- 對記錄事件進行格式化。 --> <encoder> <pattern>${CUSTOM_LOG_PATTERN}</pattern> <charset>UTF-8</charset> </encoder> </appender> <!-- 異步輸出 --> <appender name="ASYNC_logback" class="ch.qos.logback.classic.AsyncAppender"> <!-- 不丟失日志.默認的,如果隊列的80%已滿,則會丟棄TRACT、DEBUG、INFO級別的日志 --> <!-- <discardingThreshold>0</discardingThreshold> --> <!-- 更改默認的隊列的深度,該值會影響性能.默認值為256 --> <!-- <queueSize>256</queueSize> --> <!-- 添加附加的appender,最多只能添加一個 --> <appender-ref ref="log_file" /> </appender> <!-- 指定包輸出路徑 --> <!-- 用來設置某一個 包 或者具體的某一個 類 的日志打印級別、以及指定<appender>, name:用來指定受此logger約束的某一個包或者具體的某一個類。 level:用來設置打印級別,大小寫無關:TRACE, DEBUG, INFO, WARN, ERROR, ALL 和 OFF,還有一個特俗值INHERITED或者同義詞NULL,代表強制執行上級的級別。如果未設置此屬性,那么當前loger將會繼承上級的級別。 additivity:是否向上級logger傳遞打印信息。默認是true。(這個logger的上級就是上面的root) <logger>可以包含零個或多個<appender-ref>元素,標識這個appender將會添加到這個logger。 --> <logger name="org.logback.test" level="DEBUG" additivity="true"> <appender-ref ref="stdout" /> </logger> <!-- 特殊的<logger>元素,是根logger。只有一個level屬性,應為已經被命名為"root". level:設置打印級別,大小寫無關:TRACE, DEBUG, INFO, WARN, ERROR, ALL 和 OFF,不能設置為INHERITED或者同義詞NULL。默認是DEBUG。 <root>可以包含零個或多個<appender-ref>元素,標識這個appender將會添加到這個loger。 --> <root> <level value="WARN" /> <!-- if表達式,需要Janino jar --> <!-- Janino 2.6.0版本開始,除了janino.jar之外, commons-compiler.jar也需要在類路徑中 --> <if condition='property("system_host").contains("dev")'> <then> <appender-ref ref="stdout" /> </then> </if> <appender-ref ref="file" /> </root> </configuration>
注意:logback如果配置要輸出行號,性能會明顯降低,如果不是必須,建議不要配置!
4.2.3、logback使用
package org.example.logback.service; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class LogPrintUtil { /**log靜態常量*/ private static final Logger logger = LoggerFactory.getLogger(LogPrintUtil.class); public static void main(String[] args){ logger.info("info信息"); logger.warn("warn信息"); logger.error("error信息"); } }
五、SLF4J橋接
細心的你,會發現上面代碼使用時,都使用的是private static final Logger logger = LoggerFactory.getLogger(LogPrintUtil.class)這個,其中都來自org.slf4j包,SLF4J是啥?有什么作用呢?
SLF4J本身并不輸出日志,最大的特色是**:它可以通過適配的方式掛接不同的日志系統,屬于一個日志接口**。
如果項目適配到log4j就使用log4j日志庫進行輸出;如果適配到logback就使用logback日志庫進行輸出;如果適配到log4j2就使用log4j2日志庫進行輸出。
這樣最大的好處,就是當你想將項目從log4j換成log4j2的時候,只需要在項目pom.xml中進行橋接適配即可,不用修改具體需要打印日志的代碼!
六、三大主流日志框架性能比較
介紹了這么多,但是我們還不知道三個日志框架的日志輸出性能如何,本文以10000條數據進行打印,比較log4j、log4j2、logback日志的輸出時間。
本次測試采用的是本地電腦(win7),每個電腦的配置不一樣,測試的結果也不一樣,結果是真實的。
同步輸出
異步輸出
從測試結果上可以看出:
不建議生產環境進行控制臺輸出;
在純文件輸出的環境下,logback的輸出優于log4j2,而log4j2要優于log4j,如果要進行生產環境的部署,建議采用logback,如果是使用log4j2,建議使用異步方式進行輸出,輸出結果基本是實時輸出;
最后需要注意的地方是:log有風險,輸出需謹慎!
由于輸出log過程需要進行磁盤操作,且log4j為了保證log輸出過程的線程安全性而使用同步鎖,就使得輸出log成為很耗時的操作,所以log信息一定要言簡意賅,不要輸出一些無用的log。
“Log配置教程及框架性能比較是什么”的內容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業相關的知識可以關注億速云網站,小編將為大家輸出更多高質量的實用文章!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。