
SLF4J 快速指南
SLF4J - 概述
SLF4J 代表 **S**imple **L**ogging **F**acade for **J**ava。它為 Java 中的所有日誌框架提供了一個簡單的抽象層。因此,它使使用者能夠使用單個依賴項與任何日誌框架(例如 Log4j、Logback 和 **JUL**(java.util.logging))一起工作。您可以在執行時/部署時遷移到所需的日誌框架。
Ceki Gülcü 建立 SLF4J 作為 Jakarta commons-logging 框架的替代方案。

SLF4J 的優勢
以下是 SLF4J 的優勢:
使用 SLF4J 框架,您可以在部署時遷移到所需的日誌框架。
Slf4j 提供了對所有流行的日誌框架的繫結,例如 log4j、JUL、Simple logging 和 NOP。因此,您可以在部署時切換到任何這些流行的框架。
SLF4J 支援引數化日誌訊息,無論您使用哪個繫結。
由於 SLF4J 解耦了應用程式和日誌框架,您可以輕鬆編寫獨立於日誌框架的應用程式。您無需擔心編寫應用程式時使用的日誌框架。
SLF4J 提供了一個簡單的 Java 工具,稱為遷移工具。使用此工具,您可以將使用 Jakarta Commons Logging (JCL) 或 log4j 或 Java.util.logging (JUL) 等日誌框架的現有專案遷移到 SLF4J。
SLF4J - 日誌框架
程式設計中的日誌記錄是指記錄活動/事件。通常,應用程式開發人員應該負責日誌記錄。
為了使日誌記錄工作更容易,Java 提供了各種框架:log4J、java.util.logging (JUL)、tiny log、logback 等。
日誌框架概述
日誌框架通常包含三個元素:
記錄器 (Logger)
捕獲訊息以及元資料。
格式化器 (Formatter)
格式化記錄器捕獲的訊息。
處理器 (Handler)
處理器或追加器最終透過列印到控制檯、儲存到資料庫或透過電子郵件傳送來排程訊息。
一些框架將記錄器和追加器元素組合起來以加快操作速度。
Logger 物件
要記錄訊息,應用程式會發送一個帶有名稱和安全級別的 Logger 物件(有時還會包含任何異常)。
嚴重級別
記錄的訊息將具有不同的級別。下表列出了日誌的一般級別。
序號 | 嚴重級別及說明 |
---|---|
1 |
致命 (Fatal) 導致應用程式終止的嚴重問題。 |
2 |
錯誤 (ERROR) 執行時錯誤。 |
3 |
警告 (WARNING) 在大多數情況下,錯誤是由於使用了已棄用的 API。 |
4 |
資訊 (INFO) 執行時發生的事件。 |
5 |
除錯 (DEBUG) 關於系統流程的資訊。 |
6 |
跟蹤 (TRACE) 關於系統流程的更詳細的資訊。 |
SLF4J vs Log4j
什麼是 log4j?
log4j 是一個可靠、快速且靈活的 **用 Java 編寫的日誌框架 (API)**,它在 Apache 軟體許可證下發行。
log4j 透過執行時的外部配置檔案高度可配置。它從優先順序級別來看待日誌記錄過程,並提供機制將日誌資訊定向到各種目的地,例如資料庫、檔案、控制檯、UNIX Syslog 等。(有關 log4j 的更多詳細資訊,請參閱我們的 教程)。
SLF4J 和 Log4j 的比較
與 log4j 不同,SLF4J (**S**imple **L**ogging **F**acade for **J**ava) 不是日誌框架的實現,它是 Java 中所有類似於 log4J 的日誌框架的 **抽象**。因此,您無法比較兩者。但是,總是很難在兩者之間進行選擇。
如果您有選擇,日誌抽象總是優於日誌框架。如果您使用日誌抽象,特別是 SLF4J,您可以在部署時遷移到任何所需的日誌框架,而無需選擇單個依賴項。
觀察下圖以更好地理解。

