天天看點

AOP+LOG4J日志架構(自定義注解)

宸ヤ綔涓敤鍒版棩蹇楀姛鑳斤紝鍙傝€冪綉涓婁竴浜涜祫鏂欙紝鍐欎簡涓瘮杈冮€氱敤鐨勬棩蹇楁鏋訛紝鐜闆湪鎷垮嚭鏉ュ垎浜紝鍐呭娌℃湁鍋氬お澶氳В閲婏紝濡傛湁涓嶆竻妤氱殑鍦版柟鍙互缁欐垜鐣欒█鎴栨槸閫氳繃缃戜笂鏌ヨ祫鏂欐潵瑙e喅銆?

璁捐鎬濊礬锛氶€氳繃AOP杩涘叆鏂規硶涔嬪墠鎷︽埅鍋氳涓烘棩蹇楄褰曪紝鏂規硶鎶涘紓甯告嫤鎴仛閿欒鏃ュ織璁闆綍銆傚疄鐜拌嚜瀹氫箟娉ㄨВ锛屽彲浠ュ瓨鍏ヨ涓轟腑鏂囨敞閲婏紝涔熷彲浠ラ厤缃垚瀹屽叏鏍規嵁娉ㄨВ鏉ュ喅瀹氭槸鍚﹁褰曟棩蹇楃殑绛栫暐锛屾敮鎸佹帶鍒跺彴銆佹枃浠躲€佹暟鎹簱銆侀偖浠跺拰寮傛澶勭悊绛夊姛鑳戒互鍙婇拡瀵規暟鎹簱鍙互娣誨姞琛屼負缁熻銆佸紓甯哥粺璁″拰閽誨彇鏄庣粏绛夌瓑銆?

web.xml鏂囦歡閰嶇疆濡備笅锛?

<!-- 鏃ュ織 -->

<context-param>
	<param-name>log4jConfigLocation</param-name>
	<param-value>classpath:log4j.xml</param-value>
</context-param>
<!-- 鐩戝惉鍣?鏀懼湪spring鐩戝惉鍣ㄤ箣鍓?->
<listener>
	<listener-class>org.springframework.web.util.Log4jConfigListener</listener-class>
</listener>
           

spring閰嶇疆鏂囦歡濡備笅锛?

