zoukankan      html  css  js  c++  java
  • log4j发送邮件乱码

    Log4J发日志邮件给多个接收者及标题、正文乱码问题

    以前开发的系统没有单独的日志管理,所有的日志统一输出到tomcat后台一个文件里,不几天就是好几G,现在要整体增加一个Log4J管理日志的功能,其实这方面的资料网上多的是。发邮件的配置说明也有,但是具体怎么发,乱码问题怎么解决那就比较少了。

           利用javamail发送邮件,你需要导入包mail.jar和activation.jar这两个包 ,否则是没法发邮件的 ,下边配置文件里绿色行显示的就是发给两个接收者ac和ae。

           这里会出现中文乱码问题,主要有两方面的乱码,一是标题乱码;二是正文乱码。下边具体说明这两种乱码的解决方案。 
    一、 标题乱码 
    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


           灰色的行就是标题,log4J配置文件默认的读取方式是ISO-88591,遇到中文会出现乱码,我们可以把这个配置文件log4j.properties用jdk的工具native2asii转换一下编码方式。 
    命令:native2asii log4j.properties log4jxx.properties 
    把这个log4jxx.properties改名为log4j.properties取代原来的log4j.properties就ok了。 
    灰色行重新编码后是: 
    log4j.appender.MAIL.Subject=Log4J/u63d0/u9192/u60a8/uff1a/u7cfb/u7edf/u53d1/u751f/u4e86/u4e25/u91cd/u9519/u8bef 

    二、 正文乱码 
            正文乱码,解决也比较简单。阅读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"; 


    对应的配置文件设置如黄色行所示。

    Commons-logging + Log4j 使用指南(转)

    log4j 发邮件(解决中文乱码)

    Log4j的html输出格式:HTMLLayout 类重写,根据自身需要输出不同列

    附自定义html输出格式代码

    FormatHTMLLayout类
    package com.spike.test;
    
    import java.text.SimpleDateFormat;
    
    import org.apache.log4j.HTMLLayout;
    import org.apache.log4j.Layout;     
    import org.apache.log4j.Level;     
    import org.apache.log4j.helpers.Transform;     
    import org.apache.log4j.spi.LocationInfo;     
    import org.apache.log4j.spi.LoggingEvent;     
    
    public class FormatHTMLLayout extends HTMLLayout {
        public FormatHTMLLayout() {   
        }   
        
        public String getContentType() { 
            return "text/html;charset=GBK"; 
            }
      
        protected final int BUF_SIZE = 256;   
      
        protected final int MAX_CAPACITY = 1024;   
      
        static String TRACE_PREFIX = "<br>    ";   
      
        private StringBuffer sbuf = new StringBuffer(BUF_SIZE);   
           
        String title="AAA";   
      
        /**  
         * A string constant used in naming the option for setting the the HTML  
         * document title. Current value of this string constant is <b>Title</b>.  
         */  
        public static final String TITLE_OPTION = "Title";   
      
        // Print no location info by default   
        boolean locationInfo = true;   
           
        public String format(LoggingEvent event) {   
            if (sbuf.capacity() > MAX_CAPACITY) {   
                sbuf = new StringBuffer(BUF_SIZE);   
            } else {   
                sbuf.setLength(0);   
            }   
            sbuf.append(Layout.LINE_SEP + "<tr>" + Layout.LINE_SEP);   
                       
            sbuf.append("<td>");   
            sbuf.append(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss SSS").format(new java.util.Date()));   
            sbuf.append("</td>" + Layout.LINE_SEP);   
      
            sbuf.append("<td title="BBB">");   
            if (event.getLevel().equals(Level.FATAL)) {   
                sbuf.append("<font color="#339933">");   
                sbuf.append(Transform.escapeTags(String.valueOf(event.getLevel())));   
                sbuf.append("</font>");   
            } else if (event.getLevel().isGreaterOrEqual(Level.WARN)) {   
                sbuf.append("<font color="#993300"><strong>");   
                sbuf.append(Transform.escapeTags(String.valueOf(event.getLevel())));   
                sbuf.append("</strong></font>");   
            } else {   
                sbuf.append("<font color="green">");   
                sbuf.append(Transform.escapeTags(String.valueOf(event.getLevel())));   
                sbuf.append("</font>");   
            }   
            sbuf.append("</td>" + Layout.LINE_SEP);   
               
       if (locationInfo) {   
                LocationInfo locInfo = event.getLocationInformation();   
                sbuf.append("<td title="CCC">");  
                sbuf.append(locInfo.getClassName());
                sbuf.append('.');
                sbuf.append(locInfo.getMethodName());
                sbuf.append('(');
                sbuf.append(Transform.escapeTags(locInfo.getFileName()));  
                sbuf.append(':');  
                sbuf.append(locInfo.getLineNumber());  
                sbuf.append(')');
                sbuf.append("</td>" + Layout.LINE_SEP);  
            }  
                 
              
            sbuf.append("<td title="DDD">");   
            sbuf.append(Transform.escapeTags(event.getRenderedMessage()));   
            sbuf.append("</td>" + Layout.LINE_SEP);   
            sbuf.append("</tr>" + Layout.LINE_SEP);   
      
            if (event.getNDC() != null) {   
                sbuf.append("<tr><td bgcolor="#EEEEEE" style="font-size : xx-small;" colspan="6" title="Nested Diagnostic Context">");   
                sbuf.append("NDC: " + Transform.escapeTags(event.getNDC()));   
                sbuf.append("</td></tr>" + Layout.LINE_SEP);   
            }   
      
            String[] s = event.getThrowableStrRep();   
            if (s != null) {   
                sbuf.append("<tr><td bgcolor="#993300" style="color:White; font-size : xx-small;" colspan="4">");   
                appendThrowableAsHTML(s, sbuf);   
                sbuf.append("</td></tr>" + Layout.LINE_SEP);   
            }   
            return sbuf.toString();   
        }   
      
        private void appendThrowableAsHTML(String[] s, StringBuffer sbuf) {   
            if (s != null) {   
                int len = s.length;   
                if (len == 0)   
                    return;   
                sbuf.append(Transform.escapeTags(s[0]));   
                sbuf.append(Layout.LINE_SEP);   
                for (int i = 1; i < len; i++) {   
                    sbuf.append(TRACE_PREFIX);   
                    sbuf.append(Transform.escapeTags(s[i]));   
                    sbuf.append(Layout.LINE_SEP);   
                }   
            }   
        }   
      
        /**  
         * Returns appropriate HTML headers.  
         */  
        public String getHeader() {   
            StringBuffer sbuf = new StringBuffer();   
            sbuf.append("<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">" + Layout.LINE_SEP);   
            sbuf.append("<html>" + Layout.LINE_SEP);   
            sbuf.append("<head>" + Layout.LINE_SEP);   
        
            sbuf.append("<title>" + title + "</title>" + Layout.LINE_SEP);   
            sbuf.append("<style type="text/css">" + Layout.LINE_SEP);   
            sbuf.append("<!--" + Layout.LINE_SEP);   
            sbuf.append("body, table {font-family: '',arial,sans-serif; font-size: 12px;}" + Layout.LINE_SEP);   
            sbuf.append("th {background: #336699; color: #FFFFFF; text-align: left;}" + Layout.LINE_SEP);   
            sbuf.append("-->" + Layout.LINE_SEP);   
            sbuf.append("</style>" + Layout.LINE_SEP);   
            sbuf.append("</head>" + Layout.LINE_SEP);   
            sbuf.append("<body bgcolor="#FFFFFF" topmargin="6" leftmargin="6">" + Layout.LINE_SEP);   
        
            sbuf.append("<table cellspacing="0" cellpadding="4" border="1" bordercolor="#224466" width="100%">" + Layout.LINE_SEP);   
            sbuf.append("<tr>" + Layout.LINE_SEP);   
           
            sbuf.append("<th>执行时间</th>" + Layout.LINE_SEP);   
            sbuf.append("<th>级别</th>" + Layout.LINE_SEP);   
          
            if (locationInfo) {   
                sbuf.append("<th>所在行</th>" + Layout.LINE_SEP);   
            }   
       
            sbuf.append("<th>消息</th>" + Layout.LINE_SEP);   
            sbuf.append("</tr>" + Layout.LINE_SEP);   
            sbuf.append("<br></br>" + Layout.LINE_SEP);   
            return sbuf.toString();   
        }   
    }
    MailEvaluator类:
    package com.spike.test;
    
    import org.apache.log4j.Layout;
    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 void activateOptions() {
            // TODO Auto-generated method stub
    
        }
    
        @Override
        public String format(LoggingEvent event) {
            // TODO Auto-generated method stub
            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;
        }
    
    }

    DefineLayOut类

    package com.spike.test;
    
    import org.apache.log4j.HTMLLayout;
    
    public class DefineLayOut extends HTMLLayout {
        public String getContentType() { 
            return "text/html;charset=GBK"; 
            } 
    }


    配置文件:log4j.properties
    log4j.rootLogger=DEBUG,MAIL,A1
    log4j.addivity.org.apache=true
    
    # 每天新建日志
    
    #(警告的意思是DailyRollingFileAppender这个类不带属性maxBackupIndex,maxFileSize的,它是#按日期来保存日志的,所以不需要设置该2个属性,如果想要设置日志文件的大小,可以使用#RollingFileAppender这个类,平时开发中日志配置文件中需要注意设置。)
    log4j.appender.A1=org.apache.log4j.DailyRollingFileAppender
    log4j.appender.A1.File=./logs/cebLog.txt
    log4j.appender.A1.Encoding=GBK
    log4j.appender.A1.Threshold=DEBUG
    log4j.appender.A1.DatePattern='.'yyyy-MM-dd
    log4j.appender.A1.layout=org.apache.log4j.PatternLayout
    #log4j.appender.A1.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L : %m%n
    #log4j.appender.A1.layout.ConversionPattern=/n/n[%-5p] %d{yyyy-MM-dd HH:mm:ss,SSS} method:%l%n%m%n
    log4j.appender.A1.layout.ConversionPattern=%d %-5p %c.%M:%L - %m%n
    
     
    # 发送日志给邮件
    log4j.appender.MAIL=org.apache.log4j.net.SMTPAppender
    log4j.appender.MAIL.Threshold=ERROR
    log4j.appender.MAIL.BufferSize=10
    # 发件人地址
    log4j.appender.MAIL.From=xxxx@126.com
    # 发送邮件的服务器
    log4j.appender.MAIL.SMTPHost=smtp.126.com
    # 邮件的标题
    #log4j.appender.MAIL.Subject=Log4J ErrorMessage
    #log4j.appender.MAIL.Subject= Log4J提醒您:系统发生了严重错误 
    log4j.appender.MAIL.Subject=Log4J error 
    # 用户名
    log4j.appender.MAIL.SMTPUsername=xxxx
    # 密码
    log4j.appender.MAIL.SMTPPassword=xxxx
    # 日志邮件的接收者
    ##发送到什么邮箱,如果要发送给多个邮箱,则用逗号分隔;
    log4j.appender.MAIL.To=xxxx@qq.com
    ##如果需要抄送Cc给某人,则加入下列行:
    #log4j.appender.MAIL.Cc=xxxx@qq.com
    #是否打印调试信息,如果选true,则会输出和SMTP之间的握手等详细信息  
    log4j.appender.MAIL.SMTPDebug=true
    #log4j.appender.MAIL.SMTPDebug=false
    
    #log4j.appender.MAIL.layout=org.apache.log4j.HTMLLayout
    
    #log4j.appender.MAIL.layout=org.apache.log4j.PatternLayout
    #log4j.appender.MAIL.layout.ConversionPattern=%d %-5p [%c] %m%n
    
    #日志显示格式  
    #log4j.appender.MAIL.layout=com.spike.test.MailEvaluator
    #log4j.appender.MAIL.layout.ConversionPattern==%d{yyyy-MM-dd HH:mm:ss} - %c -%-4r [%t] %-5p %c %x - %m %l%n  
    
    #log4j.appender.MAIL.layout=com.spike.test.DefineLayOut
    
    
    #HTMLLayout 类重写,根据自身需要输出不同列
    #参考http://blog.csdn.net/drift_away/article/details/7410038,不过此文有问题
    log4j.appender.MAIL.layout=com.spike.test.FormatHTMLLayout  
    #log4j.appender.MAIL.layout=org.apache.log4j.HTMLLayout  
    #log4j.appender.MAIL.layout=org.apache.log4j.PatternLayout  
    #log4j.appender.MAIL.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss,SSS} [%t] [%c] [%p] - %m%n  

     配置文件:log4j.xml

    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
    
    <log4j:configuration xmlns:log4j='http://jakarta.apache.org/log4j/'>
    
        <appender name="myConsole" class="org.apache.log4j.ConsoleAppender">
            <layout class="org.apache.log4j.PatternLayout">
                <param name="ConversionPattern" value="[%d{dd HH:mm:ss,SSS} %-5p] [%t] %c{2} - %m%n" />
            </layout>
            <!--过滤器设置输出的级别 -->
            <filter class="org.apache.log4j.varia.LevelRangeFilter">
                <param name="levelMin" value="debug" />
                <param name="levelMax" value="error" />
                <param name="AcceptOnMatch" value="true" />
            </filter>
        </appender>
    
        <appender name="myFile" class="org.apache.log4j.DailyRollingFileAppender">
            <param name="File" value="./logs/cebLog.txt" /><!-- 设置日志输出文件名 -->
            <!-- 设置是否在重新启动服务时,在原有日志的基础添加新日志 -->
            <param name="Append" value="true" />
            <param name="Encoding" value="GBK" />
            <param name="DatePattern" value="'.'yyyy-MM-dd'.txt'" />
            <!-- <param name="MaxBackupIndex" value="10" /> -->
            <layout class="org.apache.log4j.PatternLayout">
                <!-- <param name="ConversionPattern" value="%p (%c:%L)- %m%n" /> -->
                <param name="ConversionPattern" value="[%d{yyyy-MM-dd HH:mm:ss SSS} %-5p] [%t] %c{3} - %m%n" />
            </layout>
        </appender>
    
        <appender name="activexAppender" class="org.apache.log4j.DailyRollingFileAppender">
            <param name="File" value="D:/Logs/Logger.log" />
            <param name="DatePattern" value="'.'yyyy-MM-dd'.log'" />
            <layout class="org.apache.log4j.PatternLayout">
                <param name="ConversionPattern" value="[%d{MMdd HH:mm:ss SSS} %-5p] [%t] %c{3} - %m%n" />
            </layout>
        </appender>
    
        <appender name="DATABASE" class="org.apache.log4j.jdbc.JDBCAppender">
            <param name="URL" value="jdbc:oracle:thin:@host:port:sid" />
            <param name="driver" value="oracle.jdbc.driver.OracleDriver" />
            <param name="user" value="username" />
            <param name="password" value="password" />
            <layout class="org.apache.log4j.PatternLayout">
                <param name="ConversionPattern"
                    value="INSERT INTO LOG4J_TEST(stamp,thread,infolevel,class,messages) VALUES ('%d{yyyy-MM-dd HH:mm:ss}', '%t', '%p', '%l', '%m')" />
            </layout>
        </appender>
    
        <!-- 发邮件(只有ERROR时才会发送!) -->
        <appender name="MAIL" class="org.apache.log4j.net.SMTPAppender">
            <param name="threshold" value="error" />
            <!-- 日志的错误级别 <param name="threshold" value="fatal"/> -->
            <!-- 缓存文件大小,日志达到512K时发送Email -->
            <param name="BufferSize" value="512" /><!-- 单位K -->
            <param name="From" value="****@126.com" />
            <param name="SMTPHost" value="smtp.126.com" />
            <param name="Subject" value="Log4J Error 错误" />
            <!-- 多个收件人用逗号,隔开 -->
            <!-- <param name="To" value="******@qq.com,******@qq.com" /> -->
            <param name="To" value="*****@qq.com" />
            <!-- 抄送收件人用Cc -->
            <param name="Cc" value="****@qq.com" />
            <param name="SMTPUsername" value="*****" />
            <param name="SMTPPassword" value="****" />
            <!-- 是否打印SMTP日志记录 -->
            <param name="SMTPDebug" value="true" />
            <!-- <layout class="org.apache.log4j.PatternLayout">
                <param name="ConversionPattern" value="%-d{yyyy-MM-dd HH:mm:ss.SSS} [%p]-[%c] %m%n" />
            </layout> -->
    <!--解决中文乱码问题--> <layout class="com.spike.test.FormatHTMLLayout"> </layout> <!-- <layout class="org.apache.log4j.HTMLLayout"> </layout> --> </appender> <!-- <appender name="ASYNC" class="org.apache.log4j.AsyncAppender"> <param name="BufferSize" value="256" /> <appender-ref ref="DATABASE" /> </appender> 通过<logger></logger>的定义可以将各个包中的类日志输出到不同的日志文件中 <logger name="com.litt2.log4j" additivity="false"> <level value="WARN" /> <appender-ref ref="CONSOLE" /> </logger> 通过<category></category>的定义可以将各个包中的类日志输出到不同的日志文件中 <category name="com.litt3"> <level value="DEBUG" /> <appender-ref ref="CONSOLE" /> <appender-ref ref="MAIL" /> </category> --> <!-- 指定logger的设置,additivity指示是否遵循缺省的继承机制 --> <!-- <logger name="com.runway.bssp.activeXdemo" additivity="false"> <priority value ="info"/> <appender-ref ref="activexAppender" /> </logger> --> <!-- 根logger的设置 --> <root> <priority value="debug" /> <appender-ref ref="myConsole" /> <appender-ref ref="myFile" /> <appender-ref ref="activexAppender" /> <appender-ref ref="DATABASE" /> <appender-ref ref="MAIL" /> </root> </log4j:configuration>

    log4j.properties和log4j.xml都存在会优先读取log4j.xml。

  • 相关阅读:
    mongodb数据库迁移
    idea激活
    常见加密方式
    restful请求风格使用详解
    Jreble破解使用
    websocket入门与分布式websocket
    分布式Session的解决方案
    mysql基础知识与优化总结
    分布式事务详解
    多线程总结与使用
  • 原文地址:https://www.cnblogs.com/huanghongbo/p/6023169.html
Copyright © 2011-2022 走看看