java操作日志实现

以下是基于springboot+springcloud实现的操作日志功能

第一步:定义日志注解SysLog

/**
 * 操作日志注解
 */
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface SysLog {

    /**
     * 日志描述
     */
    String desc() default "";
    
    /**
     * 日志操作类型
     */
    BusinessType businessType() default BusinessType.OTHER;

}

第二步:配置日志切面记录日志信息

/**
 * 操作日志切面
 */
@Slf4j
@Aspect
@Component
public class WebLogAspect {

    @Autowired
    private LogFeignClient logFeignClient;

    /**
     * 日志 切面 自定义注解  切到任意方法
     */
    @Pointcut("@annotation(com.yuguo.aspect.SysLog)")
    public void webLog() {

    }

    @Before("webLog()")
    public void doBefore(JoinPoint joinPoint) {
        log.info("dobefore...");
    }


    @AfterReturning(returning = "ret", pointcut = "webLog()")
    public void doAfterReturning(JoinPoint joinPoint, Object ret) throws Throwable {
        // 处理完请求,返回内容
        log.info("doAfter save log ...");
        try {
            //获取请求数据
            Map<String, Object> logMap = getLogData(joinPoint);
            logFeignClient.saveLog(logMap);
        } catch (Exception e) {
            log.error("##########[WebLogAspect]catch exception, save log error!###########" + e.getMessage());
        }
    }


    //获取请求数据
    private Map<String, Object> getLogData(JoinPoint joinPoint) {
        Map<String, Object> logMap = new HashMap<String, Object>();
        try {
            ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder
                    .getRequestAttributes();
            HttpServletRequest request = attributes.getRequest();
            //日志描述  日志类型
            String methodName = joinPoint.getSignature().getName();
            Method method = currentMethod(joinPoint, methodName);
            SysLog sysLog = method.getAnnotation(SysLog.class);
            String eventDesc = sysLog.desc();
            BusinessType bType = sysLog.businessType();
            String eventType = BusinessType.getMsg(bType);
            logMap.put("eventDesc", eventDesc);
            logMap.put("eventType", eventType);
            // 请求地址
            String requestUrl = request.getRequestURL().toString();
            logMap.put("requestUrl", requestUrl);
            //客户端地址
            //String requestIp = request.getRemoteAddr();
            String clientIp = getClientIp (request);
            logMap.put("requestIp", clientIp);
            //操作者
            String operator = request.getRemoteUser();
            logMap.put("operator", operator);
            //请求参数
            String requestParam = null;
            Enumeration<String> enu = request.getParameterNames();
            while (enu.hasMoreElements()) {
                String name = (String) enu.nextElement();
                requestParam = requestParam + name + ":" + request.getParameter(name) + ",";
                log.info("name【请求参数名】:{},value【请求参数值】:{}", name, request.getParameter(name));
            }
            //如果为空,就从请求体里面去获取
            if (StringUtils.isBlank(requestParam)) {
                log.info("requestParam:" + requestParam + ",再从请求体中获取");
                Object[] objects = joinPoint.getArgs();
                requestParam = JSONObject.toJSONString(objects);
            }
            log.info("REQUEST_PARAM【请求参数】 : " + requestParam);
            logMap.put("requestParam", requestParam);
            // 测试另一种获取请求参数的方式:
    		String paramData = JSON.toJSONString(request.getParameterMap(),
    				SerializerFeature.DisableCircularReferenceDetect, SerializerFeature.WriteMapNullValue);
    		log.info("######测试得到的requestParam:"+paramData+"######");
        } catch (Exception e) {
            log.error("####[WebLogAspect]catch exception, getLogData log error! 组装数据错误 #####" + e.getMessage());
        }
        return logMap;
    }

    private Method currentMethod(JoinPoint joinPoint, String methodName) {
        Method[] methods = joinPoint.getTarget().getClass().getMethods();
        Method resultMethod = null;
        for (Method method : methods) {
            if (method.getName().equals(methodName)) {
                resultMethod = method;
                break;
            }
        }
        return resultMethod;
    }
    
    /**
     * 获取客户端ip地址
     * @param request
     * @return
     */
    public static String getClientIp(HttpServletRequest request)
    {
        String ip = request.getHeader("x-forwarded-for");
        if (ip == null || ip.trim() == "" || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("Proxy-Client-IP");
        }
        if (ip == null || ip.trim() == "" || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("WL-Proxy-Client-IP");
        }
        if (ip == null || ip.trim() == "" || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getRemoteAddr();
        }
        // 多个路由时,取第一个非unknown的ip
        final String[] arr = ip.split(",");
        for (final String str : arr) {
            if (!"unknown".equalsIgnoreCase(str)) {
                ip = str;
                break;
            }
        }
        return ip;
    }

}

第三步:定义功能类型BusinessType

/**
 * 日志操作类型
 */
public enum BusinessType
{
    /**
     * 其它
     */
    OTHER,
    /**
     * 新增
     */
    INSERT,
    /**
     * 修改
     */
    UPDATE,
    /**
     * 删除
     */
    DELETE,
    /**
     * 查询
     */
    SELECT,
    /**
     * 导出
     */
    EXPORT,
    /**
     * 导入
     */
    IMPORT;

    public static String getMsg(BusinessType type){
    	String result = null;
        switch (type) {
		case INSERT:
			result = "新增";
			break;
		case UPDATE:
			result = "修改";
			break;
		case DELETE:
			result = "删除";
			break;
		case SELECT:
			result = "查询";
			break;
		case EXPORT:
			result = "导出";
			break;
		case IMPORT:
			result = "导入";
			break;
		case OTHER:
			result = "其它";
			break;
		default:
			break;
		}
        return result;
    }
}

第四步:方法上添加日志注解@SysLog()

	@PostMapping
	@SysLog(desc = "新增用户", businessType = BusinessType.INSERT)
	public Result add(User user){
		...
    }
  • 3
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值