日志切面

import com.alibaba.fastjson.JSON;
import com.google.common.base.Strings;
import com.ziku.mall.entity.MallSysLogWithBLOBs;
import com.ziku.mall.enums.ErrorCodeEnum;
import com.ziku.mall.exception.BizException;
import com.ziku.mall.interceptor.UncheckAuth;
import com.ziku.mall.model.user.UserResult;
import com.ziku.mall.util.ProjectUtil;
import com.ziku.mall.util.SpringContextUtil;
import com.ziku.msb.common.base.BusinessException;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.exception.ExceptionUtils;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.util.StopWatch;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.lang.annotation.Annotation;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * @Description:
 * @Author: wangxuqiang
 * @Date: Created in 2018/9/27
 * @Version: 1.0
 */
@Aspect
@Slf4j
@Component
public class LogAspect {

    @Autowired
    private LogService logService;

    @Pointcut("execution(* com.ziku.mall.service..*.*Impl.add*(..)) ||" +
            "execution(* com.ziku.mall.service..*.*Impl.insert*(..)) ||" +
            "execution(* com.ziku.mall.service..*.*Impl.save*(..))")
    public void saveCell() {}

    @Pointcut("execution(* com.ziku.mall.service..*.*Impl.update*(..)) &&" +
            "!execution(* com.ziku.mall.service..*.*Impl.updateOrder(..)) ||" +
            "execution(* com.ziku.mall.service..*.*Impl.edit*(..)) ||" +
            "execution(* com.ziku.mall.service..*.*Impl.send*(..)) ||" +
            "execution(* com.ziku.mall.service..*.*Impl.pay*(..))")
    public void updateCell() {}

    @Pointcut("execution(* com.ziku.mall.service..*.*Impl.delete*(..)) ||" +
            "execution(* com.ziku.mall.service..*.*Impl.cancel*(..)) &&" +
            "!execution(* com.ziku.mall.service..*.*Impl.cancelCoupon(..))")
    public void deleteCell() {}

    @Around("saveCell()")
    public Object saveLog(final ProceedingJoinPoint joinPoint) throws Throwable {
        return doLog(joinPoint);
    }

    @Around("updateCell()")
    public Object updateLog(final ProceedingJoinPoint joinPoint) throws Throwable {
        return doLog(joinPoint);
    }

    @Around("deleteCell()")
    public Object deleteLog(final ProceedingJoinPoint joinPoint) throws Throwable {
        return doLog(joinPoint);
    }


    private Object doLog(final ProceedingJoinPoint joinPoint) throws Throwable {
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.currentRequestAttributes()).getRequest();
        MallSysLogWithBLOBs sysLog=new MallSysLogWithBLOBs();
        String errorStr="";
        try {
            sysLog.setGmtCreate(new Date());
            sysLog.setIp(getIP(request));
            sysLog.setMethod(getMethod(joinPoint));
            sysLog.setParams(getParams(joinPoint));
            sysLog.setResponseResult("SUCCESS");
            sysLog.setOperation(getOperation(request));
            sysLog.setUserId(getUserId(request,joinPoint));
        } catch (Exception e) {
            if (log.isErrorEnabled()) {
                log.error("[小程序]日志信息转换异常:{}",ExceptionUtils.getStackTrace(e));
            }
            errorStr=errorMsg(e);
            sysLog.setResponseResult(errorStr);
        }

        StopWatch sw = new StopWatch(System.currentTimeMillis()+""+Math.random());
        sw.start();
        Object object=null;
        try {
            object=joinPoint.proceed();
        } catch (Throwable throwable) {
            if (log.isErrorEnabled()) {
                log.error("[小程序]日志方法执行异常:{}",ExceptionUtils.getStackTrace(throwable));
            }
            errorStr=errorStr+" --- "+errorMsg(throwable);
            sysLog.setResponseResult(errorStr);
            if (throwable instanceof BizException) {
                sw.stop();
                sysLog.setResponseTime(sw.getTotalTimeMillis());
                sysLog.setResponseResult(errorStr);
                logService.asyncSaveSysLog(sysLog);
                throw throwable;
            }
        }
        sw.stop();

        sysLog.setResponseTime(sw.getTotalTimeMillis());

        logService.asyncSaveSysLog(sysLog);

