為什么說這么一個(gè)標(biāo)題,其實(shí)還是有點(diǎn)故事的,其實(shí)說是故事還不如說是事故,慶幸的是還好沒有造成什么大的問題,既然說刪了兩臺(tái)服務(wù)器,上個(gè)月確實(shí)是操作刪了兩臺(tái)服務(wù)器。由于測試環(huán)境有問題,客戶就一直讓我們在正式環(huán)境上開發(fā),所以有時(shí)候就會(huì)造成一些問題,總之很刺激,也很危險(xiǎn)。
簡單說一下是怎么個(gè)情況吧,上個(gè)月客戶讓我測一個(gè)接口,但是那個(gè)接口只能在線上測,所以我就點(diǎn)了一個(gè)釋放資源,那個(gè)資源里面就是下發(fā)下去的兩臺(tái)服務(wù)器,由于沒有很好的日志記錄所以當(dāng)時(shí)也不知道到底是誰釋放的,當(dāng)然了,不是我死不承認(rèn),而是我也不知道,然后他們查出來我的電腦IP,直接找過來了,可嚇壞我了,還好人家那兩臺(tái)服務(wù)器沒有投入使用,讓我以后操作小心一點(diǎn)。是不是很刺激。
看了這個(gè)問題,其實(shí)我想說一個(gè)問題,就是我們的項(xiàng)目當(dāng)時(shí)沒有很好的日志管理,以至于誰刪了服務(wù)器都不知道,還要去追查一周才能定位到是誰干的,很慢,那么如果有良好的日志記錄,誰干了什么翻翻日志,是不是就可以很清楚的知道是誰操作的,所以我們今天來聊聊日志。
一、日志級(jí)別
在了解日志之前我們首先要知道有哪些日志級(jí)別,開發(fā)中我們使用哪個(gè)級(jí)別,正式的線上環(huán)境我們又使用哪個(gè)級(jí)別。
off ?最高等級(jí),用于關(guān)閉所有的日志記錄;
fatal ?具有嚴(yán)重的錯(cuò)誤時(shí)間,可能導(dǎo)致程序退出;
error ?可能存在錯(cuò)誤時(shí)間的發(fā)生,但是不會(huì)影響程序的運(yùn)行;
warn ?存在潛在的錯(cuò)誤;
info ?記錄程序運(yùn)行的過程;
debug ?會(huì)記錄所有的日志信息,比info打印的東西更為全面,一般做調(diào)試非常好用;
all ?等級(jí)最低,用于打開所有的日志記錄;
這就是我們?nèi)罩镜募?jí)別,分別從高到低,日志級(jí)別越高,記錄的日志信息就越詳細(xì),那么在實(shí)際的開發(fā)中,我們一般使用debug級(jí)別, 因?yàn)槲覀円春芏嗟娜罩拘畔ⅲ驗(yàn)榭赡艽嬖谝恍〇|西,我們要通過日志去進(jìn)行查看,那么在線上的話,我們就一般使用error級(jí)別,因?yàn)槲覀冎恍枰ビ涗浺恍╁e(cuò)誤的東西,一些其他沒用的信息沒必要記錄下來,記錄下來會(huì)比較影響我們的系統(tǒng)的性能。
二、簡單的配置
接下來我們介紹一下,如果配置我們的log4j日志信息,我們輸出的那些東西,究竟是如何進(jìn)行配置的。
首先我們說一下文件追加器:
org.apache.log4j.ConsoleAppender?(控制臺(tái));
org.apache.log4j.FileAppender?(文件);
org.apache.log4j.DailyRollingFileAppender?(每天產(chǎn)生一個(gè)日志文件);
其實(shí)文件追加器不止這3種,但是我們這里只說常用的集中,通過追加器我們就可以把日志輸出在控制臺(tái)上,但是輸出在控制臺(tái)上當(dāng)我們清掉控制臺(tái)后,日志就不見了,所以我們可以通過配置文件追加器把日志寫進(jìn)文件中,方便以后的查閱。
日志如何輸出到文件:
上面已經(jīng)寫過了,這里我就寫一個(gè)實(shí)例;
log4j.appender.I.File = logs/info/info_
這是我項(xiàng)目中配置的,那么這個(gè)日志的輸出位置就是在我項(xiàng)目下面的logs文件夾下面有個(gè)info文件夾,就在info_這個(gè)文件中記錄著。
還有一個(gè)輸出控制臺(tái)的配置,通過這個(gè)配置,我們就可以把日志輸出到控制臺(tái)上
log4j.appender.C.Target = System.out
再就是布局方式,其實(shí)有好集中,但是在開發(fā)中我們常規(guī)的是使用下面這種
log4j.appender.C.layout = org.apache.log4j.PatternLayout
這個(gè)配置的意思就是,我們的日志是追加到原有的日志文件中去的,如果不設(shè)置為true,那么每次產(chǎn)生的日志文件都會(huì)覆蓋原來的日志文件
log4g.appender.I.Append =?true
其實(shí)所有的日志記錄在一個(gè)文件中也不是一個(gè)特別好的辦法,如果日志很多,找起來特別麻煩,也很影響系統(tǒng)的性能,所以我們可以通過配置,讓他一天生成一個(gè)日志文件
log4j.appender.I.DatePattern=yyyy-MM-dd'.log '
這個(gè)其實(shí)就是你打印在控制臺(tái)和記錄在文件中的日志格式
log4j.appender.I.layout.ConversionPattern = [%-5p] %d{yyyy-MM-dd-HH-mm}?method:%l\%n%m%n
看個(gè)例子:
這個(gè)是控制臺(tái)打印的信息

