??? 這樣,對(duì)于程序運(yùn)行的控制就不用每次都跑到機(jī)器上去看日志文件這么麻煩了,我們需要的只是,開開Foxmail,用用鼠標(biāo),就可以知道,程序到底運(yùn)行的怎么樣了。
???
??? 使用log4j-1.2.15
?????????????? 之前用的是 log4j-1.2.8 ,照理說(shuō),它們之間的版本號(hào)的區(qū)別夠小,應(yīng)該沒有什么區(qū)別,但是事實(shí)卻讓我丈二摸不著頭腦。
?????????????發(fā)送郵件的一個(gè)重要的類是SMTPAppender。
???????????? 在1.2.8的版本中,SMTPAppender沒有smtpPassword 和smtpUsername 屬性。這兩個(gè)屬性分別是登錄smtp服務(wù)器用的用戶名和密碼。筆者到現(xiàn)在也沒有想明白,在通常的情況下怎樣才可以不登錄smtp服務(wù)器就可以發(fā)送郵件了。 有知道的朋友,就留個(gè)言吧,先謝過(guò)啦。
????????????? 由于不能解決上面的那個(gè)問(wèn)題,我就只好使用1.2.15這個(gè)版本啦。
- ???log4j.properties文件
???????????
- 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??
???????????這個(gè)文件配好以后,恭喜你,現(xiàn)在log4j的郵件功能,你就可以體會(huì)了。
- ? SMTP的級(jí)別默認(rèn)是ERROR級(jí)別的,怎么辦
???????????? 默認(rèn)的級(jí)別是ERROR級(jí)別的,那就是說(shuō),只有程序出錯(cuò)了,你才可以收到郵件,很顯然,這還不能滿足我們?nèi)粘9芾淼囊?。我們需要自定義的級(jí)別。
??????????? 為此,筆者繼承了TriggeringEventEvaluator類,覆蓋里面的一個(gè)方面,如下所示
- @Override??
- ????public?boolean?isTriggeringEvent(LoggingEvent?arg0)?{??
- ????????return?arg0.getLevel().isGreaterOrEqual(Level.INFO);??
- ????}??
?
- ?? 每遇到一個(gè)觸發(fā)事件就發(fā)一封郵件!
??????????? SMTPAppender 實(shí)現(xiàn)是,每當(dāng)isTriggeringEvent()這個(gè)方法返回true的時(shí)候,它都會(huì)發(fā)送郵件。這樣的話,一個(gè)程序執(zhí)行下來(lái),每個(gè)有能力觸發(fā)的事件都會(huì)形成一封郵件。這顯然不是我們希望看到的場(chǎng)面。
??????????? 筆者繼承了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();??
- ????????????}??
- ??
- ????????}??
- ????}??
????????? 這樣的話,當(dāng)事件的個(gè)數(shù)達(dá)到bufferSize的一半的時(shí)候就會(huì)發(fā)一封郵件了。
????????? 但是另外一個(gè)問(wèn)題也隨之產(chǎn)生了,當(dāng)程序結(jié)束時(shí),還在緩沖里面的事件是不會(huì)被發(fā)送出來(lái)的。因?yàn)槭录?shù)往往沒有bufferSize的一半。
?????????
- public???*****SMTPAppender()?{??
- ????????Runtime.getRuntime().addShutdownHook(new?Thread()?{??
- ??
- ????????????@Override??
- ????????????public?void?run()?{??
- ????????????????if?(cb.length()?>?0)?{??
- ????????????????????sendBuffer();??
- ????????????????}??
- ??
- ????????????}??
- ??
- ????????});??
- ????}??
?
???????? 筆者在構(gòu)造函數(shù)中,添加了一個(gè)程序結(jié)束時(shí)運(yùn)行的線程,來(lái)處理這個(gè)問(wèn)題。
- ? 設(shè)置Html格式的輸出
??????????? 按照剛剛筆者給出的配置文件,所產(chǎn)生的郵件的格式是純文本的。其實(shí)log4j有網(wǎng)頁(yè)格式的輸出的。
???????????
- log4j.appender.MAIL.layout=org.apache.log4j.HTMLLayout??
?
????????? 這樣的話,郵件就好看很多啦。
- ? 解決郵件中的中文亂碼問(wèn)題
??????????? 最后,你會(huì)發(fā)現(xiàn)中文是亂碼的,而且HTMLLayout沒有提供編碼方式的屬性設(shè)置,哎,又是一陣無(wú)語(yǔ)中。
?????????? 得,筆者也就只好再寫一個(gè)類,繼承HTMLLayout,覆蓋getContentType方法
??????????
- @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?