您和您所在的開發團隊都是怎麼列印日誌的?又是怎麼使用日誌的?

日誌是確定服務狀態,記錄業務信息,乃至於排查錯誤的依據;

但是講開發的書籍、乃至講架構的設計的書籍似乎也很少提到如何設計一個日誌系統;

但是在實際開發過程中又非常重要,我不知道這個在好的技術團隊是如何設計的?可否結合您的業務情況講講您和您所在的團隊是如何列印日誌的,謝謝。


2017-02-03 11:15:53

圖中的Log系統整套開源,沒有做很細緻的跨平台工作,不過頂層介面設計已經預留了足夠的靈活性和可擴展性,可以輕鬆實現跨平台。

tishion/sLogger

————————————————————————————

答一個。

首先撇開三方庫中提供的一些log信息不說,一條log最好能包含以下信息:

級別,時間,tickcount,進程id,線程id,filter,Log正文內容。

—————————————————————————————

明天用電腦回答。

——————————不要怕!我來了!———————————

好 我繼續說按照從LOG內容來進行設計時候需要考慮的東西。除了上面的幾個信息外,在Debug版本的程序中還可以添加每條log所在的函數,源碼文件路徑,行號等這些信息。下面詳細說一下每個field。

  1. 級別:這個可以參照大多數的三方庫裡面的做法,分為INFO,WARNING, ERROR,FATAL等等級別。不過我們目前從方便使用的角度考慮只分了DEBUG和RELEASE兩個級別,省的開發人員去寫個LOG還要考慮這個LOG到底屬於什麼類型。簡單來說,一般LOG都用Debug,而在出錯或者異常分支裡面打Releas LOG,避免外發版本出了問題招不到LOG。
  2. 時間:這個就很簡單了,一般精確到MS就可以了,主要是用於查看程序運行的大致時間信息。
  3. TickCount:這個跟時間一起用於解決發現一些時序相關問題。
  4. 進程ID:關於進程ID這個信息需不需要,取決於你的LOG系統存儲實際方式了,如果你的LOG數據是每個進程又自己獨立的存儲文件,那就不需要。如果是多個進程共享同一個存儲,那就需要加上這一項。另一點即使你的LOG存儲系統是進程獨立的,為了支持動態查看LOG信息,最好還是加上這一項。
  5. 線程ID:線程ID相當重要,在解決多線程問題的時候,這一項信息是必不可少的。
  6. Filter:主要用於查找某一類LOG時候方便,這個Filter是開發人員在開發過程中自己定義的,比如開發者xiaowang寫了個模塊,他為了能在LOG中很容的找到這一類LOG信息,於是就給這些LOG設置了filter為「xiaowang」……
  7. LOG正文內容:這個就沒太多說的,主要就是LOG信息了

先發。

上面是從LOG內容來說的,關於LOG系統的設計當然還有系統架構方面的一些問題值得關注。

首先,最大的問題就是LOG系統的IO設計。一般普通的的LOG系統就是直接寫磁碟文件,既然寫磁碟文件就牽扯到磁碟IO,而磁碟IO跟內存讀寫有一個數量級的性能差別,所以這就帶來一個選擇模型的問題:LOG寫磁碟的IO的時候是同步還是非同步?

同步:就是最簡單的做法了,直接向文件寫LOG,寫不完不返回,就block在輸出LOG的語句中,這個時候可能需要考慮的另一個問題就是對多線程(進程,多進程共享一個LOG數據存儲文件)的支持,無非是加鎖來做了(Windows下可以用內核同步對象實現)。這中做法的缺點顯而易見,對程序本身性能損耗太大,而且也打破了進程隔離的原則,使用同一個LOG系統的多個進程會相互影響。所以這種做法一般都是放在規模比較小的程序中,並且這種方法一般不會採用多進程共享LOG數據存儲方式。這種方法唯一的優點是,不用過多考慮在某些情況下出現LOG數據丟失(當然跟程序Flush的時機還是有關的)。

非同步:這裡說的非同步其實還是要等LOG語句執行完返回的,但是這個LOG是輸出到內存緩存中,然後由另外一個專用工作線程去負責把緩存中的數據轉儲到磁碟文件。基本設計模型就是生產者消費者模型了,很好理解。當然如果支持多線程(進程)的話還是不可避免的要考慮同步問題,對緩存的所有操作必須串列化。這種設計的優點是對程序本身性能影響最小,不因為打LOG而顯著影響程序運行速度。缺點是在某些異常情況下,可能丟失大量LOG數據,比如緩存中存在大量未處理數據,可是程序Crash了,如果沒有做足異常處理,那這些數據可能就丟失了。如果在Windows下可以在UnhandledExceptionHandler裡面把緩存中的數據寫入磁碟數據,減小損失,但是如果程序Crash的時候導致了緩存corruption,直接把緩存數據都破壞了,那就無力回天了。

另外一點:作為一個專業的LOG系統,必須具有實時動態查看LOG的能力,所以還需要配備一個專門的Log Viewer,它的主要功能應該具備以下:

查看目標可選:用戶可以選擇需要查看的某個進程的LOG輸出

LOG信息可篩選:進程,線程,級別,Filter,正文關鍵字等等,反正越多支持越好。

實時輸出:目標程序執行了LOG輸出,這個LOG數據不會經過IO展示在Log viewer裡面,而是通過IPC,Message等高效率的數據傳輸手段。

盡量減少對目標程序的影響: 同上。

總之一個動態Log viewer的用處對調試程序中的邏輯錯誤是非常有幫助的。

這些經驗都是在上一家公司學習到的,講的不是多麼深入,只是從整體設計上來探討一下,請各位多指教。


