文章目录
1、maven依赖:
<!--服务的注册中心-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<!--服务的配置中心 1 currentServerAddr:http://localhost:8848, err : connect timed out-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
<!-- 服务的熔断和降级限流-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>
<!--资源服务器-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-oauth2</artifactId>
</dependency>
<!--远程调用-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<!--mybatis-plus-->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
</dependency>
<!--mysql 驱动-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<!--redis 操作-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<!--jetcache 缓存-->
<dependency>
<groupId>com.alicp.jetcache</groupId>
<artifactId>jetcache-starter-redis</artifactId>
</dependency>
<!--spring 里面添加的一些工具类-->
<dependency>
<groupId>io.springside</groupId>
<artifactId>springside-utils</artifactId>
</dependency>
<!--swagger2-->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
</dependency>
<!--swagger2的web界面-->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
</dependency>
<!--web-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--hutool工具类-->
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
</dependency>
<!--mapStruct依赖 高性能对象映射-->
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct-jdk8</artifactId>
</dependency>
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct-processor</artifactId>
</dependency>
<!--配置文件处理-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
</dependency>
<dependency>
<groupId>joda-time</groupId>
<artifactId>joda-time</artifactId>
</dependency>
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
</dependency>
2、代码:
package com.zhz.aspect;
import cn.hutool.core.util.StrUtil;
import cn.hutool.core.util.URLUtil;
import com.alibaba.fastjson.JSON;
import com.zhz.model.WebLog;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
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.core.LocalVariableTableParameterNameDiscoverer;
import org.springframework.core.annotation.Order;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;
/**
* @author :zhz
* @date :Created in 2020/12/20
* @version: V1.0
* @slogan: 天下风云出我辈,一入代码岁月催
* @description: 日志切面
**/
@Component
@Aspect
@Order(1)
@Slf4j
public class WebLogAspect {
/**
* 日志记录:
* 环绕通知:方法执行之前、之后
*/
/**
* 1 定义切入点
*/
@Pointcut("execution(* com.zhz.controller.*.*(..))") // controller 包里面所有类,类里面的所有方法 都有该切面
public void webLog() {
}
/**
* 2、 记录日志的环绕通知
*/
@Around("webLog()")
public Object recodeWebLog(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
Object result = null;
WebLog webLog = new WebLog();
long start = System.currentTimeMillis();
// 执行方法的真实调用
result = proceedingJoinPoint.proceed(proceedingJoinPoint.getArgs());
long end = System.currentTimeMillis();
webLog.setSpendTime((int) (start - end) / 1000); // 请求该接口花费的时间
// 获取当前请求的request对象
ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
HttpServletRequest request = requestAttributes.getRequest();
// 获取安全的上下文
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
String url = request.getRequestURL().toString();
webLog.setUri(request.getRequestURI()); // 设置请求的uri
webLog.setUrl(url);
webLog.setBasePath(StrUtil.removeSuffix(url, URLUtil.url(url).getPath())); // http://ip:port/
webLog.setUsername(authentication == null ? "anonymous" : authentication.getPrincipal().toString()); // 获取用户的id
webLog.setIp(request.getRemoteAddr()); // TODO 获取ip 地址
// 获取方法
MethodSignature signature = (MethodSignature) proceedingJoinPoint.getSignature();
// 获取类的名称
String targetClassName = proceedingJoinPoint.getTarget().getClass().getName();
Method method = signature.getMethod();
// 因为我们会使用Swagger 这工具,我们必须在方法上面添加@ApiOperation(value="")该注解
// 获取ApiOperation
ApiOperation annotation = method.getAnnotation(ApiOperation.class);
webLog.setDescription(annotation == null ? "no desc" : annotation.value());
webLog.setMethod(targetClassName + "." + method.getName()); // com.zhz.controller.UserController.login()
webLog.setParameter(getMethodParameter(method, proceedingJoinPoint.getArgs())); //{"key_参数的名称":"value_参数的值"}
webLog.setResult(result);
log.info(JSON.toJSONString(webLog, true));
return result;
}
/**
* 获取方法的执行参数
*
* @param method
* @param args
* @return {"key_参数的名称":"value_参数的值"}
*/
private Object getMethodParameter(Method method, Object[] args) {
Map<String, Object> methodParametersWithValues = new HashMap<>();
LocalVariableTableParameterNameDiscoverer localVariableTableParameterNameDiscoverer =
new LocalVariableTableParameterNameDiscoverer();
// 方法的形参名称
String[] parameterNames = localVariableTableParameterNameDiscoverer.getParameterNames(method);
for (int i = 0; i < parameterNames.length; i++) {
if (parameterNames[i].equals("password") || parameterNames[i].equals("file")) {
methodParametersWithValues.put(parameterNames[i], "受限的支持类型");
} else {
methodParametersWithValues.put(parameterNames[i], args[i]);
}
}
return methodParametersWithValues;
}
}