        return object;
    }

    private String getIP(HttpServletRequest request){
        return ProjectUtil.getRemoteHost(request);
    }

    private String getOperation(HttpServletRequest request) {
        String url=request.getRequestURL().toString();
        return String.format("[小程序]请求路径:%s;HTTP_METHOD:%s",url,request.getMethod());
    }

    private String getMethod(ProceedingJoinPoint joinPoint) {
        return joinPoint.getSignature().getDeclaringTypeName() + "." + joinPoint.getSignature().getName();
    }

    private String getParams(final ProceedingJoinPoint joinPoint) {
        Object[] args = joinPoint.getArgs();
        Signature signature = joinPoint.getSignature();
        MethodSignature methodSignature = (MethodSignature) signature;
        String[] strings = methodSignature.getParameterNames();

        Map<Object,Object> map=new HashMap();
        String param = null;
        if(args!=null&& args.length>0 ){
            if (strings != null) {
                for (int i = 0; i < strings.length; i++) {
                    if (strings[i]!=null&&args[i]!=null) {
                        map.put(strings[i], args[i]);
                    }
                }
                param = JSON.toJSONString(map);
            } else {
                param = JSON.toJSONString(args);
            }
        }
        return param;
    }

    private String getUserId(HttpServletRequest request,ProceedingJoinPoint joinPoint){
        Signature signature = joinPoint.getSignature();
        MethodSignature methodSignature = (MethodSignature) signature;
        // RequiresAuthentication 注解的方法需要用户登录认证
        Annotation an = methodSignature.getMethod().getAnnotation(UncheckAuth.class);

        UserResult member = getCacheUser(request.getHeader("token"));

        if (an == null) {
            if (member == null) {
                throw new BusinessException(ErrorCodeEnum.USER_TOKEN_EXPIRE.getErrorCode(),ErrorCodeEnum.USER_TOKEN_EXPIRE.getErrorMsg());
            }
        }

        return member != null ? String.valueOf(member.getUserId()) : null;
    }

    private UserResult getCacheUser(String token) {

        UserResult userInfo = null;

        if (Strings.isNullOrEmpty(token)) {

            return null;
        }

        StringRedisTemplate redisTemplate = (StringRedisTemplate) SpringContextUtil.getBean("stringRedisTemplate");

        String userId = redisTemplate.opsForValue().get("JWT_TOKEN:" + token);

        if (Strings.isNullOrEmpty(userId)) {

            return null;
        }
        String userJson = redisTemplate.opsForValue().get("USER-ID:" + userId);

        if (Strings.isNullOrEmpty(userJson)) {

            return null;
        }

        userInfo = JSON.parseObject(userJson, UserResult.class);

        return userInfo;

    }


    private String errorMsg(Exception e) {
        return String.format("转换异常信息:%s --- %s",e.toString(),e.getStackTrace()[0]);
    }

    private String errorMsg(Throwable e) {
        return String.format("执行方法异常信息:%s --- %s",e.toString(),e.getStackTrace()[0]);
    }
}

 

package com.ziku.mall.aspect;

import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.*;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;
import org.springframework.validation.BindingResult;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;

/**
 * @Description:
 * @Author: wangxuqiang
 * @Date: Created in 2018/12/18
 * @Version: 1.0
 */
@Aspect
@Slf4j
@Component
public class LogConsole {
    private static final String START_TIME = "request-start";

    /**
     * 切入点
     */
    @Pointcut("execution(public * com.ziku.mall.web.*Controller.*(..))")
    public void log() {

    }

    /**
     * 前置操作
     *
     * @param point 切入点
     */
    @Before("log()")
    public void beforeLog(JoinPoint point) {
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();

        HttpServletRequest request = Objects.requireNonNull(attributes).getRequest();

        log.info("【请求 URL】:{}\n【请求 IP】:{}\n【请求类名】:{},【请求方法名】:{}\n【请求参数】:{},", request.getRequestURL(),
                request.getRemoteAddr(),point.getSignature().getDeclaringTypeName(), point.getSignature().getName(),
                getParams(point));
        //log.info("【请求 IP】:{}", request.getRemoteAddr());
        //log.info("【请求类名】:{},【请求方法名】:{}", point.getSignature().getDeclaringTypeName(), point.getSignature().getName());
        //log.info("【请求参数】:{},", getParams(point));
        Long start = System.currentTimeMillis();
        request.setAttribute(START_TIME, start);
    }

    /**
     * 环绕操作
     *
     * @param point 切入点
     * @return 原方法返回值
     * @throws Throwable 异常信息
     */
    @Around("log()")
    public Object aroundLog(ProceedingJoinPoint point) throws Throwable {
        Object result = point.proceed();
        log.info("【返回值】:{}", JSON.toJSONString((result)));
        return result;
    }

    /**
     * 后置操作
     */
    @AfterReturning("log()")
    public void afterReturning() {
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = Objects.requireNonNull(attributes).getRequest();

        Long start = (Long) request.getAttribute(START_TIME);
        Long end = System.currentTimeMillis();
        log.info("【请求耗时】:{}毫秒", end - start);
    }

    private String getParams(final JoinPoint joinPoint) {
        String param = null;
        try {
            Object[] args = joinPoint.getArgs();
            Signature signature = joinPoint.getSignature();
            MethodSignature methodSignature = (MethodSignature) signature;
            String[] strings = methodSignature.getParameterNames();

            Map<Object,Object> map=new HashMap();
            param = null;
            if(args!=null&& args.length>0 ){
                if (strings != null) {
                    for (int i = 0; i < strings.length; i++) {
                        if (args[i] instanceof ServletRequest || args[i] instanceof ServletResponse || args[i] instanceof MultipartFile ||
                                args[i] instanceof BindingResult) {
                            //ServletRequest不能序列化,从入参里排除,否则报异常:java.lang.IllegalStateException: It is illegal to call this method if the current request is not in asynchronous mode (i.e. isAsyncStarted() returns false)
                            //ServletResponse不能序列化 从入参里排除,否则报异常:java.lang.IllegalStateException: getOutputStream() has already been called for this response
                            continue;
                        }
                        if (strings[i]!=null&&args[i]!=null) {
                            map.put(strings[i], args[i]);
                        }
                    }
                    param = JSON.toJSONString(map);
                } else {
                    param = JSON.toJSONString(args);
                }
            }
        } catch (Exception e) {
            log.info("参数无法序列化为JSON");
            return "参数无法序列化为JSON";
        }
        return param;
    }
}

 

package com.ziku.mall.aspect;

import com.ziku.mall.entity.MallSysLogWithBLOBs;
import com.ziku.mall.mapper.MallSysLogMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;

/**
 * @Description:
 * @Author: wangxuqiang
 * @Date: Created in 2018/9/29
 * @Version: 1.0
 */
@Slf4j
@Component
public class LogService {

    @Autowired
    private MallSysLogMapper mallSysLogMapper;

    @Async
    public void asyncSaveSysLog(MallSysLogWithBLOBs sysLog) {
        try {
            mallSysLogMapper.insertSelective(sysLog);
        } catch (Exception e) {
            log.error("[小程序]日志保存失败:{}",e.getMessage());
        }
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值