謝邀!

先作簡略回答,以後會詳細補充。

但是講開發的書籍、乃至講架構的設計的書籍似乎也很少提到如何設計一個日誌系統

是的,同感。細講日誌方面的文獻不多。大部分圖書喜歡用 toy examples,而略掉/不展示實際的(看似累贅的)Logging/Tracing 代碼,可能是為了簡潔、節省版面吧。

為什麼日誌如此重要?

但是在實際開發過程中又非常重要,我不知道這個在好的技術團隊是如何設計的?

日誌對於提升複雜軟體開發、調試、運維的效率和質量,確實非常關鍵和重要!可惜,很多初中級碼農並沒有熟練地掌握這項技能,重視程度也不夠。原因可能就是你說的,很多教材上沒有,學校的老師也不教。

關於日誌的基礎內容和要點 @tishion 好像都提到了,這裡我補充一點不同和新的東西。

集成的測試與調試(掐蟲)工具

Webtester(簡稱 wt)是我這幾年正在開發的一個免費(即將開源)、集成的敏捷測試與調試工具。其中一個特點是集成了 Testing 與 Debugging,在同一個 Web 窗口裡你既可以看到 test cases(測例)的運行情況,也可以很方便地看到用 XHTML 呈現的系統運行日誌。

Web 應用系統的日誌當然最好用 HTML/XHTML 來呈現。Web 日誌比傳統的日誌系統、工具有許多優勢,數據表現的手段和形式也更加豐富。

wt 中的 Server 端日誌(Logger)子系統主要是用來掐蟲(Debug)的,所以也叫 Tracer(跟蹤器),主要由 XTrace、TraceWriter、TraceMessage、TraceFilter 和 ITraceManager 等類和介面組成。

如何生成日誌

(以下為 http://VB.NET 代碼)

用 XTrace 類的系列靜態函數 show() 生成日誌是很簡單、很靈活的。

例如,在類 XPage 的方法 forwardToView 中顯示某個字元串的內容:

XTrace.show("XPage.forwardToView", "_rawUrl", _rawUrl)

還可以同時顯示任意多個字元串的值:

XTrace.show("XPage.Render", "SName", getSName(), "mode", mode)

在 try-catch 的 catch 語句中輸出異常 ex 的信息:

XTrace.show("XPage.Render", ex)

輸出一條告警消息:

XTrace.warn("ConverterBase.makeChanges", "Invalid input, return.")

顯示當前是哪個函數/方法執行結束:

XTrace.showEnd("ConverterBase.makeChanges")

為什麼不在以上列印函數中設置日誌消息的級別?

傳統的日誌消息級別(level)包括 info、warning、error、fatal、debug 等等。wt 則採用了另外一種更簡明的處理方式。

。。。


不邀自來

打日誌真的是見功力的地方,簡單來說,打日誌主要講究少、准、狠

啥是少?我們查過線上問題的可能都經歷過,把日誌級別打到最低,終於把現象重現了,去查日誌發現霹靂啪噠一堆日誌,有的沒的什麼都說,你的app就像個話嘮:我開始吃飯啦,我張開了嘴,一勺食物已經進來啦,我動了一下牙,我卷了兩下舌頭,我咽下去食物啦... 雖然說的這麼詳細但並沒什麼卵用,最關鍵的為啥我少咬了一口還是一點線索都沒有,所以哪些信息是debug信息,哪些不是,什麼需要打,什麼不需要打,這個是要過腦考慮的。

啥是准?這個要真真切切踩個幾年坑才能練就的,怎麼說呢,在linux開發機上開發調試,我們最常用的就是插樁法,插幾條log,run一下,插幾條log,run一下,插的準不準,人和人還真不一樣。

啥是狠?我並沒說你要喪心病狂把磁碟寫爆^_^,狠是用來湊數的,簡單說就是該打的地方一定要打,不該打的地方一定別打。

啊哈哈哈,log大法三字真經,大家悟透了嗎


時間,地點, 參數。


日誌也是需要設計。

最近在做一些類似於運營和查bug的工作。問題定位起來很是痛苦。因為日誌中沒有區分人的流程。

一個用戶的操作流程,在後端服務中,一系列流程都需要帶上個人信息。不然很難定位哪一步出現了問題。

之前也剛好在網易URS實習過,主要是負責日誌,用hadoop和hive分析,寫寫腳本。

如果是考慮到日誌分析。可以根據業務來分析。根據業務有針對性的設計日誌的格式和元素。

比如登錄和註冊日誌,用戶的主要操作日誌。

統計比如活躍用戶,留存率等。還有登錄註冊反垃圾的一些數據可以針對性的設計日誌。

可以根據日誌分析,優化產品的流程。ps:比如遊戲註冊流程分析,看哪一步是流失的最多,可以做成漏斗圖。我貌似說太多了。

ps:稍稍說一下,遊戲註冊的時候很多垃圾流量來自於阿里雲,你懂的。


看需求。

如果你要的只是故障信息,那麼其他什麼級別、進程ID都是多餘的。


我想請答主去讀讀AOP(面向方面編程),你就知道像日誌和許可權管理這類跨業務的事情是如何來實現最優。

因為AOP解釋了橫切關注點和代碼入侵的問題,仔細讀後你就明白日誌該如何設計了。


突然覺得這個與高中作文類似,主要是:人物,地點,時間,事件


講個反例,路由器設備上的一條日誌,每幾秒打一條,把設備的cf卡寫壞掉


推薦閱讀:

TAG:軟體開發 | 軟體設計 | 日誌 |