SLF4J - 環境設定
在本章中,我們將解釋如何在 Eclipse IDE 中設定 SLF4J 環境。在繼續安裝之前,請確保您已經在系統中安裝了 Eclipse。如果沒有,請下載並安裝 Eclipse。
有關 Eclipse 的更多資訊,請參閱我們的 Eclipse 教程
步驟 1:下載依賴項 JAR 檔案
開啟 SLF4J 網站的官方 主頁 並轉到下載頁面。

現在,根據您的作業系統下載最新穩定版本的 slf4j-X.X.tar.gz 或 slf4j-X.X.zip(如果使用 Windows,則為 .zip 檔案;如果使用 Linux,則為 tar.gz 檔案)。
在下載的資料夾中,您將找到 slf4j-api-X.X.jar。這是所需的 Jar 檔案。
步驟 2:建立一個專案並設定構建路徑
開啟 Eclipse 並建立一個示例專案。右鍵單擊專案,選擇選項 **構建路徑 → 配置構建路徑…**,如下所示。

在 **Java 構建路徑** 框架的 **庫** 選項卡中,單擊 **新增外部 JARs…**

選擇下載的 slf4j-api.x.x.jar 檔案,然後單擊 **應用並關閉**。

SLF4J 繫結
除了 slf4j-api.x.x.jar 檔案之外,SLF4J 還提供其他幾個 Jar 檔案,如下所示。這些稱為 **SLF4J 繫結**。

