首页 > 其他分享 >论项目中日志处理的正确操作(springboot案例)

论项目中日志处理的正确操作(springboot案例)

时间:2022-11-30 15:38:42浏览次数:43  
标签:lang springboot sysLog 案例 import org 日志 com annotation


理论和日志的重要不需要重复,各位都明白,企业中甩锅  查询记录   必要的东西,直接贴上代码案例 

maven

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jdbc</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>


<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.31</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>

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


<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.4.4</version>
</dependency>

<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>1.1.1</version>
</dependency>

logback的配置文件(按天存储日志文件)

<?xml version="1.0" encoding="UTF-8"?>
<configuration scan="true" scanPeriod="60 seconds" debug="false">
<contextName>logback</contextName>
<!--输出到控制台-->
<appender name="console" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%d{HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n</pattern>
</encoder>
</appender>

<!--按天生成日志-->
<appender name="logFile" class="ch.qos.logback.core.rolling.RollingFileAppender">
<Prudent>true</Prudent>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<FileNamePattern>
applog/%d{yyyy-MM-dd}/%d{yyyy-MM-dd}.log
</FileNamePattern>
</rollingPolicy>
<layout class="ch.qos.logback.classic.PatternLayout">
<Pattern>
%d{yyyy-MM-dd HH:mm:ss} -%msg%n
</Pattern>
</layout>
</appender>

<logger name="com.bootdo" additivity="false">
<appender-ref ref="console"/>
<appender-ref ref="logFile" />
</logger>

<root level="error">
<appender-ref ref="console"/>
<appender-ref ref="logFile" />
</root>

</configuration>

自定义日志注解类

package com.hw.common;

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

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Log {
String value() default "";
}

用于将日志保存至数据库的配置类

package com.hw.common;


import com.hw.doman.LogDO;
import com.hw.doman.UserDO;
import com.hw.service.LogService;
import com.hw.util.HttpContextUtils;
import com.hw.util.IPUtils;
import com.hw.util.JSONUtils;
import com.hw.util.ShiroUtils;

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.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;
import java.util.Date;

import javax.servlet.http.HttpServletRequest;

@Aspect
@Component
public class LogAspect {
@Autowired
LogService logService;


@Pointcut("@annotation(com.hw.common.Log)")
public void logPointCut() {
}

@Around("logPointCut()")
public Object around(ProceedingJoinPoint point) throws Throwable {
long beginTime = System.currentTimeMillis();
// 执行方法
Object result = point.proceed();
// 执行时长(毫秒)
long time = System.currentTimeMillis() - beginTime;
//异步保存日志
saveLog(point, time);
return result;
}

void saveLog(ProceedingJoinPoint joinPoint, long time) throws InterruptedException {
MethodSignature signature = (MethodSignature) joinPoint.getSignature();
Method method = signature.getMethod();
LogDO sysLog = new LogDO();
Log syslog = method.getAnnotation(Log.class);
if (syslog != null) {
// 注解上的描述
sysLog.setOperation(syslog.value());
}
// 请求的方法名
String className = joinPoint.getTarget().getClass().getName();
String methodName = signature.getName();
sysLog.setMethod(className + "." + methodName + "()");
// 请求的参数
Object[] args = joinPoint.getArgs();
try {
String params = JSONUtils.beanToJson(args[0]).substring(0, 4999);
sysLog.setParams(params);
} catch (Exception e) {

}
// 获取request
HttpServletRequest request = HttpContextUtils.getHttpServletRequest();
// 设置IP地址
sysLog.setIp(IPUtils.getIpAddr(request));
// 用户名
//
UserDO currUser = ShiroUtils.getUser();
currUser.setUsername("test");
if (null == currUser) {
if (null != sysLog.getParams()) {
sysLog.setUserId(-1L);
sysLog.setUsername(sysLog.getParams());
} else {
sysLog.setUserId(-1L);
sysLog.setUsername("获取用户信息为空");
}
} else {
//
sysLog.setUserId( ShiroUtils.getUserId());
//
sysLog.setUsername(ShiroUtils.getUser().getUsername());
}
sysLog.setTime((int) time);
// 系统当前时间
Date date = new Date();
sysLog.setGmtCreate(date);
// 保存系统日志
logService.save(sysLog);
}
}

将日志信息打印的配置类

package com.hw.common;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import java.util.Arrays;

import javax.servlet.http.HttpServletRequest;

@Aspect
@Component
public class WebLogAspect {

private static final Logger logger = LoggerFactory.getLogger(WebLogAspect.class);

@Pointcut("execution( * com.hw.controller.*.*(..))")//两个..代表所有子目录,最后括号里的两个..代表所有参数
public void logPointCut() {
}


@Before("logPointCut()")
public void doBefore(JoinPoint joinPoint) throws Throwable {
// 接收到请求,记录请求内容
ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
HttpServletRequest request = attributes.getRequest();

// 记录下请求内容
logger.info("请求地址 : " + request.getRequestURL().toString());
logger.info("HTTP METHOD : " + request.getMethod());
// 获取真实的ip地址
//logger.info("IP : " + IPAddressUtil.getClientIpAddress(request));
logger.info("CLASS_METHOD : " + joinPoint.getSignature().getDeclaringTypeName() + "."
+ joinPoint.getSignature().getName());
logger.info("参数 : " + Arrays.toString(joinPoint.getArgs()));
// loggger.info("参数 : " + joinPoint.getArgs());

}

@AfterReturning(returning = "ret", pointcut = "logPointCut()")// returning的值和doAfterReturning的参数名一致
public void doAfterReturning(Object ret) throws Throwable {
// 处理完请求,返回内容(返回值太复杂时,打印的是物理存储空间的地址)
logger.debug("返回值 : " + ret);
}

@Around("logPointCut()")
public Object doAround(ProceedingJoinPoint pjp) throws Throwable {
long startTime = System.currentTimeMillis();
Object ob = pjp.proceed();// ob 为方法的返回值
logger.info("耗时 : " + (System.currentTimeMillis() - startTime));
return ob;
}
}

用于测试的controller类

package com.hw.controller;

import com.hw.common.Log;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class TestController {
@Log("/测试1")
@GetMapping("/test")
public String test() {
return "test";
}
}

完事直接贴上效果图:

日志打印存储

论项目中日志处理的正确操作(springboot案例)_spring

日志文件按天存储

论项目中日志处理的正确操作(springboot案例)_springboot的日志处理方式_02

数据库的存储

论项目中日志处理的正确操作(springboot案例)_json_03

标签:lang,springboot,sysLog,案例,import,org,日志,com,annotation
From: https://blog.51cto.com/u_15897407/5899810

相关文章

  • SpringBoot整合Swagger生成接口文档
    介绍:Swagger是一款RESTFUL接口的文档在线自动生成+功能测试功能软件。本文简单介绍了在项目中集成swagger的方法和一些常见问题。如果想深入分析项目源码,了解更多内容,见......
  • springboot项目同时支持http和https访问
    首先使用https需要一个server.keystore,生成教程可以然后开始改动项目:配置文件中填入server.keystore的信息server.ssl.key-store=server.keystoreserver.ssl.key-alias=tomc......
  • SpringBoot Maven RepackageMojo 打包失败原因
    maven打包提示:org/springframework/boot/maven/RepackageMojohasbeencompiledbyamorerecentversionoftheJavaRuntime(classfileversion61.0),thisver......
  • Mybatis源码分析(十七) - 源码包分析【日志模块】
    mybatis源码下载地址:​​https://github.com/mybatis/mybatis-3​​MyBatis源码导入过程:下载MyBatis的源码检查maven的版本,必须是3.25以上,建议使用maven的最新版本mybatis的......
  • SpringMVC 项目中 创建SpringBoot,使用Hibernate和JPA
    起因:老项目是SpringMVC,为了之后能使用更方便的SpringBoot。所以在其中添加了SpringBoot项目,但是老项目SpringMVC使用的Hibernate,SpringBoot希望使用JPA 解决方案:......
  • SpringBoot
    《静态资源导入》根据源码:静态资源放在下面的目录都可以:   ......
  • SpringBoot2 配置
    一.Properties与YamlSpringBoot支持properties与yaml两种配置文件application.properties/application.ymlyaml简单使用1.yaml简介yaml是以数据为中心的,比json,xml更适合做配......
  • easylogging++的那些事(四)源码分析(二)日志记录宏(四)VERBOSE日志宏
    目录CVLOG宏宏展开源码剖析CVLOG_EVERY_N宏宏展开源码剖析CVLOG_AFTER_N宏宏展开源码剖析CVLOG_N_TIMES宏宏展开源码剖析VLOG宏DCVLOG宏DVLOG宏VLOG_EVERY_N宏VLOG......
  • 求超大文件上传方案( SpringBoot )
    ​ 这里只写后端的代码,基本的思想就是,前端将文件分片,然后每次访问上传接口的时候,向后端传入参数:当前为第几块文件,和分片总数下面直接贴代码吧,一些难懂的我大部分都加上......
  • springboot2 生产部署注意事项【持续更新】
    注意事项1.去除不需要的jar开发工具jar:springs-boot-devtools2.监控一定要做好权限制或者去除 控制jar:spring-boot-starter-actuator监控druid的监控......