log4j閰嶇疆鏂囦歡濡備笅锛?

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd"> 
<!-- log4j xml閰嶇疆 鎺у埗鍙般€佹枃浠躲€佹暟鎹簱鍜岄偖浠?鏀寔寮傛  mengqingyu -->
<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">
	<!-- 鎺у埗鍙?-->
	<appender name="console" class="org.apache.log4j.ConsoleAppender">
		<param name="target" value="System.out"/>
		<layout class="org.apache.log4j.PatternLayout">
			<param name="conversionPattern" value="[%-5p] %d{yyyy-MM-dd HH:mm:ss} %m %n"/>
		</layout>
	</appender>

	<!-- 鏂囦歡 -->
	<appender name="webframe" class="org.apache.log4j.DailyRollingFileAppender">
		<param name="file" value="${webframe.root}/WEB-INF/logs/webframe.log"/>
		<!-- 8K涓轟竴涓啓鍗曞厓
		<param name="BufferedIO" value="true" />
        <param name="BufferSize" value="8192" />
         -->
		<param name="append" value="true"/>
		<param name="datePattern" value="'.'yyyy-MM-dd"/>
		<layout class="org.apache.log4j.PatternLayout">
			<param name="conversionPattern" value="[%-5p] %d{yyyy-MM-dd HH:mm:ss} %m %n"/>
		</layout>
	</appender>	

	<!-- 鏁版嵁搴?-->
	<appender name="db" class="com.berheley.bi.system.log.log4j.JDBCCustomAppender">
		<param name="bufferSize" value="1" />
		<layout class="org.apache.log4j.PatternLayout">
			<param name="conversionPattern"
				value="insert into t_log (LOG_NAME_,USER_NAME_,CLASS_,METHOD_NAME_,CREATE_TIME_,LOG_LEVEL_,METHOD_PARAM_,MSG_BRIEF_,MSG_DETAIL_,CLASS_DISCRIPTION_,METHOD_DISCRIPTION_) values ('%X{LOG_NAME_}','%X{USER_NAME_}','%X{CLASS_}','%X{METHOD_NAME_}','%d{yyyy-MM-dd HH:mm:ss}','%p','%X{METHOD_PARAM_}','%m','%X{MSG_DETAIL_}','%X{CLASS_DISCRIPTION_}','%X{METHOD_DISCRIPTION_}')" />
		</layout>
		<!-- 绾у埆杩囨護
		<filter class="org.apache.log4j.varia.LevelRangeFilter"> 
			<param name="LevelMax" value="error" /> 
			<param name="LevelMin" value="error" /> 
		</filter> 
		-->
	</appender>

	<!-- 閭歡 鍙厤缃涓猘ppender妯″潡鍒掑垎-->
	<appender name="mail" class="com.berheley.bi.system.log.log4j.SMTPCustomAppender">
		<param name="threshold" value="fatal"/>
		<param name="bufferSize" value="1"/>
		<param name="from" value="[email聽protected]"/>
		<param name="smtpHost" value="smtp.gmail.com"/>
		<param name="smtpAuth" value="true"/>
		<param name="smtpUsername" value="[email聽protected]"/>
		<param name="smtpPassword" value="1"/>
		<param name="subject" value=" Log4J Message"/>
		<param name="packages" value="com.berheley.bi.fillform,com.berheley.bi.system"/>  <!-- 鍙互閰嶇疆澶氫釜浠?鍙烽棿闅?-->		
		<param name="to" value="[email聽protected]"/> <!-- 鍙互閰嶇疆澶氫釜浠?鍙烽棿闅?-->		
		<layout class="com.berheley.bi.system.log.log4j.HTMLCustomLayout"/>
	</appender>	

	<!-- 澶氱嚎绋?-->		
	<appender name="async" class="org.apache.log4j.AsyncAppender">
		<param name="bufferSize" value="100" />
		<appender-ref ref="db" />
		<appender-ref ref="mail" />
	</appender>

	<!-- 缁ф壙root log4j鍖呬笅杩愯寮傛绾跨▼鏃ュ織 -->
	<logger name="com.berheley.bi.system.log"> 
		<level value="info"/>
		<appender-ref ref="async"/> 
	</logger>

	<!-- 杈撳嚭绾у埆 -->	
	<root>
		<priority value="error" />
		<appender-ref ref="console" />
		<appender-ref ref="webframe" />
	</root>

	<!-- 鍗曚釜鏃ュ織绾у埆鎺у埗
	<category name="monitorLogger" additivity="false">
        <priority value="info" />
        <appender-ref ref="console"/>
    </category >
    -->
</log4j:configuration>
           
import java.io.PrintWriter;
import java.io.StringWriter;
import java.lang.reflect.Method;

import org.apache.commons.logging.Log;
import org.apache.log4j.MDC;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.webframe.web.springmvc.exp.AjaxException;

import com.berheley.bi.basic.exp.BusinessException;
import com.berheley.bi.system.login.LoginUser;

/**
 * 
 * 绫誨姛鑳芥弿杩幫細 鏃ュ織宸ュ叿绫夥紝璁劇疆灞炴€? *
 * @author <a href="mailto:[email聽protected]" target="_blank" rel="external nofollow"  target="_blank" rel="external nofollow"  target="_blank" rel="external nofollow"  target="_blank" rel="external nofollow"  target="_blank" rel="external nofollow" >mengqingyu </a>
 * @version $Id: codetemplates.xml,v 1.1 2009/03/06 01:13:01 mengqingyu Exp  $
 * Create:  2013-4-12 涓嬪崍04:55:44
 */
public abstract class LogUtils {

	public static final String WEB_CONTEXT_ 			= 		"WEB_CONTEXT_";

	public static final String LOG_NAME_ 				= 		"LOG_NAME_";

	public static final String USER_NAME_ 				= 		"USER_NAME_";

	public static final String CLASS_ 					= 		"CLASS_";

	public static final String PACKAGES_ 				= 		"PACKAGES_";

	public static final String METHOD_NAME_ 			= 		"METHOD_NAME_";

	public static final String METHOD_PARAM_ 			= 		"METHOD_PARAM_";

