spring Aop 日誌

1.Mavenjava

<dependency>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-aop</artifactId>
	</dependency>

 

2.java代碼web

package cn.no7player.aspect;

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**  
 * 自定義註解 攔截service 方法名稱描述 
 * @date   2016年10月13日 
 */  
@Target({ElementType.PARAMETER, ElementType.METHOD})    
@Retention(RetentionPolicy.RUNTIME)    
@Documented
public @interface  SystemServiceLog {
    String description()  default "";   
}

 

3.切面WebLogAspectspring

package cn.no7player.aspect;

import java.io.PrintWriter;
import java.io.StringWriter;
import java.lang.reflect.Method;
import java.util.Arrays;

import javax.servlet.http.HttpServletRequest;

import org.apache.log4j.Logger;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

@Aspect
@Component
public class WebLogAspect {

    private Logger logger = Logger.getLogger(getClass());

    
    //第一個*表示全部的返回類型
    //包名:表示須要攔截的包名,後面的兩個句點表示當前包和當前包的全部子包
    //第二個*號:表示類名,*號表示全部的類
    //*(..):最後這個星號表示方法名,*號表示全部的方法,後面括弧裏面表示方法的參數,兩個句點表示任何參數
    
    @Pointcut("execution(* cn.no7player.controller..*.*(..))")
    public void webLog() {}

    /**
     * 
     * 說明: Before 在覈心業務執行前執行,不能阻止核心業務的調用。
     * @param joinPoint
     * @throws Throwable
     * @author 胥攀
     * @time:2016年10月13日 下午2:50:30
     */
    @Before("webLog()")
    public void doBefore(JoinPoint joinPoint) throws Throwable {
        // 接收到請求,記錄請求內容
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = attributes.getRequest();
        // 記錄下請求內容
        logger.info("URL : " + request.getRequestURL().toString());
        logger.info("HTTP_METHOD : " + request.getMethod());
        logger.info("IP : " + request.getRemoteAddr());
        logger.info("CLASS_METHOD : " + joinPoint.getSignature().getDeclaringTypeName() + "." + joinPoint.getSignature().getName());
        logger.info("ARGS : " + Arrays.toString(joinPoint.getArgs()));
    }

    /**
     * 
     * 說明:After 核心業務邏輯退出後(包括正常執行結束和異常退出),執行此Advice 
     * @param ret
     * @throws Throwable
     * @author 胥攀
     * @time:2016年10月13日 下午2:51:09
     */
    @AfterReturning(returning = "ret", pointcut = "webLog()")
    public void doAfterReturning(Object ret) throws Throwable {
        // 處理完請求,返回內容
        logger.info("RESPONSE : " + ret);
    }

    /**
     * 
     * 說明:異常處理
     * @param joinPoint
     * @param e
     * @throws ClassNotFoundException
     * @author 胥攀
     * @time:2016年10月13日 下午3:27:52
     */
    @AfterThrowing(value = "webLog()", throwing = "e") 
    public void afterThrowing(JoinPoint joinPoint, Throwable e) throws ClassNotFoundException {  
        String des = getServiceMthodDescription(joinPoint);  
        Logger log = Logger.getLogger(joinPoint.getTarget().getClass());  
        log.error("-------------------afterThrowing.handler.start-------------------");  
        if(!des.equals("")){  
            log.error("方法描述:" + des);  
        }  
        log.error(getMethodNameAndArgs(joinPoint));  
        log.error("ConstantUtil.getTrace(e): " + getTrace(e));  
  
        log.error("異常名稱:" + e.getClass().toString());  
        log.error("e.getMessage():" + e.getMessage());  
        log.error("-------------------afterThrowing.handler.end-------------------");
    }
    
    /** 
     * 將異常信息輸出到log文件 
     * @param t 
     * @return 
     */  
    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();      
    } 
    
    
    /** 
     * 獲取方法名和參數 
     * @param joinPoint 
     * @return 
     */  
    private String getMethodNameAndArgs(JoinPoint joinPoint){  
        Object[] args = joinPoint.getArgs();  
        StringBuffer sb = new StringBuffer("請求方法:");  
        sb.append(joinPoint.getTarget().getClass().getName() + "."  
                + joinPoint.getSignature().getName() + "(");  
        for (int i = 0; i < args.length; i++) {  
            sb.append("arg[" + i + "]: " + args[i] + ",");  
        }  
        if (args.length > 0) {  
            sb.deleteCharAt(sb.length() - 1);  
        }  
        sb.append(")");  
        return sb.toString();  
    }  
    
    /** 
     * 獲取註解中對方法的描述信息 用於service層註解 
     * @param joinPoint 
     * @return 
     * @throws ClassNotFoundException 
     */  
    public static String getServiceMthodDescription(JoinPoint joinPoint)  
            throws ClassNotFoundException {  
        String targetName = joinPoint.getTarget().getClass().getName();  
        String methodName = joinPoint.getSignature().getName();  
        Object[] arguments = joinPoint.getArgs();  
        Class targetClass = Class.forName(targetName);  
        Method[] methods = targetClass.getMethods();  
        String description = "";  
        for (Method method : methods) {  
            if (method.getName().equals(methodName) && method.isAnnotationPresent(SystemServiceLog.class)) {  
                SystemServiceLog serviceLog = method.getAnnotation(SystemServiceLog.class);  
                description =serviceLog.description();  
                break;  
            }  
        }  
        return description;  
    }  
    
}

 

 

日誌信息apache

[ INFO ] [2016-10-13 15:29:15] org.apache.catalina.core.ContainerBase.[Tomcat].[localhost].[/] [180] - Initializing Spring FrameworkServlet 'dispatcherServlet'
[ INFO ] [2016-10-13 15:29:15] org.springframework.web.servlet.DispatcherServlet [487] - FrameworkServlet 'dispatcherServlet': initialization started
[ INFO ] [2016-10-13 15:29:15] org.springframework.web.servlet.DispatcherServlet [506] - FrameworkServlet 'dispatcherServlet': initialization completed in 13 ms
[ INFO ] [2016-10-13 15:29:15] cn.no7player.aspect.WebLogAspect [50] - URL : http://localhost:7010/hello
[ INFO ] [2016-10-13 15:29:15] cn.no7player.aspect.WebLogAspect [51] - HTTP_METHOD : GET
[ INFO ] [2016-10-13 15:29:15] cn.no7player.aspect.WebLogAspect [52] - IP : 0:0:0:0:0:0:0:1
[ INFO ] [2016-10-13 15:29:15] cn.no7player.aspect.WebLogAspect [53] - CLASS_METHOD : cn.no7player.controller.HelloController.hello
[ INFO ] [2016-10-13 15:29:15] cn.no7player.aspect.WebLogAspect [54] - ARGS : [123]
[ ERROR] [2016-10-13 15:29:15] cn.no7player.controller.HelloController [84] - -------------------afterThrowing.handler.start-------------------
[ ERROR] [2016-10-13 15:29:15] cn.no7player.controller.HelloController [86] - 方法描述:hello 方法
[ ERROR] [2016-10-13 15:29:15] cn.no7player.controller.HelloController [88] - 請求方法:cn.no7player.controller.HelloController.hello(arg[0]: 123)
[ ERROR] [2016-10-13 15:29:15] cn.no7player.controller.HelloController [89] - ConstantUtil.getTrace(e): java.lang.ArithmeticException: / by zero
	at cn.no7player.controller.HelloController.hello(HelloController.java:18)
	at cn.no7player.controller.HelloController$$FastClassBySpringCGLIB$$8fb34a96.invoke(<generated>)
	at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204)
	at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:717)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157)
相關文章
相關標籤/搜索