亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

RestAPI 日志記錄實踐問題

RestAPI 日志記錄實踐問題

守著星空守著你 2023-06-08 17:34:50
我在記錄應用程序事件時遇到了這個問題。下面是要求。記錄正在發生的基本應用程序事件、方法調用、它們的參數、返回、處理時間等。但只有日志文件必須包含每個請求的 3 行日志。第一行:記錄請求詳細信息,當請求進來時。第二行:記錄所有應用程序事件(這是問題所在)第三行:記錄請求銷毀事件,當請求完成它的生命周期時。這三個請求由命中請求時創建的事務 ID 標識,該 ID 放在MDCof中slf4j?,F在我被告知使用 aStringBuilder來附加日志記錄詳細信息,它應該在控制器方法中初始化,將它的引用傳遞給每個被調用的方法,StringBuilder在finally控制器方法塊中記錄內容。此實現使整個代碼庫變得丑陋。所以我嘗試使用ThreadLocal帶有 a 的 varStringBuilder來存儲日志記錄詳細信息,并在請求被銷毀時清理它以避免內存泄漏。相反,我嘗試使用如下所示的實現(偽)。ThreadLocal用初始值初始化。public static ThreadLocal<StringBuilder> log = new ThreadLocal<StringBuilder>() {    @Override protected StringBuilder initialValue() {        return new StringBuilder("|Internal");    }};將詳細信息附加到ThreadLocal本版StringBuilderSomeClass.log.get().append("|").append(whatever);所有處理完成后,在 finally 塊的控制器方法中將此內容寫入日志文件作為日志的第二行,然后將其清理。但是我的隊友對此非常懷疑。你能告訴我在這種情況下的實施有什么問題嗎(這是一個好方法)?是否存在內存泄漏等問題?對此的任何評論都非常感謝。
查看完整描述

1 回答

?
德瑪西亞99

TA貢獻1770條經驗 獲得超3個贊

直接解決您的問題

從技術上講,我看到這種方法有兩個問題:

  1. 所有控制器方法都需要清理本地線程。這足以讓某個地方的某個人忘記將這個 finally 塊放在某個控制器中 - 事情將開始崩潰。如果不清理 StringBuilder,也會發生內存泄漏。因此,對于通過“泄漏”控制器的所有線程,數據將越來越多地累積。

  2. 如果由于某種原因 BL 在另一個線程中生成/執行,代碼將中斷。

現在關于功能本身。我看到了這樣一個要求的兩個可能的理由:

  • 審計

  • 計量

如果我們談論的是計量,考慮到您已經在使用 spring boot,您可以使用 Dropwizard 指標(spring boot 1.x)或 Micrometer(spring boot 2.x,帶有可向后移植到 1.5.x)

如果我們談論的是審計,那么與支持清理所有控制器中的內容的日志記錄的耦合可能會很脆弱,正如我上面所說的那樣。

我想引起您注意的最后一件事是“3 行”要求。一般來說,一起檢查 3 條消息并不容易,通常人們只處理 1 行日志(搜索、計數、grep 等等),而不是同時處理 3 行。我提出這個問題,因為也許它可以指出它也可以將請求日志記錄和審計應用程序業務事件的要求分開。在這種情況下,也許可以使用一種技術(過濾器、tomcat 閥等)記錄請求,而審計本身可以使用其他技術甚至技術來完成。

如果您必須使用現有的解決方案,一種有趣的方法可能是將日志記錄重構為某些 AOP 方面/過濾器或其他一些眾所周知的點,以便所有控制器都不必處理您描述的代碼


查看完整回答
反對 回復 2023-06-08
  • 1 回答
  • 0 關注
  • 149 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號