	public static final String CLASS_DISCRIPTION_ 		= 		"CLASS_DISCRIPTION_";

	public static final String METHOD_DISCRIPTION_ 		= 		"METHOD_DISCRIPTION_";

	public static final String MSG_DETAIL_ 				= 		"MSG_DETAIL_";

	/**
	 * 
	 * @function:鎿嶄綔琛屼負璁闆綍
	 * @param clazz 绫誨璞?	 * @param method 鏂規硶瀵矽薄
	 * @param args 鏂規硶鍙傛暟
	 * @param log 鏃ュ織瀵矽薄
	 * @throws BusinessException
	 * @author: mengqingyu    2013-5-30 涓嬪崍05:29:57
	 */
	public static void beforeLog(Class<?> clazz, Method method, Object[] args, Log log, boolean annotation) throws BusinessException{
		LogDiscription methodDiscription =  method.getAnnotation(LogDiscription.class);
		if(annotation==false||methodDiscription!=null){
			initLog(clazz, method, args, null, methodDiscription);
			log.info(new StringBuilder("info:").append(LogUtils.getClassName()).append("->").append(LogUtils.getMethodName()));
		}
	}

	/**
	 * 
	 * @function:寮傚父璁闆綍
	 * @param clazz 绫誨璞?	 * @param method 鏂規硶瀵矽薄
	 * @param args 鏂規硶鍙傛暟
	 * @param ex 寮傚父瀵矽薄
	 * @param log 鏃ュ織瀵矽薄
	 * @throws BusinessException
	 * @author: mengqingyu    2013-5-30 涓嬪崍05:30:00
	 */
	public static void throwingLog(Class<?> clazz, Method method, Object[] args, Exception ex, Log log, boolean annotation) throws BusinessException{
		LogDiscription methodDiscription =  method.getAnnotation(LogDiscription.class);
		if(annotation==false||methodDiscription!=null){
			initLog(clazz, method, args, ex, methodDiscription);
			if(ex instanceof BusinessException || ex instanceof AjaxException){
				log.error(ex.getMessage(),ex);
			}
			else{
				log.fatal(ex.getMessage(),ex);
			}
		}
	}

	/**
	 * 
	 * @function:鍒濆鍖栧弬鏁?	 * @param clazz 绫誨璞?	 * @param method 鏂規硶瀵矽薄
	 * @param args 鏂規硶鍙傛暟
	 * @param ex 寮傚父瀵矽薄
	 * @throws BusinessException
	 * @author: mengqingyu    2013-4-12 涓嬪崍04:56:09
	 */
	protected static void initLog(Class<?> clazz, Method method, Object[] args, Exception ex, LogDiscription methodDiscription) throws BusinessException{
		if(clazz==null||method==null)
			throw new BusinessException("鏃ュ織鍒濆鍖栧弬鏁癱lazz鎴杕ethod涓虹┖");

		setLogName();
		setClass(clazz);
		setMethodName(method);
		setMethodParam(args,methodDiscription);
		setClassDiscription(clazz.getAnnotation(LogDiscription.class));
		setMethodDiscription(methodDiscription);
		setMsgDetail(ex);
	}

	/**
	 * 
	 * @function:鍒濆鍖栧弬鏁?	 * @param clazz 绫誨璞?	 * @param method 鏂規硶鍚嶇О
	 * @param classTypes 鏂規硶鍙傛暟绫誨瀷
	 * @param args 鏂規硶鍙傛暟
	 * @param ex 寮傚父瀵矽薄
	 * @throws BusinessException
	 * @author: mengqingyu    2013-4-12 涓嬪崍04:56:09
	 */
	@SuppressWarnings("rawtypes")
	public static Method initLog(Class<?> clazz, String methodName, Class[] classTypes) throws BusinessException{
		if(clazz==null||methodName==null)
			throw new BusinessException("鏃ュ織鍒濆鍖栧弬鏁幫細clazz鎴杕ethod涓虹┖");

		Method method;
		try {
			method = clazz.getMethod(methodName, classTypes);
		} catch (SecurityException e) {
			throw new BusinessException("鏂規硶鏉冮檺閿欒"+methodName,e);
		} catch (NoSuchMethodException e) {
			throw new BusinessException("鏂規硶鍚嶆垨鍙傛暟绫誨瀷閿欒锛?+methodName,e);
		}
		return method;
	}

	private static void setLogName(){
		Authentication auth = SecurityContextHolder.getContext().getAuthentication();
		String Username;
		String RealName;
		if(auth!=null){
			LoginUser loginUser = (LoginUser)auth.getPrincipal();
			Username = loginUser.getUsername();
			RealName = loginUser.getRealName();
		}
		else{
			Username = Thread.currentThread().getName();
			RealName = "鏃?;
		}
		MDC.put(LogUtils.LOG_NAME_, Username);
		MDC.put(LogUtils.USER_NAME_, RealName);
	}

	private static void setClass(Class<?> clazz){
		MDC.put(LogUtils.CLASS_, clazz.getName().substring(clazz.getName().lastIndexOf(".")+1));
		MDC.put(LogUtils.PACKAGES_, clazz.getName());
	}

	private static void setMethodName(Method method){
		MDC.put(LogUtils.METHOD_NAME_, method.getName());
	}

	private static void setMethodParam(Object[] args, LogDiscription logDiscription){
		if(args!=null){
			StringBuilder methodParam = new StringBuilder();
			String param = logDiscription==null?"":logDiscription.param();
			if("".equals(param)){
		        for(Object o:args){  
		        	methodParam.append(o).append("<br/>");
		        }  
			}
			else{
				String[] paramArray = param.split(",");
				int paramLength = paramArray.length;
				if(paramLength != args.length){
					methodParam.append("鍙傛暟娉ㄩ噴閿欒");
				}
				else{
					for(int i=0;i<args.length;i++){
						methodParam.append(paramArray[i]).append("锛?).append(args[i]).append("<br/>");
					}
				}
			}
			MDC.put(LogUtils.METHOD_PARAM_, replaceParam(methodParam.toString()));
		}
	}

	private static void setClassDiscription(LogDiscription logDiscription){
		MDC.put(LogUtils.CLASS_DISCRIPTION_, replaceParam(logDiscription==null?"":logDiscription.clazz()));
	}

	private static void setMethodDiscription(LogDiscription logDiscription){
		MDC.put(LogUtils.METHOD_DISCRIPTION_, replaceParam(logDiscription==null?"":logDiscription.method()));
	}

	/**
	 * 
	 * @function:璁劇疆寮傚父淇℃伅
	 * @param ex 寮傚父瀵矽薄
	 * @author: mengqingyu    2013-4-12 涓嬪崍04:56:53
	 */
	public static void setMsgDetail(Exception ex){
		if(ex!=null){
			StringWriter sw = new StringWriter();
			PrintWriter pw = new PrintWriter(sw);
			ex.printStackTrace(pw);
			MDC.put(LogUtils.MSG_DETAIL_, sw);
		}
	}

	/**
	 * 
	 * @function:鑾峰彇绫誨悕绉?	 * @return
	 * @author: mengqingyu    2013-4-12 涓嬪崍04:57:13
	 */
	public static String getClassName(){
		return MDC.get(LogUtils.CLASS_)==null?"null":MDC.get(LogUtils.CLASS_).toString();
	}

	/**
	 * 
	 * @function:鑾峰彇鏂規硶鍚嶇О
	 * @return
	 * @author: mengqingyu    2013-4-12 涓嬪崍04:57:30
	 */
	public static String getMethodName(){
		return MDC.get(LogUtils.METHOD_NAME_)==null?"null":MDC.get(LogUtils.METHOD_NAME_).toString();
	}

	private static String replaceParam(String value){
		return value.replace(",", "\\,").replace("'", "\\'");
	}
}

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;

/**
 * 
 * 绫誨姛鑳芥弿杩幫細鑷畾涔夋棩蹇楁敞瑙? *
 * @author <a href="mailto:[email聽protected]" target="_blank" rel="external nofollow"  target="_blank" rel="external nofollow"  target="_blank" rel="external nofollow"  target="_blank" rel="external nofollow"  target="_blank" rel="external nofollow" >mengqingyu </a>
 * @version $Id: codetemplates.xml,v 1.1 2009/03/06 01:13:01 mengqingyu Exp  $
 * Create:  2013-4-12 涓嬪崍01:57:44
 */
@Retention(RetentionPolicy.RUNTIME)
public @interface LogDiscription {
	/**
	 * 鐢ㄦ硶锛氬湪绫誨悕涓婃柟鍔犲叆娉ㄨВ浠g爜 @LogDiscription(clazz="琛ㄥ崟鍒嗛厤")
	 * @function:绫繪敞閲?	 * @return
	 * @author: mengqingyu    2013-4-12 涓嬪崍01:57:10
	 */
	String clazz() default "";

	/**
	 * 鐢ㄦ硶锛氬湪鏂規硶鍚嶄笂鏂瑰姞鍏ユ敞瑙d唬鐮?@LogDiscription(method = "绔嬪嵆鍙戝竷",param = "浠誨姟ID:{0} 涓婚敭:{1} 鍒涘緩鏃堕棿:{2}")
	 * @function:鏂規硶娉ㄩ噴
	 * @return
	 * @author: mengqingyu    2013-4-12 涓嬪崍01:57:22
	 */
	String method() default "";

	/**
	 * 
	 * @function:鏂規硶鍙傛暟娉ㄩ噴
	 * @return
	 * @author: mengqingyu    2013-4-12 涓嬪崍01:57:30
	 */
	String param() default "";
}

import java.sql.Connection;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Iterator;

import javax.sql.DataSource;

import org.apache.log4j.jdbc.JDBCAppender;
import org.apache.log4j.spi.ErrorCode;
import org.apache.log4j.spi.LoggingEvent;
import org.webframe.web.util.WebFrameUtils;

/**
 * 
 * 绫誨姛鑳芥弿杩幫細log4j 鍏ュ簱鏃ュ織绠$悊锛岄噸鍐欐绫昏В鍐蟲暟鎹簮銆佹壒閲忔彃鍏ュ拰鏃ュ織杩囨護绛夐棶棰? *
 * @author <a href="mailto:[email聽protected]" target="_blank" rel="external nofollow"  target="_blank" rel="external nofollow"  target="_blank" rel="external nofollow"  target="_blank" rel="external nofollow"  target="_blank" rel="external nofollow" >mengqingyu </a>
 * @version $Id: codetemplates.xml,v 1.1 2009/03/06 01:13:01 mengqingyu Exp  $
 * Create:  2013-4-9 涓嬪崍02:20:08
 */
public class JDBCCustomAppender extends JDBCAppender {

	/**
	 * 绫誨姛鑳芥弿杩幫細鏁版嵁搴撹繛鎺ユ睜锛屽崟渚嬶紝寤惰繜瀹炰緥鍖?	 */
	private static class DataSourceHolder {
		private static final DataSource dataSource = (DataSource) WebFrameUtils.getApplicationContext().getBean("dataSource");
	}

	/**
	 * 鍦ㄦ棩蹇楀姞鍏ラ泦鍚堣繃绋嬩腑杩涜澶勭悊
	 */
	@SuppressWarnings("unchecked")
	@Override
	public void append(LoggingEvent event) {
		buffer.add(event);
		if (buffer.size() >= bufferSize)
			flushBuffer();
	}

	/**
	 * 浠庤繛鎺ユ睜涓幏鍙栬繛鎺?	 */
	@Override
	protected Connection getConnection() throws SQLException {
		return DataSourceHolder.dataSource.getConnection();
	}

	/**
	 * 鍒犲幓浜嗘簮鏂規硶涓殑涓€浜涙搷浣?	 */
	@Override
	public void close() {
		this.closed = true;
	}

	/**
	 * 閲婃斁杩炴帴
	 */
	@Override
	protected void closeConnection(Connection con) {
		try {
			con.close();
		} catch (SQLException e) {
			errorHandler.error("Error closing connection", e, ErrorCode.GENERIC_FAILURE);
		}
	}

	/**
	 * 閲嶅啓鎵歸噺鎻掑叆鎿嶄綔
	 */
	@SuppressWarnings("unchecked")
	@Override
	public void flushBuffer() {
		Connection con = null;
		Statement stmt = null;
		try {
			con = getConnection();
			stmt = con.createStatement();
			removes.ensureCapacity(buffer.size());
			for (Iterator<LoggingEvent> i = buffer.iterator(); i.hasNext();) {
				LoggingEvent logEvent = i.next();
				stmt.addBatch(getLogStatement(logEvent));
				removes.add(logEvent);
			}
		 	stmt.executeBatch();
		} catch (SQLException e) {
		    errorHandler.error("Failed to excute sql", e,ErrorCode.FLUSH_FAILURE);
		} finally {
			try {
				stmt.close();
			} catch (SQLException e) {
				errorHandler.error("Failed to excute sql", e,ErrorCode.FLUSH_FAILURE);
			} finally {
				closeConnection(con);
			}
		}
		buffer.removeAll(removes);
		removes.clear();
	}
}

import java.util.Properties;

import javax.mail.Authenticator;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.PasswordAuthentication;
import javax.mail.Session;
import javax.mail.internet.AddressException;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;

import org.apache.log4j.helpers.LogLog;
import org.apache.log4j.net.SMTPAppender;
import org.apache.log4j.spi.ErrorCode;
import org.apache.log4j.spi.LoggingEvent;

/**
 * 
 * 绫誨姛鑳芥弿杩幫細log4j 閭歡鏃ュ織绠$悊锛岄噸鍐欐绫昏В鍐充笉鏀寔鏉冮檺璁よ瘉銆佺紦瀛橀棶棰樺拰gmail绔彛鍙烽棶棰橈紝娉細鏂扮増鏈琹og4j宸茬粡鏀寔璁よ瘉
 *
 * @author <a href="mailto:[email聽protected]" target="_blank" rel="external nofollow"  target="_blank" rel="external nofollow"  target="_blank" rel="external nofollow"  target="_blank" rel="external nofollow"  target="_blank" rel="external nofollow" >mengqingyu </a>
 * @version $Id: codetemplates.xml,v 1.1 2009/03/06 01:13:01 mengqingyu Exp  $
 * Create:  2013-4-11 涓嬪崍01:44:19
 */
public class SMTPCustomAppender extends SMTPAppender {

	protected String smtpUsername;

	protected String smtpPassword;

	protected String smtpAuth;

	protected String[] packages;

	protected String to;

	protected String from;

	protected String subject;

	protected String smtpHost;

	protected int bufferSize = 512;

	protected boolean locationInfo = false;

	public void setSmtpUsername(String smtpUsername) {
		this.smtpUsername = smtpUsername;
	}

	public void setSmtpPassword(String smtpPassword) {
		this.smtpPassword = smtpPassword;
	}

	public void setSmtpAuth(String smtpAuth) {
		this.smtpAuth = smtpAuth;
	}

	public void setTo(String to) {
		this.to = to;
	}

	public void setPackages(String packages) {
		this.packages = packages.split(",");
	}

	public void setFrom(String from) {
		this.from = from;
	}

	public void setSubject(String subject) {
		this.subject = subject;
	}

	public void setSmtpHost(String smtpHost) {
		this.smtpHost = smtpHost;
	}

	public void setBufferSize(int bufferSize) {
		this.bufferSize = bufferSize;
	}

	public void setLocationInfo(boolean locationInfo) {
		this.locationInfo = locationInfo;
	}

	/**
	 * 鍦ㄦ棩蹇楀姞鍏ラ泦鍚堣繃绋嬩腑杩涜澶勭悊
	 */
	public void append(LoggingEvent event) {
		if (!checkEntryConditions()) {
			return;
		}

		event.getThreadName();
		event.getNDC();
		if (locationInfo) {
			event.getLocationInformation();
		}
		//鍖呰繃婊?		if(packages!=null&&packages.length>0){
			String clazz = event.getMDC(LogUtils.PACKAGES_).toString();
			for(int i=0;i<packages.length;i++){
				if(clazz.startsWith(packages[i])){
					cb.add(event);
					break;
				}
			}
		}
		else{
			cb.add(event);
		}
		if (evaluator.isTriggeringEvent(event)) {
            if (cb.length() >= bufferSize) { //娣誨姞缂撳瓨鍒ゆ柇 
                sendBuffer();  
            }  
		}
	}

	/**
	 * 鍒濆鍖栭偖浠跺璞″苟杩涜鏉冮檺璁よ瘉
	 */
	public void activateOptions() {
		Properties props = new Properties(System.getProperties());
		if (smtpHost != null) {
			props.put("mail.smtp.host", smtpHost);
			// 閭歡榛樿绔彛鍙鋒槸25锛実mail閭歡鏈嶅姟鍟嗙敤鏄?65绔彛锛岄渶瑕佹墜鍔ㄥ鐞?			if (smtpHost.indexOf("smtp.gmail.com") >= 0) {
				props.setProperty("mail.smtp.socketFactory.class",
						"javax.net.ssl.SSLSocketFactory");
				props.setProperty("mail.smtp.socketFactory.fallback", "false");
				props.setProperty("mail.smtp.port", "465");
				props.setProperty("mail.smtp.socketFactory.port", "465");
			}
		}

		Authenticator authenticator = null;

		if (smtpAuth != null && smtpAuth.trim().equals("true")) {
			props.put("mail.smtp.auth", "true");
			authenticator = new Authenticator() {
				protected PasswordAuthentication getPasswordAuthentication() {
					return new PasswordAuthentication(smtpUsername,
							smtpPassword);
				}
			};
		}

		Session session = Session.getInstance(props, authenticator);
		msg = new MimeMessage(session);

		try {
			if (from != null)
				msg.setFrom(getAddress(from));// 璁劇疆鍙戜歡浜?			else
				msg.setFrom();
			msg.setRecipients(Message.RecipientType.TO, parseAddress(to));// 璁劇疆鏀朵歡浜?			if (subject != null){
				String context = WebFrameUtils.getWebContextPath();
				context = StringUtils.isBlank(context)?subject:context.replace("/", "")+" "+subject;
				msg.setSubject(context);
			}

		} catch (MessagingException e) {
			LogLog.error("Could not activate SMTPAppender options.", e);
		}
	}

	/**
	 * 
	 * @function:鑾峰緱鍦闆潃
	 * @param addressStr
	 * @return
	 * @author: mengqingyu 2013-4-10 涓嬪崍02:38:30
	 */
	protected InternetAddress getAddress(String addressStr) {
		try {
			return new InternetAddress(addressStr);
		} catch (AddressException e) {
			errorHandler.error("Could not parse address [" + addressStr + "].",
					e, ErrorCode.ADDRESS_PARSE_FAILURE);
			return null;
		}
	}

	/**
	 * 
	 * @function:杞崲鍦闆潃
	 * @param addressStr
	 * @return
	 * @author: mengqingyu 2013-4-10 涓嬪崍02:38:52
	 */
	protected InternetAddress[] parseAddress(String addressStr) {
		try {
			return InternetAddress.parse(addressStr, true);
		} catch (AddressException e) {
			errorHandler.error("Could not parse address [" + addressStr + "].",
					e, ErrorCode.ADDRESS_PARSE_FAILURE);
			return null;
		}
	}
}

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;

/**
 * 
 * 绫誨姛鑳芥弿杩幫細log4j 鏃ュ織妯℃澘锛岄噸鍐欐绫昏В鍐充腑鏂囦貢鐮佸拰鑷畾涔夋ā鏉塊棶棰? *
 * @author <a href="mailto:[email聽protected]" target="_blank" rel="external nofollow"  target="_blank" rel="external nofollow"  target="_blank" rel="external nofollow"  target="_blank" rel="external nofollow"  target="_blank" rel="external nofollow" >mengqingyu </a>
 * @version $Id: codetemplates.xml,v 1.1 2009/03/06 01:13:01 mengqingyu Exp  $
 * Create:  2013-4-11 涓嬪崍01:46:43
 */
public class HTMLCustomLayout extends HTMLLayout {

	protected StringBuffer sbuf = new StringBuffer(BUF_SIZE);

	protected static String TRACE_PREFIX = "<br>聽聽聽聽";

	protected boolean locationInfo = false;

	protected String title = "Log4J Log Messages";

	public void setLocationInfo(boolean flag) {
		locationInfo = flag;
	}

	public boolean getLocationInfo() {
		return locationInfo;
	}

	public void setTitle(String title) {
		this.title = title;
	}

	public String getTitle() {
		return title;
	}

	/**
	 * 鏍煎紡鍖朒TML澶撮儴妯℃澘
	 */
	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: x-small;}"
				+ 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("<hr size=\"1\" noshade>" + Layout.LINE_SEP);
		sbuf.append("Log session start time " + new java.util.Date() + "<br>"
				+ Layout.LINE_SEP);
		sbuf.append("<br>" + Layout.LINE_SEP);
		sbuf.append("<table cellspacing=\"0\" cellpadding=\"4\" 1\" bordercolor=\"#224466\" width=\"100%\">"
				+ Layout.LINE_SEP);
		sbuf.append("<tr>" + Layout.LINE_SEP);
		sbuf.append("<th>鐧誨綍鍚?lt;/th>" + Layout.LINE_SEP);
		sbuf.append("<th>鐢ㄦ埛鍚?lt;/th>" + Layout.LINE_SEP);
		sbuf.append("<th>绾у埆</th>" + Layout.LINE_SEP);
		sbuf.append("<th>绫誨悕绉?lt;/th>" + Layout.LINE_SEP);
		if (locationInfo) {
			sbuf.append("<th>File:Line</th>" + Layout.LINE_SEP);
		}
		sbuf.append("<th>鏂規硶鍚嶇О</th>" + Layout.LINE_SEP);
		sbuf.append("</tr>" + Layout.LINE_SEP);
		return sbuf.toString();
	}

	/**
	 * 鏍煎紡鍖朒TML妯℃澘
	 */
	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(event.getMDC("LOG_NAME_"));
		sbuf.append("</td>" + Layout.LINE_SEP);

		sbuf.append("<td>");
		sbuf.append(event.getMDC("USER_NAME_"));
		sbuf.append("</td>" + Layout.LINE_SEP);

		sbuf.append("<td title=\"Level\">");
		if (event.getLevel().equals(Level.DEBUG)) {
			sbuf.append("<font color=\"#339933\">");
			sbuf.append(event.getLevel());
			sbuf.append("</font>");
		} else if (event.getLevel().isGreaterOrEqual(Level.WARN)) {
			sbuf.append("<font color=\"#993300\"><strong>");
			sbuf.append(event.getLevel());
			sbuf.append("</strong></font>");
		} else {
			sbuf.append(event.getLevel());
		}
		sbuf.append("</td>" + Layout.LINE_SEP);

		sbuf.append("<td>");
		sbuf.append(event.getMDC("CLASS_"));
		sbuf.append("</td>" + Layout.LINE_SEP);

		if (locationInfo) {
			LocationInfo locInfo = event.getLocationInformation();
			sbuf.append("<td>");
			sbuf.append(Transform.escapeTags(locInfo.getFileName()));
			sbuf.append(':');
			sbuf.append(locInfo.getLineNumber());
			sbuf.append("</td>" + Layout.LINE_SEP);
		}

		sbuf.append("<td>");
		sbuf.append(event.getMDC("METHOD_NAME_"));
		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);
		}

		Object methodParam = event.getMDC("METHOD_PARAM_");
		if(methodParam!=null){
			sbuf.append("<tr><td style=\"font-size : xx-small;\" colspan=\"6\">");
			sbuf.append("鏂規硶鍙傛暟锛?+methodParam.toString().replace("\\r\\n", "聽聽"));
			sbuf.append("</td></tr>" + Layout.LINE_SEP);
		}

		sbuf.append("<tr><td style=\"font-size : xx-small;\" colspan=\"6\">");
		sbuf.append("寮傚父鎽樿锛?+event.getMessage());
		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=\"6\">");
			appendThrowableAsHTML(s, sbuf);
			sbuf.append("</td></tr>" + Layout.LINE_SEP);
		}

		return sbuf.toString();
	}

	/**
	 * 
	 * @function:鎷艱寮傚父鍐呭
	 * @param s
	 * @param sbuf
	 * @author: mengqingyu    2013-4-11 涓嬪崍01:49:29
	 */
	protected 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);
			}
		}
	}

	/**
	 * 涓枃缂栫爜
	 */
	public String getContentType() {
		return "text/html;charset=GBK";
	}
}
           

娉細鍦ㄧ被鎴栨柟娉曚笂閫氳繃娉ㄨВ鐨勬柟寮忔潵杩涜鎻忚堪