Log4j的郵件功能能夠為我們做這樣的事情----當程序運行完的時候,或者正在運行也是可以的,它將程序的日志通過郵件的方式發到你的郵箱上。
??? 這樣,對于程序運行的控制就不用每次都跑到機器上去看日志文件這么麻煩了,我們需要的只是,開開Foxmail,用用鼠標,就可以知道,程序到底運行的怎么樣了。
???
?????????????? 之前用的是 log4j-1.2.8 ,照理說,它們之間的版本號的區別夠小,應該沒有什么區別,但是事實卻讓我丈二摸不著頭腦。
?????????????發送郵件的一個重要的類是SMTPAppender。
???????????? 在1.2.8的版本中,SMTPAppender沒有smtpPassword 和smtpUsername
屬性。這兩個屬性分別是登錄smtp服務器用的用戶名和密碼。筆者到現在也沒有想明白,在通常的情況下怎樣才可以不登錄smtp服務器就可以發送郵件了。
有知道的朋友,就留個言吧,先謝過啦。
????????????? 由于不能解決上面的那個問題,我就只好使用1.2.15這個版本啦。
???????????
- log4j.appender.MAIL=org.apache.log4j.net.SMTPAppender??
- ??
- log4j.appender.MAIL.BufferSize=10??
- ??
- log4j.appender.MAIL.From=yourname@?domain.com??
- ??
- log4j.appender.MAIL.SMTPHost=mail.domain.com??
- ??
- log4j.appender.MAIL.Subject=Log4J?Message??
- ??
- log4j.appender.MAIL.To=target@domain.com??
- ??
- log4j.appender.MAIL.SMTPUsername=username??
- ??
- log4j.appender.MAIL.SMTPPassword=password??
- ??
- log4j.appender.MAIL.layout=org.apache.log4j.PatternLayout??
- ??
- log4j.appender.MAIL.layout=org.apache.log4j.PatternLayout??
- ??
- log4j.appender.MAIL.layout.ConversionPattern=[framework]?%d?-?%c?-%-4r?[%t]?%-5p?%c?%x?-?%m%n??
log4j.appender.MAIL=org.apache.log4j.net.SMTPAppender
log4j.appender.MAIL.BufferSize=10
log4j.appender.MAIL.From=yourname@ domain.com
log4j.appender.MAIL.SMTPHost=mail.domain.com
log4j.appender.MAIL.Subject=Log4J Message
log4j.appender.MAIL.To=target@domain.com
log4j.appender.MAIL.SMTPUsername=username
log4j.appender.MAIL.SMTPPassword=password
log4j.appender.MAIL.layout=org.apache.log4j.PatternLayout
log4j.appender.MAIL.layout=org.apache.log4j.PatternLayout
log4j.appender.MAIL.layout.ConversionPattern=[framework] %d - %c -%-4r [%t] %-5p %c %x - %m%n
???????????這個文件配好以后,恭喜你,現在log4j的郵件功能,你就可以體會了。
???????????? 默認的級別是ERROR級別的,那就是說,只有程序出錯了,你才可以收到郵件,很顯然,這還不能滿足我們日常管理的要求。我們需要自定義的級別。
??????????? 為此,筆者繼承了TriggeringEventEvaluator類,覆蓋里面的一個方面,如下所示
- @Override??
- ????public?boolean?isTriggeringEvent(LoggingEvent?arg0)?{??
- ????????return?arg0.getLevel().isGreaterOrEqual(Level.INFO);??
- ????}??
@Override
public boolean isTriggeringEvent(LoggingEvent arg0) {
return arg0.getLevel().isGreaterOrEqual(Level.INFO);
}
?
??????????? SMTPAppender 實現是,每當isTriggeringEvent()這個方法返回true的時候,它都會發送郵件。這樣的話,一個程序執行下來,每個有能力觸發的事件都會形成一封郵件。這顯然不是我們希望看到的場面。
??????????? 筆者繼承了SMTPAppender類,重裝了append方法。??????????
- @Override??
- ????public?void?append(LoggingEvent?event)?{??
- ??
- ????????if?(!checkEntryConditions())?{??
- ????????????return;??
- ????????}??
- ??
- ????????event.getThreadName();??
- ????????event.getNDC();??
- ????????event.getMDCCopy();??
- ????????if?(this.getLocationInfo())?{??
- ????????????event.getLocationInformation();??
- ????????}??
- ????????cb.add(event);??
- ????????if?(evaluator.isTriggeringEvent(event))?{??
- ????????????if?(cb.length()?>?this.getBufferSize()?/?2)?{??
- ????????????????sendBuffer();??
- ????????????}??
- ??
- ????????}??
- ????}??
@Override
public void append(LoggingEvent event) {
if (!checkEntryConditions()) {
return;
}
event.getThreadName();
event.getNDC();
event.getMDCCopy();
if (this.getLocationInfo()) {
event.getLocationInformation();
}
cb.add(event);
if (evaluator.isTriggeringEvent(event)) {
if (cb.length() > this.getBufferSize() / 2) {
sendBuffer();
}
}
}
????????? 這樣的話,當事件的個數達到bufferSize的一半的時候就會發一封郵件了。
????????? 但是另外一個問題也隨之產生了,當程序結束時,還在緩沖里面的事件是不會被發送出來的。因為事件數往往沒有bufferSize的一半。
?????????
- public???*****SMTPAppender()?{??
- ????????Runtime.getRuntime().addShutdownHook(new?Thread()?{??
- ??
- ????????????@Override??
- ????????????public?void?run()?{??
- ????????????????if?(cb.length()?>?0)?{??
- ????????????????????sendBuffer();??
- ????????????????}??
- ??
- ????????????}??
- ??
- ????????});??
- ????}??
public *****SMTPAppender() {
Runtime.getRuntime().addShutdownHook(new Thread() {
@Override
public void run() {
if (cb.length() > 0) {
sendBuffer();
}
}
});
}
?
???????? 筆者在構造函數中,添加了一個程序結束時運行的線程,來處理這個問題。
??????????? 按照剛剛筆者給出的配置文件,所產生的郵件的格式是純文本的。其實log4j有網頁格式的輸出的。
???????????
- log4j.appender.MAIL.layout=org.apache.log4j.HTMLLayout??
log4j.appender.MAIL.layout=org.apache.log4j.HTMLLayout
?
????????? 這樣的話,郵件就好看很多啦。
??????????? 最后,你會發現中文是亂碼的,而且HTMLLayout沒有提供編碼方式的屬性設置,哎,又是一陣無語中。
?????????? 得,筆者也就只好再寫一個類,繼承HTMLLayout,覆蓋getContentType方法
??????????
- @Override??
- ????public?String?getContentType()?{??
- ????????return?"text/html;charset=GBK";??
- ??
- ????}??
@Override
public String getContentType() {
return "text/html;charset=GBK";
}
?????????? 添加上述功能之后的配置文件如下所示:
- log4j.appender.MAIL.To=target@domain.com??
- ??
- log4j.appender.MAIL.From=yourname@domain.com??
- ??
- log4j.appender.MAIL.SMTPHost=smtp.domain.com??
- ??
- log4j.appender.MAIL.Subject=?Information??
- ??
- log4j.appender.MAIL.SMTPUsername=username??
- ??
- log4j.appender.MAIL.SMTPPassword=password??
- ??
- log4j.appender.MAIL.EvaluatorClass=com.wole.***.MailEvaluator??
- ??
- log4j.appender.MAIL.layout=com.wole.log4j.net.DefaultLayOut?