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 应用来说,通常是在请求被处理的最开始保存这些数据。




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值