记录系统日志
- 1.日志上下文
本地线程上下文,用来存储在同一个线程中可能会用到的全局变量
/**
* 日志实体
*/
private MgSysLog logger = new MgSysLog();
/**
* 线程本地内存中的变量
*/
private static ThreadLocal<SystemContext> threadLocal =new ThreadLocal<>();
public static SystemContext get(){
if(threadLocal.get() == null){
SystemContext threadLocalContext = new SystemContext();
threadLocal.set(threadLocalContext);
}
return threadLocal.get();
}
public void remove(){
threadLocal.remove();
}
@Aspect
@Component
@Slf4j
public class RequestAspect {
@Autowired
private SysLogService sysLogService;
/**
* 声明切点
*/
@Pointcut("execution( * com.hl.crm.controller..*(..))")
public void logPointCut(){
}
/**
* 前置通知
* @param joinPoint
* @throws Exception
*/
@Before("logPointCut()")
public void doBefore(JoinPoint joinPoint) throws Exception {
// 接收到请求,记录请求内容
ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
assert attributes != null;
// 获取request
HttpServletRequest request = attributes.getRequest();
// 获取请求地址
String uri = request.getRequestURI();
// 记录日志
// 日志输出基本信息
log.info("请求地址:{}", uri);
log.info("请求方式:{}", request.getMethod());
// 获取请求IP
String remoteIp = StringUtils.getRemoteIp(request);
log.info("IP:{}", remoteIp);
// 获取请求的controller
String controllerName = joinPoint.getSignature().getDeclaringTypeName();
log.info("方法:{}.{}", controllerName, joinPoint.getSignature().getName());
// 记录参数
Object[] args = joinPoint.getArgs();
// 记录日志条件:参数不为空,并且第一个参数不是request也不是MultipartFile
boolean logParamFlag = args != null && args.length > 0 && !(args[0] instanceof ServletRequest) && !(args[0] instanceof MultipartFile);
MgSysLog sysLog = SystemContext.get().getLogger();
if (logParamFlag) {
String param = JSON.toJSONString(args);
log.info("请求参数:{}", param);
sysLog.setLogParams(param);
}
// 记录日志
sysLog.setLogUrl(uri);
sysLog.setLogStatus(ResultCode.REQUEST_SUCCESS.getCode());
sysLog.setLogMethod(request.getMethod());
sysLog.setLogIp(remoteIp);
sysLog.setLogUa(request.getHeader("user-Agent"));
sysLog.setLogController(controllerName);
}
/**
* 环绕通知
*
* @param pjp
* @return
* @throws Throwable
*/
@Around("logPointCut()")
public Object doAround(ProceedingJoinPoint pjp) throws Throwable {
// 记录方法执行时间
long startTime = System.currentTimeMillis();
Object ob = pjp.proceed();
long time = System.currentTimeMillis() - startTime;
log.info("方法执行耗时:{}", time);
MgSysLog sysLog = SystemContext.get().getLogger();
sysLog.setLogTime(time);
String result = JSON.toJSONString(ob);
log.info("返回值:{}", result);
sysLog.setLogResult(result);
sysLogService.save(sysLog);
SystemContext.get().remove();
return ob;
}
/**
* 异常通知,发生异常走这里
*
* @param joinPoint
* @param throwable
*/
@AfterThrowing(pointcut = "logPointCut()", throwing = "throwable")
public void doException(JoinPoint joinPoint, Throwable throwable) {
MgSysLog sysLog = SystemContext.get().getLogger();
sysLog.setLogStatus(ResultCode.REQUEST_ERROR.getCode());
sysLog.setLogMessage(throwable.getMessage());
sysLog.setLogTime(0L);
sysLogService.save(sysLog);
SystemContext.get().remove();
}
}
/**
* 获得用户远程地址
*/
public static String getRemoteIp(HttpServletRequest request) {
String remoteAddr = request.getRemoteAddr();
String remoteIp = request.getHeader("X-Forwarded-For");
if (isBlank(remoteIp) || LOCAL_HOST_IP.equals(remoteIp)) {
remoteIp = request.getHeader("X-Real-IP");
}
if (isBlank(remoteIp) || LOCAL_HOST_IP.equals(remoteIp)) {
remoteIp = request.getHeader("Proxy-Client-IP");
}
if (isBlank(remoteIp) || LOCAL_HOST_IP.equals(remoteIp)) {
remoteIp = request.getHeader("WL-Proxy-Client-IP");
}
String ip = remoteIp != null ? remoteIp : remoteAddr;
int pos = ip.indexOf(',');
if (pos >= 0) {
ip = ip.substring(0, pos);
}
return ip;
}
- 4.日志信息
到此,系统日志信息就完成了,现在的日志是存到数据库的,可以把日志信息存到非关系型数据库。
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/262766350521bf2cbfc826dba7bf91b5.png)