CodeGym /Java Blog /Toto sisi /Java 日誌記錄
John Squirrels
等級 41
San Francisco

Java 日誌記錄

在 Toto sisi 群組發布
你好!在編寫課程時,我特別強調是否有一個特定的主題在實際工作中是絕對必要的。所以,聽好了!從就業的第一天起,我們今天要討論的主題肯定會在您的所有項目中派上用場。我們將討論 Java 日誌記錄。這個話題一點也不復雜(我什至會說簡單)。但是在您的第一份工作中您將有足夠多明顯的事情需要強調,因此最好現在就徹底理解它 :) 好吧,讓我們開始吧。

Java 中的日誌記錄是什麼?

日誌記錄是記錄有關程序運行的數據的行為。我們記錄這些數據的地方叫做“日誌”。立即出現兩個問題:寫入什麼數據以及寫入何處?讓我們從“哪裡”開始。您可以在許多不同的地方編寫有關程序工作的數據。例如,在你學習期間,你經常使用System.out.println()將數據輸出到控制台。這確實是日誌記錄,儘管是最簡單的形式。當然,這對用戶或產品支持團隊來說不是很方便:顯然,他們不想安裝 IDE 並監視控制台 :) 有一種更常用的信息記錄格式:文本文件。人類閱讀這種格式的數據要舒服得多,當然存儲數據也方便得多!現在是第二個問題:應該記錄哪些程序數據?這完全取決於你!Java 的日誌系統非常靈活。您可以將其配置為記錄您的程序所做的一切。一方面,這很好。但另一方面,想像一下,如果 Facebook 或 Twitter 的日誌將所有內容都寫入其中,那麼它們的日誌會有多大。這些大公司可能確實有能力存儲那麼多數據。但想像一下,在 500 GB 的文本日誌中找到關於一個嚴重錯誤的信息會有多困難?這比大海撈針還糟糕。因此,Java 可以配置為僅記錄錯誤數據。甚至只是嚴重錯誤!也就是說,談論 Java 的本機日誌系統並不完全準確。事實上,在將此功能添加到語言之前,程序員需要日誌記錄。當 Java 推出自己的日誌庫時,每個人都已經在使用 log4j 庫。Java 中的日誌記錄歷史實際上非常悠久且內容豐富。總之,Java有自己的日誌庫,但是幾乎沒有人用:)後來,當幾個不同的日誌庫出現並開始被程序員使用時,兼容性問題就出現了。為了阻止人們在十幾個具有不同接口的不同庫中重新發明輪子,創建了抽象的 SLF4J 框架(“Service Logging Facade For Java”)。之所以稱為抽象,是因為即使您使用和調用 SLF4J 類的方法,在幕後它們實際上使用了之前出現的所有日誌記錄框架:log4j、標準 java.util.logging 等。如果在某些時候您需要其他庫缺少的 Log4j 的某些特定功能,但又不想將您的項目直接鏈接到該庫,只需使用 SLF4J。然後讓它調用 Log4j 方法。如果您改變主意並決定不再需要 Log4j 功能,則只需重新配置“此處,以及此處的Log4j 庫。接下來,解壓存檔並使用 IntelliJ IDEA 將 JAR 文件添加到類路徑中。菜單項:File -> Project Structure -> Libraries 選擇需要的JAR文件並添加到項目中(我們下載的archives包含很多JAR文件——看圖片就可以看到你需要的)注意這個指令是給那些同學 的誰不知道如何使用 Maven。如果您知道如何使用 Maven,通常最好(更容易)嘗試從那裡開始。 如果您使用Maven,請添加此依賴項: 為什麼我們需要日誌 - 2為什麼我們需要日誌記錄 - 3

    	<dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-slf4j-impl</artifactId>
            <version>2.14.0</version>
    	</dependency>
偉大的!我們弄清楚了設置 :) 讓我們看看 SLF4J 是如何工作的。我們如何確保程序的工作記錄在某處?為此,我們需要兩件事:記錄器和追加器。讓我們從第一個開始。記錄器是提供對日誌記錄的完全控制的對象。創建記錄器非常簡單:我們使用靜態LoggerFactory.getLogger()方法來完成此操作。方法參數是將記錄其操作的類。讓我們運行我們的代碼:

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class MyTestClass {

   public static final Logger LOGGER = LoggerFactory.getLogger(MyTestClass.class);

   public static void main(String[] args) {

       LOGGER.info("Test log entry!!!");
       LOGGER.error("An error occurred!");
   }
}
控制台輸出:

ERROR StatusLogger No Log4j 2 configuration file found. Using default configuration (logging only errors to the console), or user programmatically provided configurations. Set system property 'log4j2.debug' to show Log4j 2 internal initialization logging. See https://logging.apache.org/log4j/2.x/manual/configuration.html for instructions on how to configure Log4j 2 15:49:08.907 [main] ERROR MyTestClass - An error occurred!
我們在這裡看到了什麼?首先,我們看到一條錯誤消息。這是因為現在我們缺少必要的設置。因此,我們的記錄器目前只能輸出錯誤消息 (ERROR),並且只能輸出到控制台。logger.info ()方法不起作用。但是logger.error()做到了!在控制台上,我們看到當前日期,錯誤發生的方法(main),單詞“ERROR”,以及我們的信息!ERROR 是日誌級別。一般來說,如果一個日誌條目被標記為“ERROR”,那麼程序就在此時發生了錯誤。如果該條目標有單詞“INFO”,則該消息僅表示有關程序正常運行的當前信息。SLF4J 庫有很多不同的日誌記錄級別,可以讓您靈活地配置日誌記錄。這一切都非常易於管理:所有必要的邏輯都已在 Java Logger類中。你只需要調用相關的方法。如果要記錄常規消息,請調用 logger.info()方法。對於錯誤消息,請使用logger.error()。對於警告,請使用logger.warn()

現在讓我們談談appender

appender 是你的數據去的地方。在某種程度上,數據源的對立面,即“B點”。默認情況下,數據輸出到控制台。請注意,在前面的示例中,我們無需進行任何配置:文本出現在控制台中,Log4j 庫的記錄器只能向控制台輸出 ERROR 級別的消息。很明顯,人們在文本文件中讀寫日誌更方便。要更改記錄器的默認行為,我們需要配置文件附加程序。首先,您需要直接在 src 文件夾中創建一個 log4j.xml 文件。您已經熟悉 XML 格式:我們最近上了一堂關於它的:) 以下是文件的內容:

<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="INFO">
   <Appenders>
       <File name="MyFileAppender" fileName="C:\Users\Username\Desktop\testlog.txt" immediateFlush="false" append="false">
           <PatternLayout pattern="%d{yyy-MM-dd HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
       </File>
   </Appenders>
   <Loggers>
       <Root level="INFO">
           <AppenderRef ref="MyFileAppender"/>
       </Root>
   </Loggers>
</Configuration>
這裡沒有什麼特別的或困難的:) 但是,讓我們過一遍內容。
<Configuration status="INFO">
這就是所謂的 StatusLogger。它與我們的記錄器無關,用於 Log4j 的內部進程。如果你設置 status="TRACE" 而不是 status="INFO",那麼所有關於 Log4j 內部工作的信息都會顯示在控制台上(StatusLogger 在控制台上顯示數據,即使我們的 appender 是一個文件)。我們現在不需要它,所以讓我們保持原樣。

<Appenders>
   <File name="MyFileAppender" fileName="C:\Users\Evgeny\Desktop\testlog.txt" append="true">
       <PatternLayout pattern="%d{yyy-MM-dd HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
   </File>
</Appenders>
在這裡我們創建我們的 appender。<File>標籤表明它將是一個文件追加器 name="MyFileAppender"設置附加程序的名稱。 fileName="C:\Users\Username\Desktop\testlog.txt"指示將寫入所有數據的日誌文件的路徑。 append="true"表示數據是否應該寫在文件的末尾。在我們的例子中,這正是我們要做的。如果將該值設置為 false,則每次啟動程序時都會刪除日誌文件的舊內容。 <PatternLayout pattern="%d{yyy-MM-dd HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>表示格式設置。在這裡,我們可以使用正則表達式來自定義日誌中文本的格式。

<Loggers>
       <Root level="INFO">
           <AppenderRef ref="MyFileAppender"/>
       </Root>
</Loggers>
此處我們指示根級別。我們設置了“INFO”級別,這意味著所有級別高於 INFO 的消息(根據我們上面查看的表格)將不會被記錄。我們的程序將有 3 條消息:一條 INFO、一條 WARN 和一條 ERROR。使用當前配置,將記錄所有 3 條消息。如果將根級別更改為 ERROR,則只有來自 LOGGER.error() 方法調用的最後一條消息才會出現在日誌中。此外,此處還包含對 appender 的引用。要創建這樣的引用,您需要在<Root>標記內創建一個<ApprenderRef>標記,並向其添加ref='your appender's name'屬性。以防你忘記了,這是我們設置 appender 名稱的地方:<. 這是我們的代碼!

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class MyTestClass {

   public static final Logger LOGGER = LoggerFactory.getLogger(MyTestClass.class);

   public static void main(String[] args) {

       LOGGER.info("The program is starting!!!");

       try {
           LOGGER.warn("Attention! The program is trying to divide a number by another.
           System.out.println(12/0);
       } catch (ArithmeticException x) {

           LOGGER.error("Error! Division by zero!");
       }
   }
}
當然,它有點古怪(捕獲 RuntimeException 是一個有問題的想法),但它非常適合我們的目的:) 讓我們連續運行main()方法 4 次並查看我們的 testlog.txt 文件。您不需要提前創建它:庫會自動執行此操作。一切正常!:) 現在你有一個配置好的記錄器。您可以嘗試一些舊程序,為每個方法添加記錄器調用。然後查看生成的日誌 :) 它深入考慮了日誌記錄的主題。一次閱讀所有內容將是一項挑戰。也就是說,它確實包含很多額外的有用信息。例如,您將學習如何配置記錄器,以便在我們的 testlog.txt 文件達到特定大小時創建一個新的文本文件 :) 我們的課程到此結束!今天你熟悉了一個很重要的話題,這些知識一定會對你以後的工作有所幫助。直到下一次!:)
留言
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION