AOP實現日誌管理

利用AOP實現在controller層實現日誌記錄,往日誌文件裏寫相應日誌信息。


先在log4j進行log功能的一些配置

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE log4j:configuration PUBLIC "-//APACHE//DTD LOG4J 1.2//EN" "log4j.dtd"> 
<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/"
	threshold="all" debug="false">

	<appender name="console" class="org.apache.log4j.ConsoleAppender">
		<layout class="org.apache.log4j.PatternLayout">
			<param name="ConversionPattern" value="%d %-5p %c %x - %m%n" />
		</layout>
		<filter class="org.apache.log4j.varia.LevelRangeFilter">
			<param name="levelMin" value="DEBUG" />
			<param name="levelMax" value="FATAL" />
			<param name="AcceptOnMatch" value="true" />
		</filter>
	</appender>


	<appender name="file" class="org.apache.log4j.rolling.RollingFileAppender">
		<rollingPolicy class="org.apache.log4j.rolling.TimeBasedRollingPolicy">
			<param name="FileNamePattern" value="${webapp.root}logs/api/api-log-%d{yyyyMMdd}.log" />
		</rollingPolicy>
		<layout class="org.apache.log4j.PatternLayout">
			<param name="ConversionPattern" value="[%d{yyyy-MM-dd HH:mm:ss}] %m%n" />
		</layout>
	</appender>

	<appender name="exceptionAppender" class="org.apache.log4j.rolling.RollingFileAppender">
		<rollingPolicy class="org.apache.log4j.rolling.TimeBasedRollingPolicy">
			<param name="FileNamePattern" value="${webapp.root}logs/api/api-error-%d{yyyyMMdd}.log" />
		</rollingPolicy>
		<layout class="org.apache.log4j.PatternLayout">
			<param name="ConversionPattern" value="[%d{yyyy-MM-dd HH:mm:ss}] %m%n" />
		</layout>
	</appender>

        <appender name="chargeAppender" class="org.apache.log4j.rolling.RollingFileAppender">
		<rollingPolicy class="org.apache.log4j.rolling.TimeBasedRollingPolicy">
			<param name="FileNamePattern" value="${webapp.root}logs/api/api-charge-%d{yyyyMMdd}.log" />
		</rollingPolicy>
		<layout class="org.apache.log4j.PatternLayout">
			<param name="ConversionPattern" value="%d{yyyy-MM-dd HH:mm:ss} %m%n" />
		</layout>
	</appender>

	<appender name="userBehaviorAppender" class="org.apache.log4j.rolling.RollingFileAppender">
		<rollingPolicy class="org.apache.log4j.rolling.TimeBasedRollingPolicy">
			<param name="FileNamePattern"
				value="${webapp.root}logs/api/api-user-behavior-%d{yyyyMMdd}.log" />
		</rollingPolicy>
		<layout class="org.apache.log4j.PatternLayout">
			<param name="ConversionPattern" value="%m%n" />
		</layout>
	</appender>

	<appender name="inOutPutAppender" class="org.apache.log4j.rolling.RollingFileAppender">
		<rollingPolicy class="org.apache.log4j.rolling.TimeBasedRollingPolicy">
			<param name="FileNamePattern"
				value="${webapp.root}logs/api/api-inOutPut-%d{yyyyMMdd}.log" />
		</rollingPolicy>
		<layout class="org.apache.log4j.PatternLayout">
			<param name="ConversionPattern" value="%m%n" />
		</layout>
	</appender>

	<appender name="httpAppender" class="org.apache.log4j.rolling.RollingFileAppender">
		<rollingPolicy class="org.apache.log4j.rolling.TimeBasedRollingPolicy">
			<param name="FileNamePattern" value="${webapp.root}logs/api/api-http-%d{yyyyMMdd}.log" />
		</rollingPolicy>
		<layout class="org.apache.log4j.PatternLayout">
			<param name="ConversionPattern" value="[%d{yyyy-MM-dd HH:mm:ss}] %m%n" />
		</layout>
	</appender>

	<appender name="accessAppender" class="org.apache.log4j.rolling.RollingFileAppender">
		<rollingPolicy class="org.apache.log4j.rolling.TimeBasedRollingPolicy">
			<param name="FileNamePattern"
				value="${webapp.root}logs/api/api-access-%d{yyyyMMdd}.log" />
		</rollingPolicy>
		<layout class="org.apache.log4j.PatternLayout">
			<param name="ConversionPattern" value="%m%n" />
		</layout>
	</appender>

	<appender name="serviceAppender" class="org.apache.log4j.rolling.RollingFileAppender">

		<rollingPolicy class="org.apache.log4j.rolling.TimeBasedRollingPolicy">
			<param name="FileNamePattern"
				value="${webapp.root}logs/api/api-servitization-%d{yyyyMMdd}.log" />
		</rollingPolicy>
		<layout class="org.apache.log4j.PatternLayout">
			<param name="ConversionPattern" value="[%d{yyyy-MM-dd HH:mm:ss}] %m%n" />
		</layout>
	</appender>

	<logger name="exceptionLog" additivity="false">
		<level value="INFO" />
		<appender-ref ref="exceptionAppender" />
	</logger>

	<logger name="chargeLog" additivity="false">
		<level value="INFO" />
		<appender-ref ref="chargeAppender" />
	</logger>

	<logger name="userBehaviorLog" additivity="false">
		<level value="INFO" />
		<appender-ref ref="userBehaviorAppender" />
	</logger>

	<logger name="inOutPutLog" additivity="false">
		<level value="INFO" />
		<appender-ref ref="inOutPutAppender" />
	</logger>

	<logger name="httpLog" additivity="false">
		<level value="INFO" />
		<appender-ref ref="httpAppender" />
	</logger>

	<logger name="accessLog" additivity="false">
		<level value="INFO" />
		<appender-ref ref="accessAppender" />
		<!-- <appender-ref ref="accessAppenderScribe" /> -->
	</logger>

	<logger name="serviceLog" additivity="false">
		<level value="INFO" />
		<appender-ref ref="serviceAppender" />
	</logger>

	<root>
		<priority value="error" />
		<appender-ref ref="console" />
		<appender-ref ref="file" />
	</root>

</log4j:configuration>

再創建一個Java文件(LogHelper),作爲工具類,往日誌表裏寫入日誌或輸出到控制檯等等。

package com.warehouse.controller.api.log;

import java.io.PrintWriter;
import java.io.StringWriter;
import java.net.URL;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
import java.util.StringTokenizer;
import javax.servlet.http.HttpServletRequest;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.log4j.Logger;
import org.apache.log4j.xml.DOMConfigurator;
import com.alibaba.fastjson.JSON;
import com.warehouse.controller.util.RegexUtil;

/**
 * @author Meng
 */
public class LogHelper {

	protected static final Log log = LogFactory.getLog(LogHelper.class);
	private static boolean isInit = false;
	private final Object lock = new Object();
	protected static Class LogHelper; /* synthetic field */
	private static String logXml = "/log4j.xml";
	private Logger logger;
	private static HashMap<String, LogHelper> logHelperMap = new HashMap<String, LogHelper>();

	/**
	 * 初始化log4j配置文件
	 * 
	 * @param logXmlConfigFile
	 */
	public static void init(String logXmlConfigFile) {
		log.debug("init log");
		if ((logXmlConfigFile != null) && (!logXmlConfigFile.equals(""))) {
			logXml = logXmlConfigFile;
		}
	}

	/**
	 * constructor init the Log4j only one time
	 */
	private LogHelper() {
		synchronized (lock) {
			if (!isInit) {
				String file = null;
				try {
					// file = SystemConfig.getProperty("log.file.path");
					if (StringUtils.isBlank(file)) {
						URL res = super.getClass().getResource(logXml);
						if (res == null) {
							file = "." + logXml;
						} else {
							file = res.getPath();
						}
					}
					DOMConfigurator.configure(file);
					isInit = true;
				} catch (Exception e) {
					e.printStackTrace();
					log.error("Log4j init fail:" + e.toString());
				}
			}
		}
	}

