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
posted @ 2013-01-19 20:05  horizon~~~  阅读(637)  评论(0编辑  收藏  举报