1. 程式人生 > >為什麽要打印日誌?

為什麽要打印日誌?

企業級應用 又是 幫助 正常 數據結構 審核 sms 輸入輸出 acl

【User Story2.0】

1.使用應用程序是客戶,如果程序出了問題,一般客戶能提供精確步驟就阿彌陀佛了。

如果我們僅僅使用調試器斷點機制,該問題沒有重現,會讓我們以為已經解決了,但其實問題藏的深,可能是多線程有關呢(因為斷點讓執行速度變慢了)。

所以【成功地調試程序、監控和錯誤報告地關鍵是【日誌】】

2.K&R的K和Rob Pike總結 一、 認真思考添加輸出語句+在關鍵位置代碼自檢 更快於 僅僅通過調試器獲得棧或者就1個變量值(復雜數據結構和控制流細節會丟失)

             .二、瀏覽可疑位置【輸出】 更省時於 單擊跳過語句查看

             .三、輸出可以保留在程序中 更好於 等下要手動去掉調試。

總結:我們無法用調試器監控 客戶在生產環境下的應用程序,所以計劃在不使用調試器解決問題的思路是合乎情理的。

話外音:System.err System.out 缺少粒度 會妨礙應用程序的性能 ,所以我們需要的是可以配置顯示多或少日誌信息...

【在日誌記錄內容】

1.當系統崩潰會阻止日誌機制工作,因此JVM內建了工具,Oracle和OpenJDK 的JVM添加-XX:+HeapDumpOnOutOfMemoryError在JVM內存益處時生成堆轉儲。

2.用日誌記錄關於錯誤【所有信息】(類型、消息、棧跟蹤以及最後一次程序在幹嘛),對用戶不能暴露可能危害系統的信息(文件路徑、SQL查詢)

3.雖然【警告】可以引起人註意,表示應用程序潛在的問題。

4.【重要】事件,幫助我們了解系統是否正常,如實體創建、組件啟動、用戶登錄成功、任務執行成功。

5.最困難的調試場景中,需要打印出進入方法或者退出方法時間,以及每個方法的參數值和返回值。高負載應用程序中,執行循環要打印出叠代數據。

【日誌寫入方式】

1.Console

2.XML日誌比較臃腫、JSON日誌可讀性稍差一點、在Linux中 syslog是一種所有進程可以寫入的設備。

滾動文件可以應用在上述的模式,周期性(時間或文件大小)改變日誌文件,比如Tomcat每天都會創建新的日誌文件。

3.套接字 專門日誌服務器

4.SMTP和SMS 被用於通知系統管理員要立即解決的問題。

5.數據庫 高效且事務安全、易於查詢和過濾、審核數據(法律)也不怕,缺點是數據寫入索引表引起網絡棧開銷,寫入速度慢,限制數據庫大小(嘗試關閉代價是更耗時不利於過濾日誌)

推薦NoSQL,存儲數百GB甚至TB仍然保持良好的性能。比如MongoDB以BSON二進制存儲JSON,進一步壓縮了數據,但犧牲的是讀的性能所以過濾非常慢。

(缺點MongoDB不是ACID兼容的,需要我們構造正確的文檔結構)

【日誌的級別和分類】

java.utl.logging.Level定義的常量

技術分享圖片

技術分享圖片

Apache HTTPD定義的日誌界別 emerg、alert、crit、error、warn、notice、info、debug、trace1~trace8

【選擇日誌框架】

場景:現有數千個類都使用了日誌的企業級應用程序,要從syslog輸出改成數據庫日誌輸出,潛在問題是日誌API被耦合在具體實現上,如果不修改所有日誌代碼就無法替換。

解決:編寫簡單的日誌API隱藏底層框架,然後在更換框架時只需要修改API幾個類,其他程序可以繼續使用API記錄日誌。

java.util.logging已經幫我們將日誌API和實現分離,在收到請求時,java.utl.logging.LogManager類負責創建和返回Logger實例,我們可以擴展LogManager。

標準實現具有可以寫入文件、流、套接字、console、內存處理器,缺點是不適合Web應用程序,因為它從系統屬性加載配置而不是Classpath。

=>【選擇框架的原因】不能從Classpath加載配置的話,部署到同一個容器的兩個web應用程序不可以有不同日誌配置,這樣就不好移植。

=>【性能】無論開發應用程序哪個部分,向文件、Socket、數據庫、電子郵件,這些任務會耗費時間在阻塞上等待輸入輸出完成,又是靠操作系統控制進而無法通過軟件加速這一過程。

【典型的框架】CommonsLogging和SLF4J 通常Scope=Compile,而它們的實現Scope=runtime,這樣避免了應用程序直接使用底層實現。

SLF4J的LoggerFactory.getLogger方法將返回Logger...

【Log4j 2】最重要的指標 關閉日誌性能。

和Logback相比,性能大致相同,Log4j 2擅長在於日誌過濾器。

直接使用Log4j 2 API而不用SLF4J的原因,因為前者更完整,特性豐富。

為什麽要打印日誌?