	/**
	 * get a LogHelper instance by the log name.
	 * 
	 * @param logName
	 * @return
	 */
	public static LogHelper getInstatnce(String logName) {
		if (!logHelperMap.containsKey(logName)) {
			LogHelper tmphelper = new LogHelper();
			tmphelper.logger = Logger.getLogger(logName);
			logHelperMap.put(logName, tmphelper);
			return tmphelper;
		}
		return logHelperMap.get(logName);
	}

	/**
	 * for log4j ,the log level is info
	 * 
	 * @param str
	 */
	public void write(String str) {
		logger.info(str);
	}

	public void trace(Exception e) {
		logger.info(LogHelper.class, e);
	}

	public void trace(Exception e, String str) {
		logger.info(str);
		logger.info(LogHelper.class, e);
	}

	public static String getLogClass() {
		return "";
	}

	/**
	 * 輸出到控制檯
	 * 
	 * @param str
	 */
	public static void stdout(String str) {
		System.out.println(getLogDate() + getLogClass() + str);
	}

	public static void stderr(String str) {
		System.err.println(getLogDate() + getLogClass() + str);
	}

	public static void stderrTrace(Exception e) {
		System.err.println(getLogDate() + getLogClass() + e.toString());
		e.printStackTrace();
	}

	private static String getLogDate() {
		SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		return "[" + df.format(new Date()) + "] ";
	}

	public static void studioLog(String str) {
		log.info(str);
		getInstatnce("studioLog").logger.fatal(getLogClass() + str);
	}

	public static String locate(String esc) {
		StringWriter sw = new StringWriter();
		(new Exception()).printStackTrace(new PrintWriter(sw));
		StringTokenizer st = new StringTokenizer(sw.toString(), "\n");
		do {
			if (!st.hasMoreTokens()) {
				break;
			}
			String str = st.nextToken();
			if (str.indexOf("Exception") != -1 || str.indexOf((LogHelper != null ? LogHelper
					: (LogHelper = class$("com.ihandy.yuncai.studio.util.IhandyLogHelper"))).getName()) != -1 || esc != null && str
					.indexOf(esc) != -1) {
				continue;
			}
			if (esc == "!@*#~^?'/\"") {
				return str;
			}
			int i = str.indexOf(40);
			int j = str.indexOf(41);
			if (i != -1 && j != -1) {
				return str.substring(i, j + 1);
			}
			break;
		} while (true);
		return "";
	}

	protected static Class class$(String x1) {
		try {
			return Class.forName(x1);
		} catch (ClassNotFoundException x2) {
			throw new NoClassDefFoundError(x2.getMessage());
		}
	}

	public static void exceptionLog(Throwable t) {
		try {
			String str = getTrace(t);
			str = "\r\n>>>>>>>>>>>\r\n" + getLogDate() + "\r\n" + getLogClass() + str + "\r\n<<<<<<<<<";
			System.out.println(str);
			getInstatnce("exceptionLog").logger.fatal(str);
		} catch (Throwable e) {
			e.printStackTrace();
		}
	}

	public static void exceptionLog(String msg, Throwable t) {
		try {
			String str = getTrace(t);
			str = "\r\n>>>>>>>>>>>" + getLogDate() + "\r\n" + getLogClass() + "\r\n" + msg + "\r\n" + str + "\r\n<<<<<<<<<";
			System.out.println(str);
			getInstatnce("exceptionLog").logger.fatal(str);
		} catch (Throwable e) {
			e.printStackTrace();
		}
	}

	public static void exceptionLog(String description, String errorMsg) {
		try {
			String str = "\r\n>>>>>>>>>>>" + getLogDate() + "\r\n" + getLogClass() + "\r\n" + description + "\r\n" + errorMsg + "\r\n<<<<<<<<<";
			System.out.println(str);
			getInstatnce("exceptionLog").logger.fatal(str);
		} catch (Throwable e) {
			e.printStackTrace();
		}
	}