每個繫結都對應其各自的日誌框架。
下表列出了 SLF4J 繫結及其對應的框架。
序號 | Jar 檔案 & 日誌框架 |
---|---|
1 |
slf4j-nop-x.x.jar 不執行任何操作,丟棄所有日誌。 |
2 |
slf4j-simple-x.x.jar 簡單的實現,其中列印資訊及以上級別的訊息,其餘所有輸出到 System.err。 |
3 |
slf4j-jcl-x.x.jar Jakarta Commons Logging 框架。 |
4 |
slf4j-jdk14-x.x.jar Java.util.logging 框架 (JUL)。 |
5 |
slf4j-log4j12-x.x.jar Log4J 框架。此外,您還需要 log4j.jar。 |
要使 SLF4J 與 slf4l-api-x.x.jar 一起工作,您需要將所需日誌框架的相應 Jar 檔案(繫結)新增到專案的類路徑中(設定構建路徑)。
要從一個框架切換到另一個框架,您需要替換相應的繫結。如果沒有找到繫結,則預設為不執行操作模式。
SLF4J 的 pom.xml
如果您正在建立 Maven 專案,請開啟 pom.xml 並將以下內容貼上到其中,然後重新整理專案。
<project xmlns = "http://maven.apache.org/POM/4.0.0" xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation = "http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>Sample</groupId> <artifactId>Sample</artifactId> <version>0.0.1-SNAPSHOT</version> <build> <sourceDirectory>src</sourceDirectory> <plugins> <plugin> <artifactId>maven-compiler-plugin</artifactId> <version>3.7.0</version> <configuration> <source>1.8</source> <target>1.8</target> </configuration> </plugin> </plugins> </build> <dependencies> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> <version>1.7.25</version> </dependency> </dependencies> </project>
SLF4J - 參考 API
在本章中,我們將討論在本教程後續章節中將使用的類和方法。
Logger 介面
org.slf4j 包的 Logger 介面是 SLF4J API 的入口點。以下是此介面的重要方法列表。
序號 | 方法和說明 |
---|---|
1 | void debug(String msg) 此方法以 DEBUG 級別記錄訊息。 |
2 | void error(String msg) 此方法以 ERROR 級別記錄訊息。 |
3 | void info(String msg) 此方法以 INFO 級別記錄訊息。 |
4 | void trace(String msg) 此方法以 TRACE 級別記錄訊息。 |
5 | void warn(String msg) 此方法以 WARN 級別記錄訊息。 |
LoggerFactory 類
org.slf4j 包的 LoggerFactory 類是一個實用程式類,用於為各種日誌 API(例如 log4j、JUL、NOP 和 simple logger)生成記錄器。
序號 | 方法和說明 |
---|---|
1 | Logger getLogger(String name) 此方法接受表示名稱的字串值,並返回具有指定名稱的 **Logger** 物件。 |
Profiler 類
此類屬於包 **org.slf4j**,用於效能分析目的,被稱為“窮人的效能分析器”。使用它,程式設計師可以找出執行長時間任務所需的時間。
以下是此類的重要方法。
序號 | 方法和說明 |
---|---|
1 | void start(String name) 此方法將啟動一個新的子秒錶(命名),並停止之前的子秒錶(或時間工具)。 |
2 | TimeInstrument stop() 此方法將停止最近的子秒錶和全域性秒錶,並返回當前時間工具。 |
3 | void setLogger(Logger logger) 此方法接受一個 Logger 物件並將指定的記錄器與當前 Profiler 關聯。 |
4 | void log() 記錄與記錄器關聯的當前時間工具的內容。 |
5 | void print() 列印當前時間工具的內容。 |
SLF4J - Hello World
在本章中,我們將看到一個使用 SLF4J 的簡單的基本記錄器程式。按照下面描述的步驟編寫一個簡單的記錄器。
步驟 1 - 建立 slf4j.Logger 介面的物件
由於 **slf4j.Logger** 是 SLF4J API 的入口點,因此首先需要獲取/建立其物件
**LoggerFactory** 類的 **getLogger()** 方法接受表示名稱的字串值,並返回具有指定名稱的 **Logger** 物件。
Logger logger = LoggerFactory.getLogger("SampleLogger");
步驟 2 - 記錄所需的訊息
**slf4j.Logger** 介面的 **info()** 方法接受表示所需訊息的字串值,並將其以 info 級別記錄。
logger.info("Hi This is my first SLF4J program");
示例
以下程式演示瞭如何使用 SLF4J 在 Java 中編寫示例記錄器。
import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class SLF4JExample { public static void main(String[] args) { //Creating the Logger object Logger logger = LoggerFactory.getLogger("SampleLogger"); //Logging the information logger.info("Hi This is my first SLF4J program"); } }
輸出
執行以下程式時,您將獲得以下輸出,而不是所需的訊息。
SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder". SLF4J: Defaulting to no-operation (NOP) logger implementation SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details.
由於我們尚未將類路徑設定為表示日誌框架的任何繫結,正如本教程前面提到的那樣,SLF4J 預設使用不執行操作的實現。因此,要檢視訊息,您需要將所需的繫結新增到專案類路徑中。由於我們使用的是 Eclipse,因此請為相應的 JAR 檔案設定 **構建路徑**,或在 pom.xml 檔案中新增其依賴項。
例如,如果我們需要使用 JUL(Java.util.logging 框架),我們需要為 jar 檔案 slf4j-jdk14-x.x.jar 設定構建路徑。如果我們想使用 log4J 日誌框架,我們需要設定 jar 檔案 slf4j-log4j12-x.x.jar 和 log4j.jar 的構建路徑或新增依賴項。
將表示任何日誌框架(除了 slf4j-nopx.x.jar)的繫結新增到專案(類路徑)後,您將獲得以下輸出。
Dec 06, 2018 5:29:44 PM SLF4JExample main INFO: Hi Welcome to Tutorialspoint
SLF4J - 錯誤訊息
在本章中,我們將討論使用 SLF4J 時遇到的各種錯誤訊息或警告,以及這些訊息的原因/含義。
無法載入類“org.slf4j.impl.StaticLoggerBinder”。
這是一個警告,它是在類路徑中沒有提供任何 SLF4J 繫結時引起的。
以下是完整的警告:
SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder". SLF4J: Defaulting to no-operation (NOP) logger implementation SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details.
要解決這個問題,您需要新增任一日誌框架繫結。本教程的HelloWorld章節對此進行了說明。
注意 − 這發生在 SLF4J 1.6.0 到 1.8.0-beta2 版本之間。
未找到任何 SLF4J 提供程式
在 slf4j-1.8.0-beta2 中,上述警告更加明確,顯示為“未找到任何 SLF4J 提供程式”。
以下是完整的警告:
SLF4J: No SLF4J providers were found. SLF4J: Defaulting to no-operation (NOP) logger implementation SLF4J: See http://www.slf4j.org/codes.html#noProviders for further details.
類路徑包含針對早於 1.8 的 slf4j-api 版本的 SLF4J 繫結
如果您使用的是 SLF4J 1.8 版本,並且類路徑中包含先前版本的繫結,但沒有 1.8 的繫結,則會看到如下所示的警告。
SLF4J: No SLF4J providers were found. SLF4J: Defaulting to no-operation (NOP) logger implementation SLF4J: See http://www.slf4j.org/codes.html#noProviders for further details. SLF4J: Class path contains SLF4J bindings targeting slf4j-api versions prior to 1.8. SLF4J: Ignoring binding found at [jar:file:/C:/Users/Tutorialspoint/Desktop/Latest%20Tutorials/SLF4J%20Tutorial/ slf4j-1.7.25/slf4j-jdk14-1.7.25.jar!/org/slf4j/impl/StaticLoggerBinder.class] SLF4J: See http://www.slf4j.org/codes.html#ignoredBindings for an explanation.
NoClassDefFoundError: org/apache/commons/logging/LogFactory
如果您使用的是slf4j-jcl,並且類路徑中只有slf4j-jcl.jar,則會得到如下所示的異常。
Exception in thread "main" java.lang.NoClassDefFoundError: org/apache/commons/logging/LogFactory at org.slf4j.impl.JCLLoggerFactory.getLogger(JCLLoggerFactory.java:77) at org.slf4j.LoggerFactory.getLogger(LoggerFactory.java:358) at SLF4JExample.main(SLF4JExample.java:8) Caused by: java.lang.ClassNotFoundException: org.apache.commons.logging.LogFactory at java.net.URLClassLoader.findClass(Unknown Source) at java.lang.ClassLoader.loadClass(Unknown Source) at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source) at java.lang.ClassLoader.loadClass(Unknown Source) ... 3 more
要解決這個問題,您需要將commons-logging.jar新增到您的類路徑。
在類路徑中檢測到 jcl-over-slf4j.jar 和繫結 slf4j-jcl.jar。
繫結slf4j-jcl.jar將 slf4j 日誌器的呼叫重定向到 JCL,而jcl-over-slf4j.jar將 JCL 日誌器的呼叫重定向到 slf4j。因此,您的專案類路徑中不能同時包含這兩個檔案。如果您這樣做,則會得到如下所示的異常。
SLF4J: Detected both jcl-over-slf4j.jar AND bound slf4j-jcl.jar on the class path, preempting StackOverflowError. SLF4J: See also http://www.slf4j.org/codes.html#jclDelegationLoop for more details. Exception in thread "main" java.lang.ExceptionInInitializerError at org.slf4j.impl.StaticLoggerBinder.<init>(StaticLoggerBinder.java:71) at org.slf4j.impl.StaticLoggerBinder.<clinit>(StaticLoggerBinder.java:42) at org.slf4j.LoggerFactory.bind(LoggerFactory.java:150) at org.slf4j.LoggerFactory.performInitialization(LoggerFactory.java:124) at org.slf4j.LoggerFactory.getILoggerFactory(LoggerFactory.java:412) at org.slf4j.LoggerFactory.getLogger(LoggerFactory.java:357) at SLF4JExample.main(SLF4JExample.java:8) Caused by: java.lang.IllegalStateException: Detected both jcl-over-slf4j.jar AND bound slf4j-jcl.jar on the class path, preempting StackOverflowError. See also http://www.slf4j.org/codes.html#jclDelegationLoop for more details. at org.slf4j.impl.JCLLoggerFactory.<clinit>(JCLLoggerFactory.java:54) ... 7 more
要解決這個問題,請刪除其中一個 jar 檔案。
檢測到日誌器名稱不匹配
您可以透過以下方式建立一個 Logger 物件:
將要建立的日誌器的名稱作為引數傳遞給getLogger()方法。
將一個類作為引數傳遞給此方法。
如果您嘗試透過傳遞一個類作為引數來建立日誌器工廠物件,並且您已將系統屬性slf4j.detectLoggerNameMismatch設定為 true,則作為引數傳遞給getLogger()方法的類的名稱和您使用的類應該相同,否則您將收到以下警告:
“檢測到日誌器名稱不匹配。”
考慮以下示例。
import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class SLF4JExample { public static void main(String[] args) { System.setProperty("slf4j.detectLoggerNameMismatch", "true"); //Creating the Logger object Logger logger = LoggerFactory.getLogger(Sample.class); //Logging the information logger.info("Hi Welcome to Tutorilspoint"); } }
在這裡,我們將slf4j.detectLoggerNameMismatch屬性設定為 true。我們使用的類的名稱是SLF4JExample,我們傳遞給getLogger()方法的類名是Sample,由於兩者不相等,我們將收到以下警告。
SLF4J: Detected logger name mismatch. Given name: "Sample"; computed name: "SLF4JExample". SLF4J: See http://www.slf4j.org/codes.html#loggerNameMismatch for an explanation Dec 10, 2018 12:43:00 PM SLF4JExample main INFO: Hi Welcome to Tutorilspoint
注意 − 這發生在 slf4j 1.7.9 之後
類路徑包含多個 SLF4J 繫結。
您應該只在類路徑中包含一個繫結。如果您有多個繫結,則會收到一個警告,列出這些繫結及其位置。
例如,如果我們的類路徑中包含slf4j-jdk14.jar和slf4j-nop.jar繫結,我們將收到以下警告。
SLF4J: Class path contains multiple SLF4J bindings. SLF4J: Found binding in [jar:file:/C:/Users/Tutorialspoint/Desktop/Latest%20Tutorials/SLF4J%20Tutorial/ slf4j-1.7.25/slf4j-nop-1.7.25.jar!/org/slf4j/impl/StaticLoggerBinder.class] SLF4J: Found binding in [jar:file:/C:/Users/Tutorialspoint/Desktop/Latest%20Tutorials/SLF4J%20Tutorial/ slf4j-1.7.25/slf4j-jdk14-1.7.25.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 [org.slf4j.helpers.NOPLoggerFactory]
在類路徑中檢測到 log4j-over-slf4j.jar 和繫結 slf4j-log4j12.jar。
要將 log4j 日誌器呼叫重定向到 slf4j,您需要使用log4j-over-slf4j.jar繫結;如果您想將 slf4j 呼叫重定向到 log4j,您需要使用slf4j-log4j12.jar繫結。
因此,您不能同時在類路徑中包含兩者。如果您這樣做,則會收到以下異常。
SLF4J: Detected both log4j-over-slf4j.jar AND bound slf4j-log4j12.jar on the class path, preempting StackOverflowError. SLF4J: See also http://www.slf4j.org/codes.html#log4jDelegationLoop for more details. Exception in thread "main" java.lang.ExceptionInInitializerError at org.slf4j.impl.StaticLoggerBinder.<init>(StaticLoggerBinder.java:72) at org.slf4j.impl.StaticLoggerBinder.<clinit>(StaticLoggerBinder.java:45) at org.slf4j.LoggerFactory.bind(LoggerFactory.java:150) at org.slf4j.LoggerFactory.performInitialization(LoggerFactory.java:124) at org.slf4j.LoggerFactory.getILoggerFactory(LoggerFactory.java:412) at org.slf4j.LoggerFactory.getLogger(LoggerFactory.java:357) at org.slf4j.LoggerFactory.getLogger(LoggerFactory.java:383) at SLF4JExample.main(SLF4JExample.java:8) Caused by: java.lang.IllegalStateException: Detected both log4j-over-slf4j.jar AND bound slf4j-log4j12.jar on the class path, preempting StackOverflowError. See also http://www.slf4j.org/codes.html#log4jDelegationLoop for more details.
SLF4J - 引數化日誌
正如本教程前面所述,SLF4J 提供了對引數化日誌訊息的支援。
您可以在訊息中使用引數,並在稍後的同一語句中傳遞值。
語法
如下所示,您需要在訊息(字串)中使用佔位符({}),稍後您可以以物件形式為佔位符傳遞值,用逗號分隔訊息和值。
Integer age; Logger.info("At the age of {} ramu got his first job", age);
示例
以下示例演示了使用 SLF4J 進行引數化日誌記錄(使用單個引數)。
import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class PlaceHolders { public static void main(String[] args) { //Creating the Logger object Logger logger = LoggerFactory.getLogger(PlaceHolders.class); Integer age = 23; //Logging the information logger.info("At the age of {} ramu got his first job", age); } }
輸出
執行後,上述程式將生成以下輸出:
Dec 10, 2018 3:25:45 PM PlaceHolders main INFO: At the age of 23 Ramu got his first job
引數化日誌記錄的優勢
在 Java 中,如果我們需要在一個語句中列印值,我們將使用連線運算子,如下所示:
System.out.println("At the age of "+23+" ramu got his first job");
這涉及將整數 23 轉換為字串並將該值與周圍的字串連線起來。
如果這是一個日誌記錄語句,並且該語句的特定日誌級別被停用,那麼所有這些計算都是沒有用的。
在這種情況下,您可以使用引數化日誌記錄。在此格式中,SLF4J 最初會確認是否啟用了特定級別的日誌記錄。如果是,則它會將訊息中的佔位符替換為相應的值。
例如,如果我們有一個語句:
Integer age; Logger.debug("At the age of {} ramu got his first job", age);
只有在啟用除錯時,SLF4J 才會將年齡轉換為整數並將其與字串連線起來,否則什麼也不做。因此,在日誌級別被停用時會產生引數構造的成本。
兩個引數變體
您也可以在訊息中使用兩個引數,如下所示:
logger.info("Old weight is {}. new weight is {}.", oldWeight, newWeight);
示例
以下示例演示了在引數化日誌記錄中使用兩個佔位符。
import java.util.Scanner; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class PlaceHolders { public static void main(String[] args) { Integer oldWeight; Integer newWeight; Scanner sc = new Scanner(System.in); System.out.println("Enter old weight:"); oldWeight = sc.nextInt(); System.out.println("Enter new weight:"); newWeight = sc.nextInt(); //Creating the Logger object Logger logger = LoggerFactory.getLogger(Sample.class); //Logging the information logger.info("Old weight is {}. new weight is {}.", oldWeight, newWeight); //Logging the information logger.info("After the program weight reduced is: "+(oldWeight-newWeight)); } }
輸出
執行後,上述程式將生成以下輸出。
Enter old weight: 85 Enter new weight: 74 Dec 10, 2018 4:12:31 PM PlaceHolders main INFO: Old weight is 85. new weight is 74. Dec 10, 2018 4:12:31 PM PlaceHolders main INFO: After the program weight reduced is: 11
多個引數變體
您還可以使用兩個以上的佔位符,如下例所示:
import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class PlaceHolders { public static void main(String[] args) { Integer age = 24; String designation = "Software Engineer"; String company = "Infosys"; //Creating the Logger object Logger logger = LoggerFactory.getLogger(Sample.class); //Logging the information logger.info("At the age of {} ramu got his first job as a {} at {}", age, designation, company); } }
輸出
執行後,上述程式將生成以下輸出:
Dec 10, 2018 4:23:52 PM PlaceHolders main INFO: At the age of 24 ramu got his first job as a Software Engineer at Infosys
SLF4J - 遷移工具
如果您有一個 Jakarta Commons Logging (JCL) 或 log4j 或 java.util.logging (JUL) 專案,並且想要將這些專案轉換為 SLF4J,您可以使用 SLF4J 分發版中提供的遷移工具。

執行 SLF4J 遷移器
SLF4J 是一個簡單的單個 jar 檔案 (slf4j-migrator.jar),您可以使用 java –jar 命令執行它。
要執行它,請在命令提示符中瀏覽到您擁有此 jar 檔案的目錄,然後執行以下命令。
java -jar slf4j-migrator-1.8.0-beta2.jar Starting SLF4J Migrator
這將啟動遷移器,您將看到一個獨立的 Java 應用程式,如下所示:

如視窗中指定的那樣,您需要檢查要執行的遷移型別,選擇專案目錄,然後單擊“遷移專案到 SLF4J”按鈕。
此工具會轉到您提供的原始檔,並執行簡單的修改,例如將匯入行和日誌器宣告從當前日誌框架更改為 SLF4j。
示例
例如,假設我們在 eclipse 中有一個示例log4j(2)專案,其中包含一個檔案,如下所示:
import org.apache.log4j.Logger; import java.io.*; import java.sql.SQLException; import java.util.*; public class Sample { /* Get actual class name to be printed on */ static Logger log = Logger.getLogger(Sample.class.getName()); public static void main(String[] args)throws IOException,SQLException { log.debug("Hello this is a debug message"); log.info("Hello this is an info message"); } }
要將示例log4j(2)專案遷移到 slf4j,我們需要選中從 log4j 到 slf4j單選按鈕,選擇專案的目錄,然後單擊退出以進行遷移。

遷移器將上述程式碼更改如下。在這裡,如果您觀察匯入和日誌器語句,它們已被修改。
import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.io.*; import java.sql.SQLException; import java.util.*; public class Sample { static Logger log = LoggerFactory.getLogger(Sample.class.getName()); public static void main(String[] args)throws IOException,SQLException { log.debug("Hello this is a debug message"); log.info("Hello this is an info message"); } }
由於您的專案中已經有了log4j.jar,您需要將slf4j-api.jar和slf4j-log4j12.jar檔案新增到專案中才能執行它。
SLF4JMigrator 的限制
以下是 SLF4J 遷移器的限制。
遷移器不會修改像 ant、maven 和 ivy 這樣的構建指令碼,您需要自己動手。
遷移器不支援除字串型別以外的訊息。
遷移器不支援 FATAL 級別。
在使用 log4j 時,遷移器不會遷移對 PropertyConfigurator 或 DomConfigurator 的呼叫。
SLF4J - 效能分析
SLF4J 分發版提供slf4j-ext.jar,其中包含用於分析、擴充套件日誌記錄、事件日誌記錄和使用 Java 代理進行日誌記錄等功能的 API。
分析
有時程式設計師想要測量程式的某些屬性,例如記憶體使用情況、時間複雜度或特定指令的使用情況,以衡量該程式的實際能力。這種對程式的測量稱為分析。分析使用動態程式分析來進行這種測量。
SLF4J 在org.slf4j.profiler包中提供了一個名為Profiler的類用於分析目的。這被稱為“窮人版”分析器。使用它,程式設計師可以找出執行長時間任務所花費的時間。
使用 Profiler 類進行分析
分析器包含秒錶和子秒錶,我們可以使用分析器類提供的方法啟動和停止它們。
要使用分析器類繼續進行分析,請按照以下步驟操作。
步驟 1 - 例項化分析器類
透過傳遞一個表示分析器名稱的字串值來例項化 Profiler 類。當我們例項化 Profiler 類時,將啟動一個全域性秒錶。
//Creating a profiler Profiler profiler = new Profiler("Sample");
步驟 2 - 啟動子秒錶
當我們呼叫start()方法時,它將啟動一個新的子秒錶(命名),並停止之前的子秒錶(或時間工具)。
透過傳遞一個表示要建立的子秒錶名稱的字串值來呼叫Profiler類的start()方法。
//Starting a child stopwatch and stopping the previous one. profiler.start("Task 1"); obj.demoMethod1();
建立這些秒錶後,您可以執行您的任務或呼叫執行您的任務的那些方法。
步驟 3:啟動另一個子秒錶(如果您希望)
如果需要,可以使用start()方法建立另一個秒錶並執行所需的任務。如果您這樣做,它將啟動一個新的秒錶並停止之前的秒錶(即任務 1)。
//Starting another child stopwatch and stopping the previous one. profiler.start("Task 2"); obj.demoMethod2();
步驟 4:停止秒錶
當我們呼叫stop()方法時,它將停止最近的子秒錶和全域性秒錶,並返回當前時間工具。
// Stopping the current child stopwatch and the global stopwatch. TimeInstrument tm = profiler.stop();
步驟 5:列印時間工具的內容。
使用print()方法列印當前時間工具的內容。
//printing the contents of the time instrument tm.print();
示例
以下示例演示了使用 SLF4J 的 Profiler 類進行分析。在這裡,我們採用了兩個示例任務,列印從 1 到 10000 的數字的平方和,列印從 1 到 10000 的數字的和。我們試圖獲得這兩個任務所花費的時間。
import org.slf4j.profiler.Profiler; import org.slf4j.profiler.TimeInstrument; public class ProfilerExample { public void demoMethod1(){ double sum = 0; for(int i=0; i< 1000; i++){ sum = sum+(Math.pow(i, 2)); } System.out.println("Sum of squares of the numbers from 1 to 10000: "+sum); } public void demoMethod2(){ int sum = 0; for(int i=0; i< 10000; i++){ sum = sum+i; } System.out.println("Sum of the numbers from 1 to 10000: "+sum); } public static void main(String[] args) { ProfilerExample obj = new ProfilerExample(); //Creating a profiler Profiler profiler = new Profiler("Sample"); //Starting a child stop watch and stopping the previous one. profiler.start("Task 1"); obj.demoMethod1(); //Starting another child stop watch and stopping the previous one. profiler.start("Task 2"); obj.demoMethod2(); //Stopping the current child watch and the global watch. TimeInstrument tm = profiler.stop(); //printing the contents of the time instrument tm.print(); } }
輸出
執行後,上述程式將生成以下輸出:
Sum of squares of the numbers from 1 to 10000: 3.328335E8 Sum of the numbers from 1 to 10000: 49995000 + Profiler [BASIC] |-- elapsed time [Task 1] 2291.827 microseconds. |-- elapsed time [Task 2] 225.802 microseconds. |-- Total [BASIC] 3221.598 microseconds.
記錄分析器資訊
為了將分析器的結果記錄到日誌中,您需要:
使用LoggerFactory類建立一個日誌器。
透過例項化 Profiler 類來建立一個分析器。
透過將建立的日誌器物件傳遞給Profiler類的setLogger()方法來將日誌器與分析器關聯。
最後,使用log()方法記錄分析器的資訊,而不是列印它。
示例
在下面的示例中,與之前的示例不同(不是列印),我們嘗試記錄時間工具的內容。
import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.slf4j.profiler.Profiler; import org.slf4j.profiler.TimeInstrument; public class ProfilerExample_logger { public void demoMethod1(){ double sum = 0; for(int i=0; i< 1000; i++){ sum = sum+(Math.pow(i, 2)); } System.out.println("Sum of squares of the numbers from 1 to 10000: "+sum); } public void demoMethod2(){ int sum = 0; for(int i=0; i< 10000; i++){ sum = sum+i; } System.out.println("Sum of the numbers from 1 to 10000: "+sum); } public static void main(String[] args) { ProfilerExample_logger obj = new ProfilerExample_logger(); //Creating a logger Logger logger = LoggerFactory.getLogger(ProfilerExample_logger.class); //Creating a profiler Profiler profiler = new Profiler("Sample"); //Adding logger to the profiler profiler.setLogger(logger); //Starting a child stop watch and stopping the previous one. profiler.start("Task 1"); obj.demoMethod1(); //Starting another child stop watch and stopping the previous one. profiler.start("Task 2"); obj.demoMethod2(); //Stopping the current child watch and the global watch. TimeInstrument tm = profiler.stop(); //Logging the contents of the time instrument tm.log(); } }
輸出
執行後,上述程式將生成以下輸出。
Sum of squares of the numbers from 1 to 10000: 3.328335E8 Sum of the numbers from 1 to 10000: 49995000