Log4J发日志邮件给多个接收者及标题、正文乱码问题
转自:http://www.blogjava.net/henry1451/articles/205358.html
前言:
以前开发的系统没有单独的日志管理,所有的日志统一输出到tomcat后台一个文件里,不几天就是好几G,现在要整体增加一个Log4J管理日志的功能,其实这方面的资料网上多的是。发邮件的配置说明也有,但是具体怎么发,乱码问题怎么解决那就比较少了。
解析:
利用javamail发送邮件,你需要导入包mail.jar和activation.jar这两个包 ,否则是没法发邮件的。
1.问题:
这里会出现中文乱码问题,主要有两方面的乱码:一是,标题乱码;二是,正文乱码。
2.具体说明这两种乱码的解决方案:
a. 标题乱码:
Log4J日志邮件的标题在配置文件log4j.properties里设定,如下:
log4j.appender.MAIL=org.apache.log4j.net.SMTPAppender log4j.appender.MAIL.Threshold=FATAL log4j.appender.MAIL.BufferSize=10 log4j.appender.MAIL.From=ab@163.com log4j.appender.MAIL.SMTPHost=smtp@163.com log4j.appender.MAIL.Subject= Log4J提醒您:系统发生了严重错误 log4j.appender.MAIL.To=ac@163.com,ae@163.com log4j.appender.MAIL.layout=com.sun.DefineLayOut log4j.appender.MAIL.layout.LocationInfo=true
注意:配置文件里绿色行显示的就是发给两个接收者ac和ae,发送者是ab;灰色的行就是标题。
log4J配置文件默认的读取方式是ISO-88591,遇到中文会出现乱码,我们可以把这个配置文件log4j.properties用jdk的工具native2ascii转换一下编码方式。
命令:
native2asii log4j.properties log4jxx.properties
把这个log4jxx.properties改名为log4j.properties取代原来的log4j.properties就ok了(这里我是把这些在txt文件里转好了只把标题粘过来就行了)。
在线转换工具:http://www.00bug.com/native2ascii.html
灰色行重新编码后是:
log4j.appender.MAIL.Subject=Log4J/u63d0/u9192/u60a8/uff1a/u7cfb/u7edf/u53d1/u751f/u4e86/u4e25/u91cd/u9519/u8bef
b.正文乱码
正文乱码,解决也比较简单。阅读Log4J的源码类SMTPAppender,我们可以发现sendBuffer()方法中有这样一句:
part.setContent(sbuf.toString(), layout.getContentType());
继续追踪发现layout就是配置文件里的layout属性对应的布局模式。但是这些布局模式都是继承自Layout,而contentType是只可通过getContentType方法取得,不能修改。所有的布局模式getContentType方法返回的都是"text/plain";为处理中文乱码,我们可以写一个布局模式。
如果你要使用HTMLLayout,我们就写一个HTMLLayout的子类,覆盖HTMLLayout的getContentType方法即可。
假如我要用org.apache.log4j.HTMLLayout。我们就可以写一个DefineLayOut 类,代码如下:
package com.sun; import org.apache.log4j.HTMLLayout; public class DefineLayOut extends HTMLLayout{ public String getContentType() { return "text/html;charset=GBK"; } } 对应的配置文件设置如蓝色行所示。
如果是Layout,可以这样写:
package dao; import org.apache.log4j.Layout; import org.apache.log4j.SimpleLayout; import org.apache.log4j.spi.LoggingEvent; public class MailEvaluator extends Layout{ StringBuffer sbuf; @Override public String getContentType() { return "text/html;charset=GBK"; } public MailEvaluator() { sbuf = new StringBuffer(128); } @Override public String format(LoggingEvent event) { sbuf.setLength(0); sbuf.append("错误等级:"+event.getLevel().toString()+"==="); sbuf.append("错误原因:"+event.getMessage().toString()+"==="); sbuf.append("错误所在类"+event.getLocationInformation().getClassName()+"==="); sbuf.append("错误方法所在:"+event.getLocationInformation().getMethodName()+"==="); sbuf.append("错误行:"+event.getLocationInformation().getLineNumber()); return sbuf.toString(); } @Override public boolean ignoresThrowable() { // TODO Auto-generated method stub return false; } public void activateOptions() { // TODO Auto-generated method stub } }
注意:如果是Layout的话在log4j.properties文件可以是这样的:
## MAIL log4j.appender.MAIL=org.apache.log4j.net.SMTPAppender # 记录error等级得错误 log4j.appender.MAIL.Threshold=ERROR #当日志到达126k时,发送邮件 log4j.appender.MAIL.BufferSize=126 #邮件服务器 log4j.appender.MAIL.SMTPHost=smtp.163.com #是否打印调试信息 log4j.appender.MAIL.SMTPDebug=true #邮件主题 log4j.appender.MAIL.Subject=Log4J ErrorMessage #邮箱登陆账号 log4j.appender.MAIL.SMTPUsername=***@163.com #邮箱登陆密码 log4j.appender.MAIL.SMTPPassword=*** #邮件发送方 log4j.appender.MAIL.From=***@163.com #邮件接收方 log4j.appender.MAIL.To=***@163.com #日志显示格式 log4j.appender.MAIL.layout.ConversionPattern==%d{yyyy-MM-dd HH:mm:ss} - %c -%-4r [%t] %-5p %c %x - %m %l%n