	public static void exceptionLog(String description) {
		exceptionLog(description, "");
	}

	public static String getTrace(Throwable t) {
		StringWriter stringWriter = new StringWriter();
		PrintWriter writer = new PrintWriter(stringWriter);
		t.printStackTrace(writer);
		StringBuffer buffer = stringWriter.getBuffer();
		return buffer.toString();
	 }

	/**
	 * 訪問日誌參數添加方法,參數需要以鍵值對的形式傳入
	 * 調用示例LogHelper.addAccessLogAttribute(request, "rechargeType", cardType, "rechargeAmount", amount.toString());
	 * @param request
	 * @param paramNames 參數及值對
	 */
	public static void addAccessLogAttribute(HttpServletRequest request, Object... paramNames) {
		if ((paramNames.length % 2) == 0) {
 			for (int i = 0; i < paramNames.length / 2; i++) {
				request.setAttribute(String.valueOf(paramNames[2 * i]), paramNames[2 * i + 1]);
			}
		} else {
			String msg = "向訪問日誌傳遞日誌參數不成對,屬性無法添加";
			exceptionLog(msg, new RuntimeException());
		}
	}

	/**
	 * 請求參數
	 * @return
	 */
	public static String requestParamsJson(HttpServletRequest req) {
		String paramsJson = "";
		Map<String, Object> map = new HashMap<String, Object>();
		Enumeration<String> paramNames = req.getParameterNames();
		while (paramNames.hasMoreElements()) {
			String paramName = paramNames.nextElement();
			//進行屏蔽,不記錄到日誌
			if (RegexUtil.validate("\\w*password\\w*", paramName)) {
				continue;
			}		
			//oios1.30需求中,屏蔽掉vip驗證和恢復接口的參數
			if ("jsondata".equals(paramName)) {
				continue;
			}		
			String paramValue = req.getParameter(paramName);
			//參數的值超過500個字節時做截斷
			if (paramValue.length() > 500) {
				 paramValue = paramValue.substring(0, 500);
			}
			map.put(paramName, paramValue);
		}
		if (map != null && map.size() > 0) {
			paramsJson = JSON.toJSONString(map);
			//對“][”日誌分割符進行轉碼成"]_["
			paramsJson = paramsJson.replaceAll("]\\[", "]_[");
		}
		return paramsJson;
	}

	/**
	 * 處理參數
	 * @param request
	 * @param paramNames
	 */
	public static void addProcessingParams(HttpServletRequest request, Object... paramNames) {
		Map<String, Object> map = new HashMap<String, Object>();
		if ((paramNames.length % 2) == 0) {
			for (int i = 0; i < paramNames.length / 2; i++) {
				map.put(String.valueOf(paramNames[2 * i]), paramNames[2 * i + 1]);
			}
		} else {
			String msg = "處理參數:向訪問日誌傳遞日誌參數不成對,屬性無法添加";
			exceptionLog(msg, new RuntimeException());
		}
		request.setAttribute("processingParams", JSON.toJSONString(map));
	}
}

接下來配置AOP-----------------------------------



(以下配置時注意路徑問題)