這個(gè)是日志文件記錄的信息

這樣你就可以比較清晰的看到我們的日志信息是什么級(jí)別的日志,什么時(shí)間,哪個(gè)類,多少行,你還可以配置你想要的日志格式,我把一些參數(shù)放在下面。
log4j.appender.C.layout.ConversionPattern = %d{yyyy-MM-dd-HH-mm} [%t] [%c] [%p] - %m%n
%m ? 輸出代碼中指定的消息
%p ? 輸出優(yōu)先級(jí),即DEBUG,INFO,WARN,ERROR,F(xiàn)ATAL
%r ? 輸出自應(yīng)用啟動(dòng)到輸出該log信息耗費(fèi)的毫秒數(shù)
%c ? 輸出所屬的類目,通常就是所在類的全名
%t ? 輸出產(chǎn)生該日志事件的線程名
%n ? 輸出一個(gè)回車換行符,Windows平臺(tái)為“/r/n”,Unix平臺(tái)為“/n”
%d ? 輸出日志時(shí)間點(diǎn)的日期或時(shí)間。默認(rèn)格式為ISO8601,也可以在其后指定格式。比如:%d{yyy MMM dd HH:mm:ss , SSS},輸出類似:2002年10月18日 22:10:28, 921
%l ? 輸出日志事件的發(fā)生位置,包括類目名、發(fā)生的線程,以及在代碼中的行數(shù)
還有一點(diǎn)就是下面這個(gè)配置,上面的有些C I E D可能大家不知道是什么意思,其實(shí)它就是一個(gè)變量,變量前面的debug就是我們?nèi)罩据敵龅募?jí)別。
log4j.rootLogger =?debug,C,I,E,D
所謂變量其實(shí)就是通過它配置我們的日志信息,下面分別定義了兩個(gè)變量I和E,下面有個(gè)log4j.append.E.Threshold = error這樣一個(gè)配置,其實(shí)就是通過E這個(gè)變量去定義E,這個(gè)變量記錄的是error級(jí)別的日志,那么有關(guān)error的信息,那么都會(huì)寫進(jìn)這個(gè)對應(yīng)的文件中

最后把我寫的日志文件信息完整版放在最后,歡迎大家參考交流:
# C 變量
log4j.rootLogger = debug,C,I,E,D
log4j.appender.C = org.apache.log4j.ConsoleAppender
# 日志輸出位置,也可以指定為文件
log4j.appender.C.Target = System.out?
# 布局方式,一般選擇自由方式布局
log4j.appender.C.layout = org.apache.log4j.PatternLayout
# 日志輸出格式
log4j.appender.C.layout.ConversionPattern = [%-5p] %d{yyyy-MM-dd-HH-mm}?method:%l\%n%m%n
log4j.appender.I = org.apache.log4j.DailyRollingFileAppender
log4j.appender.I.DatePattern=yyyy-MM-dd-HH'.log '
log4j.appender.I.File = logs/info/info_
log4g.appender.I.Append =?true
log4j.appender.I.Threshold = info
log4j.appender.I.layout = org.apache.log4j.PatternLayout
log4j.appender.I.layout.ConversionPattern = [%-5p] %d{yyyy-MM-dd-HH-mm}?method:%l\%n%m%n
log4j.appender.E = org.apache.log4j.DailyRollingFileAppender
log4j.appender.E.DatePattern=yyyy-MM-dd-HH'.log '
log4j.appender.E.File = logs/error/error_
log4g.appender.E.Append =?true
log4j.appender.E.Threshold = error
log4j.appender.E.layout = org.apache.log4j.PatternLayout
log4j.appender.E.layout.ConversionPattern = [%-5p] %d{yyyy-MM-dd-HH-mm}?method:%l\%n%m%n
log4j.appender.D = org.apache.log4j.DailyRollingFileAppender
log4j.appender.D.DatePattern=yyyy-MM-dd-HH'.log '
log4j.appender.D.File = logs/debug/debug_
log4g.appender.D.Append =?true
log4j.appender.D.Threshold = debug
log4j.appender.D.layout = org.apache.log4j.PatternLayout
log4j.appender.D.layout.ConversionPattern = [%-5p] %d{yyyy-MM-dd-HH-mm}?method:%l\%n%m%n