日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

slf4j 记录日志文件_教程:正确的SLF4J日志记录用法以及如何检查它

發(fā)布時(shí)間:2023/12/3 编程问答 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 slf4j 记录日志文件_教程:正确的SLF4J日志记录用法以及如何检查它 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

slf4j 記錄日志文件

SLF4J是一個(gè)非常流行的日志記錄外觀,但是,就像我們使用的所有庫一樣,我們有可能以錯(cuò)誤的方式或至少以一種非最佳方式使用它。

在本教程中,我們將列出常見的日志記錄錯(cuò)誤以及如何使用FindBugs檢測到它們。 我們還將在相關(guān)時(shí)提及PMD和Sonar Squid檢查。

我們將使用兩個(gè)外部FindBugs插件,它們將日志記錄檢測器添加到FindBugs。

第一個(gè)是Kengo Toda的SLF4J only插件 ,其中僅包含SLF4J檢測器。

第二個(gè)插件是流行的FB Contrib ,其中包含許多測井儀。

有關(guān)如何使用FindBugs插件的信息,請參閱以下文章:

  • [Maven]( https://gualtierotesta.wordpress.com/2015/06/14/tutorial-using-findbugs-with-maven/ )
  • [NetBeans]( https://gualtierotesta.wordpress.com/2015/06/07/findbugs-plugins/ )

注意:在所有示例中,我們將假定以下導(dǎo)入:

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

1.記錄儀定義

錯(cuò)誤的方法:

W1a. Logger log = LoggerFactory.getLogger(MyClass.class); W1b. private Logger logger = LoggerFactory.getLogger(MyClass.class); W1c. static Logger LOGGER = LoggerFactory.getLogger(AnotherClass.class);

正確方法:

C1a. private static final Logger LOGGER = LoggerFactory.getLogger(MyClass.class); C1b. private final Logger logger = LoggerFactory.getLogger(getClass());

一般規(guī)則 :記錄器應(yīng)該是最終的且私有的,因?yàn)闆]有理由與其他課程共享或重新分配記錄器。

相反,對于記錄器是否應(yīng)該是靜態(tài)的,并沒有普遍的共識。 SLF4J插件支持非靜態(tài)版本(C1b),而PMD(“ LoggerIsNotStaticFinal”規(guī)則)和Sonar(魷魚規(guī)則S1312)更喜歡靜態(tài)記錄器(C1a),因此這兩個(gè)選項(xiàng)均應(yīng)視為有效。

附加信息:

  • [SLF4J常見問題解答]( http://slf4j.org/faq.html#declared_static )
  • [Apache Commons靜態(tài)日志]( http://wiki.apache.org/commons/Logging/StaticLog )。

請注意:

  • 在靜態(tài)版本(C1a)中,記錄器名稱通常使用大寫字母作為所有常量字段。 否則,PMD將報(bào)告“ VariableNamingConventions”違規(guī)行為。
  • 在這兩種情況下,建議的名稱都是“ logger / LOGGER”而不是“ log / LOG”,因?yàn)槟承┟s定會避免使用太短的名稱(少于四個(gè)字符)。 而且log是動(dòng)詞,更適合于方法名。
  • W1c是錯(cuò)誤的,因?yàn)槲覀冎傅氖且粋€(gè)類(AnotherClass),它不是定義記錄器的類。 在99%的情況下,這是由于從一類復(fù)制到另一類而導(dǎo)致的。

相關(guān)的FindBugs(SLF4J插件)檢查:

  • SLF4J_LOGGER_SHOULD_BE_PRIVATE
  • SLF4J_LOGGER_SHOULD_BE_NON_STATIC
  • SLF4J_LOGGER_SHOULD_BE_FINAL
  • SLF4J_ILLEGAL_PASSED_CLASS

2.格式字符串

錯(cuò)誤的方法:

W2a. LOGGER.info("Obj=" + myObj); W2b. LOGGER.info(String.format(“Obj=%s”, myObj));

正確方法:

C2. LOGGER.info("Obj={}",myObj);

一般規(guī)則 :格式字符串(第一個(gè)參數(shù))應(yīng)為常量,沒有任何字符串串聯(lián)。 動(dòng)態(tài)內(nèi)容(示例中的myObj值)應(yīng)使用占位符(“ {}”)添加。

動(dòng)機(jī)很簡單:無論是否記錄消息,我們都應(yīng)在記錄器建立延遲記錄消息的創(chuàng)建,具體取決于當(dāng)前的記錄級別。 如果我們使用字符串連接,則無論采用哪種日志記錄級別,都會以任何方式構(gòu)建消息,這會浪費(fèi)CPU和內(nèi)存資源。

相關(guān)的FindBugs(SLF4J插件)檢查:

  • SLF4J_FORMAT_SHOULD_BE_CONST格式應(yīng)為常數(shù)
  • SLF4J_SIGN_ONLY_FORMAT格式字符串不應(yīng)僅包含占位符

相關(guān)的FindBugs(FB Contrib插件)檢查:

  • LO_APPENDED_STRING_IN_FORMAT_STRING方法將串聯(lián)的字符串傳遞給SLF4J的格式字符串

3.占位符參數(shù)

錯(cuò)誤的方法:

W3a. LOGGER.info("Obj={}",myObj.getSomeBigField()); W3b. LOGGER.info("Obj={}",myObj.toString()); W3c. LOGGER.info("Obj={}",myObj, anotherObj); W3d. LOGGER.info("Obj={} another={}",myObj);

正確方法:

C3a. LOGGER.info("Obj={}",myObj); C3b. LOGGER.info("Obj={}",myObj.log());

一般規(guī)則 :占位符應(yīng)該是對象(C3a),而不是方法返回值(W3a),以便在記錄級別分析后推遲對其求值(請參見上一段)。 在W3a示例中,無論日志記錄級別如何,都會始終調(diào)用方法getSomeBigField()。 出于同樣的原因,我們應(yīng)該避免在語義上與C3a等效的W3b,但是它總是在toString()方法調(diào)用中產(chǎn)生。

解決方案W3c和W3d是錯(cuò)誤的,因?yàn)楦袷阶址械恼嘉环麛?shù)量與占位符參數(shù)數(shù)量不匹配。

解決方案C3b可能在某種程度上具有誤導(dǎo)性,因?yàn)樗椒ㄕ{(diào)用,但是每當(dāng)myObj包含多個(gè)字段(例如,它是一個(gè)大型JPA實(shí)體)但我們不想記錄其所有內(nèi)容時(shí),它就很有用。

例如,讓我們考慮以下類:

public class Person { private String id; private String name; private String fullName; private Date birthDate; private Object address; private Map<String, String> attributes; private List phoneNumbers;

它的toString()方法很可能會包含所有字段。 使用解決方案C3a,所有它們的值都將打印在日志文件中。

如果不需要所有這些數(shù)據(jù),則定義如下的幫助方法將很有用:

public String log() { return String.format("Person: id=%s name=%s", this.id, this.name); }

僅打印相關(guān)信息。 此解決方案的CPU和內(nèi)存也比toString()輕。

有什么關(guān)系? 它取決于應(yīng)用程序和對象類型。 對于JPA實(shí)體,我通常在log()方法中包括ID字段(以便在需要所有列數(shù)據(jù)時(shí)讓我在數(shù)據(jù)庫中找到記錄),并且可能是一個(gè)或兩個(gè)重要字段。

毫無疑問,應(yīng)該記錄密碼字段和/或敏感信息(電話號碼,...)。 這是不使用toString()登錄的另一個(gè)原因。

相關(guān)的FindBugs(SLF4J插件)檢查:

  • SLF4J_PLACE_HOLDER_MISMATCH

4.調(diào)試消息

重要提示:規(guī)則4(請參閱5條規(guī)則文章 )指導(dǎo)我們使用受保護(hù)的調(diào)試日志記錄

if (LOGGER.isDebugEnabled()) { LOGGER.debug(“Obj={}”, myObj); }

使用SLF4J,如果占位符參數(shù)是對象引用(請參閱解決方案C3a / C3b),則可以使用if來避免代碼混亂。

因此,使用以下內(nèi)容是安全的:

LOGGER.debug(“Obj={}”, myObj);

5.例外

適當(dāng)?shù)漠惓H罩居涗浭菃栴}分析的重要支持,但很容易忽略它的用處。

錯(cuò)誤的方法:

W5a. catch (SomeException ex) { LOGGER.error(ex);}.. W5b. catch (SomeException ex) { LOGGER.error("Error:" + ex.getMessage());}..

正確方法:

C5. catch (SomeException ex) { LOGGER.error("Read operation failed: id={}", idRecord, ex);}..`

一般規(guī)則 :

  • 不要使用getMessage()(請參閱W5b)而不是完整的異常來刪除堆棧跟蹤信息。 堆棧跟蹤通常包括問題的真正原因,很容易是底層代碼引發(fā)的另一個(gè)異常。 僅記錄消息將阻止我們發(fā)現(xiàn)問題的真正原因。
  • 確實(shí)在日志消息中顯示了重要的信息(對于將要分析日志文件的人員),該信息顯示了一個(gè)文本,解釋了在引發(fā)異常(不是異常種類或諸如“錯(cuò)誤”之類的消息)時(shí)我們想要執(zhí)行的操作:我們已經(jīng)知道有些不良情況發(fā)生了)。 我們需要知道的是我們在做什么以及在哪些數(shù)據(jù)上。
  • C5示例告訴我們,我們正在嘗試讀取具有特定ID的記錄,該ID的值已與消息一起寫入了日志。

    請注意,C5在格式字符串中使用一個(gè)占位符,但是有兩個(gè)附加參數(shù)。 這不是錯(cuò)誤,而是一種特殊的模式,SLF4J將其識別為異常記錄案例:最后一個(gè)參數(shù)(在C5示例中為ex)被SLF4J視為Throwable(異常),因此不應(yīng)將其包含在格式字符串中。

    相關(guān)的FindBugs(SLF4J插件)檢查:

    • SLF4J_MANUALLY_PROVIDED_MESSAGE:消息不應(yīng)基于異常getMessage()

    翻譯自: https://www.javacodegeeks.com/2016/02/tutorial-correct-slf4j-logging-usage-check.html

    slf4j 記錄日志文件

    總結(jié)

    以上是生活随笔為你收集整理的slf4j 记录日志文件_教程:正确的SLF4J日志记录用法以及如何检查它的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。