第一種配置方法:使用@AspectJ標籤

  1. 在配置文件中添加<aop:aspectj-autoproxy/>註解(注:SpringMVC的配置文件中完成,不要在spring的配置文件中完成
  2. 創建一個Java文件,使用@Aspect註解修飾該類(LogHandler)
  3. 創建一個方法,使用@Before、@After、@Around等進行修飾,在註解中寫上切入點的表達式(LogHandler中的方法)

說明:上述Java文件創建好後,需要將其在Spring的容器中進行聲明,可以在配置文件中定義<bean/>節點,也可以使用@Component組件進行修飾

1、在SpringMVC配置文件中添加AOP註解的相關配置信息

	<!--註解實現AOP切面 -->
 <!-- 啓動對@AspectJ註解的支持,通知spring使用cglib而不是jdk的來生成代理方法  -->
    <aop:aspectj-autoproxy expose-proxy="true"></aop:aspectj-autoproxy>
 <!--將Aspect類註冊爲Bean,@AfterReturning時需要使用此配置 -->
 <context:component-scan base-package="com.warehouse.util">
	<context:include-filter type="annotation" expression="org.aspectj.lang.annotation.Aspect"/>
     </context:component-scan>

注意:proxy-target-class屬性值決定是基於接口的還是基於類的代理被創建。如果proxy-target-class 屬性值被設置爲true,那麼基於類的代理將起作用(這時需要cglib庫)。如果proxy-target-class屬值被設置爲false或者這個屬性被省略,那麼標準的JDK 基於接口的代理將起作用。即使你未聲明 proxy-target-class="true" ,但運行類沒有繼承接口,spring也會自動使用CGLIB代理。高版本spring自動根據運行類選擇 JDK 或 CGLIB 代理

2、建一個文件進行相關的代理操作

package com.warehouse.controller.util;

import java.text.SimpleDateFormat;
import java.util.Date;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Component;
import com.warehouse.controller.api.log.LogHelper;

@Component	//註解實現AOP切面
@Aspect	//註解實現AOP切面
public class LogHandler {
	
	static{
		System.out.println("-----------已加載LogHandler-----------");//查看LogHandler是否加載
	}
	
    //方法執行的前調用 
	@Before("execution(* com.warehouse.controller.*.*.*(..))")	//註解實現AOP切面  
    public void doBeforeInServiceLayer(JoinPoint joinPoint) {  
    	SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        System.out.println(df.format(new Date())+"====================================@Before:doBeforeInServiceLayer====================================");
        StringBuilder sb = new StringBuilder();
		sb.append(df.format(new Date())+"====================================@Before:doBeforeInServiceLayer====================================");
		LogHelper.getInstatnce("inOutPutLog").write(sb.toString());
    }
	
    //方法執行的後調用 
	@After("execution(* com.warehouse.controller.*.*.*(..))")	//註解實現AOP切面  
    public void doAfterInServiceLayer(JoinPoint joinPoint) {  
    	SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        System.out.println(df.format(new Date())+"====================================@After:doAfterInServiceLayer====================================");
        StringBuilder sb = new StringBuilder();
		sb.append(df.format(new Date())+"====================================@After:doAfterInServiceLayer====================================");
		LogHelper.getInstatnce("inOutPutLog").write(sb.toString());
    }
	
    //方法執行的前後調用 
	@Around("execution(* com.warehouse.controller.*.*(..))")	//註解實現AOP切面
    public void doAround(ProceedingJoinPoint pjp) throws Throwable {  
    	SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		StringBuilder sb = new StringBuilder();
		sb.append(df.format(new Date())+"====================================@Around:doAround====================================");
		System.out.println(df.format(new Date())+"====================================@Around:doAround====================================");
		LogHelper.getInstatnce("inOutPutLog").write(sb.toString());
    }
    
    //方法運行出現異常時調用  
    @AfterThrowing(pointcut = "execution (* com.warehouse.controller.*.*(..))",throwing = "ex")	//註解實現AOP切面
    public void doAfterThrowing(Exception ex){  
    	System.out.println("====================================@AfterThrowing:doAfterThrowing====================================");
        System.out.println(ex);  
    }
	/**
	 * ControllerLayer
	 * 方法執行的後返回值
	 * @param joinPoint
	 * @param returnValue
	 */
	@AfterReturning(pointcut = "execution (* com.warehouse.controller.*.*.*(..))", returning = "returnValue")
	public void doAfterReturnInControllerLayer(JoinPoint joinPoint, Object returnValue) {
		if(logSwitch){
			SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
			StringBuilder stringBuilder = new StringBuilder();
			stringBuilder.append(df.format(new Date())+" INFO "+joinPoint.getTarget().getClass().getName()+":"+joinPoint.getSignature().getName()+" [Warehouse] - ");
			stringBuilder.append(returnValue);
			stringBuilder.append("\n");
//			System.out.println(stringBuilder.toString());
			LogHelper.getInstatnce("inOutPutLog").write(stringBuilder.toString());
		}
	}
	
    /**
     * ServiceLayer
     * 方法執行的前調用   
     * @param joinPoint
     */
	@Before("execution(* com.warehouse.service.impl.*.*(..))")
    public void doBeforeInServiceLayer(JoinPoint joinPoint) {  
		if(logSwitch){
			SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
			StringBuilder stringBuilder = new StringBuilder();
			stringBuilder.append(df.format(new Date())+" INFO "+joinPoint.getTarget().getClass().getName()+":"+joinPoint.getSignature().getName()+" [Warehouse] - ");
			for (int i = 0; i < joinPoint.getArgs().length; i++) {
				JSONObject data = new JSONObject();
				data.put("requestParameter", joinPoint.getArgs()[i]);
				stringBuilder.append(data); 
			}
			stringBuilder.append("\n");
			//System.out.println(stringBuilder.toString());
			LogHelper.getInstatnce("inOutPutLog").write(stringBuilder.toString());
		}
    }
	
	/**
	 * ServiceLayer
	 * 方法執行的後返回值   
	 * @param joinPoint
	 * @param returnValue
	 */
	@AfterReturning(pointcut = "execution (* com.warehouse.service.impl.*.*(..))", returning = "returnValue")
	public void doAfterReturnInServiceLayer(JoinPoint joinPoint, Object returnValue) {
		if(logSwitch){
			SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
			StringBuilder stringBuilder = new StringBuilder();
			stringBuilder.append(df.format(new Date())+" INFO "+joinPoint.getTarget().getClass().getName()+":"+joinPoint.getSignature().getName()+" [Warehouse] - ");
			JSONObject data = new JSONObject();
			data.put("returnValue", returnValue);
			stringBuilder.append(data); 
			stringBuilder.append("\n");
			//System.out.println(stringBuilder.toString());
			LogHelper.getInstatnce("inOutPutLog").write(stringBuilder.toString());
		}
	}

	/**
	 * ServiceLayer
	 * 方法執行的後調用  
	 * @param joinPoint
	 */
	@After("execution(* com.warehouse.service.impl.*.*(..))")
    public void doAfterInServiceLayer(JoinPoint joinPoint) {  
		if(logSwitch){
			SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
			//System.out.println(df.format(new Date())+" @After:doAfterInServiceLayer ");
			StringBuilder stringBuilder = new StringBuilder();
			stringBuilder.append(df.format(new Date())+" @After:doAfterInServiceLayer ");
			LogHelper.getInstatnce("inOutPutLog").write(stringBuilder.toString());
		}
    }

	/**
	 * Debug日誌
	 * @param className 類名稱
	 * @param funName 方法名稱
	 * @param content debug內容
	 */
    public void logRecordForDebug(String className, String funName, String content) {
		SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
		StringBuilder stringBuilder = new StringBuilder();
		stringBuilder.append(df.format(new Date())+" DEBUG "+className+":"+funName+" [Warehouse] - ");
		stringBuilder.append(content);  
		System.out.println(stringBuilder.toString());
		LogHelper.getInstatnce("inOutPutLog").write(stringBuilder.toString());
    }

}

第二種配置方法:基於配置文件的配置

  1. 創建一個Java文件,並指定一個用於執行攔截的方法(LogHandler)
  2. 在SpringMVC配置文件中註冊該Java類爲一個Bean
  3. 在SpringMVC使用<aop:config/>、<aop:aspect/>等標籤進行配置
1、建一個文件進行相關的代理操作

package com.warehouse.controller.util;

import java.text.SimpleDateFormat;
import java.util.Date;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import com.warehouse.controller.api.log.LogHelper;

public class LogHandler {
	
	static{
		System.out.println("-----------已加載LogHandler-----------");//查看LogHandler是否加載
	}
	
    //方法執行的前調用 
    public void doBeforeInServiceLayer(JoinPoint joinPoint) {  
    	SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        System.out.println(df.format(new Date())+"====================================@Before:doBeforeInServiceLayer====================================");
        StringBuilder sb = new StringBuilder();
		sb.append(df.format(new Date())+"====================================@Before:doBeforeInServiceLayer====================================");
		LogHelper.getInstatnce("inOutPutLog").write(sb.toString());
    }
	
    //方法執行的後調用 
    public void doAfterInServiceLayer(JoinPoint joinPoint) {  
    	SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        System.out.println(df.format(new Date())+"====================================@After:doAfterInServiceLayer====================================");
        StringBuilder sb = new StringBuilder();
		sb.append(df.format(new Date())+"====================================@After:doAfterInServiceLayer====================================");
		LogHelper.getInstatnce("inOutPutLog").write(sb.toString());
    }
	
    //方法執行的前後調用 
    public void doAround(ProceedingJoinPoint pjp) throws Throwable {  
    	SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		StringBuilder sb = new StringBuilder();
		sb.append(df.format(new Date())+"====================================@Around:doAround====================================");
		System.out.println(df.format(new Date())+"====================================@Around:doAround====================================");
		LogHelper.getInstatnce("inOutPutLog").write(sb.toString());
    }
    
    //方法運行出現異常時調用  
    public void doAfterThrowing(Exception ex){  
    	System.out.println("====================================@AfterThrowing:doAfterThrowing====================================");
        System.out.println(ex);  
    }
}
2、在SpringMVC配置文件中註冊該Java類爲一個Bean,使用<aop:config/>、<aop:aspect/>等標籤進行配置

	<!--配置文件實現AOP切面 -->
	<bean id="logHandler" class="com.warehouse.controller.util.LogHandler" />
	
	<aop:config>
            <aop:aspect id="addInOutPutLog" ref="logHandler">
                <aop:pointcut id="addAllMethod" expression="execution(* com.warehouse.controller.*.*.*(..))" />
                <aop:before method="doBeforeInServiceLayer" pointcut-ref="addAllMethod" />
                <aop:after method="doAfterInServiceLayer" pointcut-ref="addAllMethod" />
            </aop:aspect>
        </aop:config>


log4j MDC用戶操作日誌追蹤配置

http://blog.csdn.net/userwyh/article/details/52862216

 MDC(Mapped Diagnostic Context,映射調試上下文)是 log4j 和 logback 提供的一種方便在多線程條件下記錄日誌的功能。某些應用程序採用多線程的方式來處理多個用戶的請求。在一個用戶的使用過程中,可能有多個不同的線程來進行處理。典型的例子是 Web 應用服務器。當用戶訪問某個頁面時,應用服務器可能會創建一個新的線程來處理該請求,也可能從線程池中複用已有的線程。在一個用戶的會話存續期間,可能有多個線程處理過該用戶的請求。這使得比較難以區分不同用戶所對應的日誌。當需要追蹤某個用戶在系統中的相關日誌記錄時,就會變得很麻煩。

  一種解決的辦法是採用自定義的日誌格式,把用戶的信息採用某種方式編碼在日誌記錄中。這種方式的問題在於要求在每個使用日誌記錄器的類中,都可以訪問到用戶相關的信息。這樣纔可能在記錄日誌時使用。這樣的條件通常是比較難以滿足的。MDC 的作用是解決這個問題。

  MDC 可以看成是一個與當前線程綁定的哈希表,可以往其中添加鍵值對。MDC 中包含的內容可以被同一線程中執行的代碼所訪問。當前線程的子線程會繼承其父線程中的 MDC 的內容。當需要記錄日誌時,只需要從 MDC 中獲取所需的信息即可。MDC 的內容則由程序在適當的時候保存進去。對於一個 Web 應用來說,通常是在請求被處理的最開始保存這些數據。




發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章