在程序中寫日志是一件非常重要,但是很容易被開發人員忽視的地方。寫好程序的日志可以幫助我們大大減輕后期維護壓力。
在實際的工作中,開發人員往往迫於的巨大時間壓力,而寫日志又是一個非常繁瑣的事情,往往沒有引起足夠的重視。
如果我們的開發人員在一開始就養成一個良好的習慣將非常有幫助。並且在實際的工作中也應當為寫日志預留足夠的時間。
我們為什要寫日志呢?
一般來講,我們在程序中記錄日志出自下面幾個方面的需求。
* 記錄用戶操作的審計日志,甚至有的時候就是監管部門的要求。
* 快速定位問題的根源,
* 追蹤程序執行的過程
* 追蹤數據的變化
* 數據統計和性能分析
* 采集運行環境數據
多數情況下,在我們的程序上線(Go Live)之后,一旦發生異常,我們要做的第一件事就是要弄清楚當時倒底發生了什么,
例如:用戶當時做了什么操作,環境有無異常,數據有什么變化,是不是反復發生,等等。
然后再進一步的確定大致是哪個方面的問題。 確定是程序的問題之后再交由開發人員去重現,研究,提出解決方案。
這個時候日志就給我們提供了第一手的資料。
在生產環境和測試環境分開的情況下,在開發人員拿到日志的時候離問題發生已經過去很長時間。
所以清晰詳盡的日志信息對於我們迅速定位問題根源就顯得非常重要。它既是我們找尋原因的地圖,也是最直接的證據。
對於稍大一點的系統來講,做維護的人員和開發者通常都不是同一組人,這個過程所花費的時間和人力要遠遠超過開發本身數倍甚至數十倍。
都有哪些人要看日志?
正如前面所講,產品支持,運維人員,開發人員,測試人員都需要查看日志。當然自己也是要看的。
寫日志有些什么要求?
上面需求對我們在程序中記錄日志提出了一定的要求:
* 日志的可讀性
日志是給人讀的,不僅僅是讓自己明白同時也要讓沒有接觸過我們源代碼的其他程序員也能夠一目了然。
我常常見到很多同事在日志中打印特殊的標識符號,例如 “+++++++++++”,“--------------”和“==============”,這些符號往往讓人眼花繚亂。他們的本意也僅僅是在自己調試的時候能一眼就發現這是自己的日志。既然如此,把自己名字寫入日志中豈不是更明確?
把日志分類輸出到不同的文件中也有利於我們排除干擾,迅速找到我們需要的信息。
* 日志的性能
無論我們把日志寫到文件還是數據庫,都需要消耗IO資源。適當的控制日志的輸出也有利於提高程序的性能。例如:
盡量避免在在大的循環中打印意義不大的日志內容。
輸出日志之前最好能判斷日志的級別(例如. debug前先調用isDebugEnabled()作出判斷)。
* 占用的磁盤空間
通常,我們都是把日志寫入磁盤上的日志文件中。適當的使用滾動日志並且定時清除舊文件是有好處的。
我見過這樣一個例子,程序運行幾次后就跑不起來了,前幾次都是正常的。怎么都想不明白程序有什么問題,最后才發現居然是日志文件占滿了磁盤空間。
在實際的應用中出現上G的日志文件也往往不少見。要在這樣規模的日志文件中找出對解決問題有用的信息也是一大挑戰。
* 日志的時效性
有的時候我們並不能及時的發現問題。需要追溯之前的日志。所以我們是需要保留一段時間以內的日志便於追溯。
* 日志的級別
通常我們在產品環境中日志的級別都在INFO以上,所以我們必須保證在這樣的情況下程序仍然能夠輸出足夠我們作出判斷的信息。
* 日志的內容
我們在寫日志的時候,需要注意輸出適當的內容。
首先,盡量使用業務相關的描述。我們的程序是實現某種業務的,那么就最好能描述清楚這個時候走到了業務過程的哪一步。
其次,避免在日志中輸出一些敏感信息,例如用戶名和密碼。
以及,要保持編碼的一致。如果不能保證就盡量使用英文而不是中文。這樣當我們拿到日志之后就不會因為看到一堆亂碼而不知所雲了。
怎么樣寫出好的日志來?
其實寫好日志並不難,只要我們能在寫代碼的時候能體會到后面的維護工作的壓力和艱辛,多點關注和理解就一定能做好這件事。