java使用AOP切面获取请求日志并记录

简介: java使用AOP切面获取请求日志并记录


3.AOP切面如下

package com.tjair.tjapi.config;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.tjair.common.log.TjapiLogVo;
import com.tjair.common.util.IPUtil;
import com.tjair.tjapi.feign.LogFeignService;
import com.tjair.tjapi.util.HttpHelper;
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.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.util.Date;
import java.util.Objects;
/**
• @description 拦截所有控制器的返回,记录响应报文
• @author unhejing
• @date 2021-03-17 上午11:52:26
*/
@Aspect
@Configuration
@Slf4j
public class LogAspect {
@Autowired
private LogFeignService logFeignService;
public LogAspect() {
}
@Pointcut(“execution(public * com.tjair.tjapi.controller..(…))”)
public void pointCutMethod() {
}
// 声明环绕通知
@Around(“pointCutMethod()”)
public Object doAround(ProceedingJoinPoint pjp) throws Throwable {
Long startTime = System.currentTimeMillis();
ApiOperation apiOperation = ((MethodSignature)pjp.getSignature()).getMethod().getAnnotation(ApiOperation.class);
// 获取request对象
RequestAttributes ra = RequestContextHolder.getRequestAttributes();
ServletRequestAttributes sra = (ServletRequestAttributes) ra;
HttpServletRequest request = sra.getRequest();
Object ret = pjp.proceed();
Long endTime = System.currentTimeMillis();
TjapiLogVo tjapiLogVo = getTjapiLogVo(request,Objects.nonNull(apiOperation) ? apiOperation.value() : “”,endTime-startTime,JSON.toJSONString(ret));
// 添加日志
addLog(tjapiLogVo);
log.info(“响应数据耗时{}:响应数据{}”,endTime-startTime,JSON.toJSONString(ret));
return ret;
}
public void addLog(TjapiLogVo tjapiLogVo) {
log.info(“添加日志:{}”,JSON.toJSONString(tjapiLogVo));
Long startTime = System.currentTimeMillis();
logFeignService.addTjapiLog(tjapiLogVo);
Long endtime = System.currentTimeMillis();
log.info(“添加日志耗时:{}”,endtime-startTime);
}
private TjapiLogVo getTjapiLogVo(HttpServletRequest request,String apiName,Long time,String response) throws IOException {
TjapiLogVo tjapiLogVo = new TjapiLogVo();
String jsonBody = HttpHelper.getBodyString(request);
log.info(“请求参数:{}”,jsonBody);
JSONObject reqObj = Objects.nonNull(JSON.parseObject(jsonBody)) ? JSON.parseObject(jsonBody) : new JSONObject();
JSONObject resObj = Objects.nonNull(JSON.parseObject(response)) ? JSON.parseObject(response) : new JSONObject();
//设置请求参数
tjapiLogVo.setParams(jsonBody);
tjapiLogVo.setPartnerid(Objects.nonNull(reqObj.getString(“partnerId”)) ? reqObj.getString(“partnerId”) : “-1”);
// 设置IP地址
tjapiLogVo.setIp(IPUtil.getIpAddr(request));
// 设置位置
tjapiLogVo.setLocation(IPUtil.getCityInfo(tjapiLogVo.getIp()));
//设置请求方法,GET,POST…
tjapiLogVo.setMethod(request.getMethod());
//设置请求路径
tjapiLogVo.setUrl(request.getRequestURI());
// 设置请求方法名称
tjapiLogVo.setApiName(apiName);
// 设置创建时间
tjapiLogVo.setCreateTime(new Date());
// 设置请求状态
Integer code = Objects.nonNull(resObj.getInteger(“code”)) ? resObj.getInteger(“code”) : 1;
tjapiLogVo.setStatus(code);
// 设置接口消耗时间
tjapiLogVo.setTime(time.intValue());
// 设置响应内容
tjapiLogVo.setResponse(response);
return tjapiLogVo;
}
}

4.测试接口

package com.tjair.tjapi.controller;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.tjair.common.service.RedisUtils;
import com.tjair.common.util.Result;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
/**
• @author jingyujie
• @create 2021-03-16 下午2:39
**/
@RestController
@RequestMapping(“/test”)
@Api(tags = “测试API控制器”)
public class TestController {
@Autowired
private RedisUtils redisUtils;
@PostMapping(“/apiTest”)
@ApiOperation(“接口测试”)
public Result apiTest(@RequestBody JSONObject obj){
return Result.returnSuccess(“接口已联通,请求入参:”+ JSON.toJSONString(obj));
}
}

5.请求结果如下

备注说明:

1.LogFeignService是添加日志的service

2.IPUtil是获取IP和地址信息相关的工具类

3.HttpHelper是解析request中的请求参数的工具类

4.ApiOperation是获取接口的注解上面的接口描述

5.partnerId是我请求参数里面必传的用户编码

6.code是响应参数里面的状态码,用于判断接口是否请求成功

末尾附上工具类:

IPUtil.java

类中的/ip2region.db这个是一个地址库,可直接百度下载即可。

package com.tjair.common.util;
import org.apache.commons.io.FileUtils;
import org.lionsoul.ip2region.DataBlock;
import org.lionsoul.ip2region.DbConfig;
import org.lionsoul.ip2region.DbSearcher;
import org.lionsoul.ip2region.Util;
import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.lang.reflect.Method;
/**
• ip操作相关工具类
• @author jingyujie
• @create 2020-06-24 下午2:11
**/
public class IPUtil {
public static String getCityInfo(String ip){
try {
//db
String dbPath = IPUtil.class.getResource(“/ip2region.db”).getPath();
System.out.println(“路径:”+dbPath);
File file = new File(dbPath);
if (file.exists() == false) {
System.out.println(“Error: Invalid ip2region.db file”);
String tmpDir = System.getProperties().getProperty(“java.io.tmpdir”);
dbPath = tmpDir + “ip.db”;
System.out.println(dbPath);
file = new File(dbPath);
FileUtils.copyInputStreamToFile(IPUtil.class.getClassLoader().getResourceAsStream(“classpath:ip2region.db”), file);
}
//查询算法
int algorithm = DbSearcher.BTREE_ALGORITHM; //B-tree
//DbSearcher.BINARY_ALGORITHM //Binary
//DbSearcher.MEMORY_ALGORITYM //Memory
DbSearcher searcher = null;
try {
DbConfig config = new DbConfig();
searcher = new DbSearcher(config, dbPath);


相关实践学习
【涂鸦即艺术】基于云应用开发平台CAP部署AI实时生图绘板
【涂鸦即艺术】基于云应用开发平台CAP部署AI实时生图绘板
相关文章
|
7月前
|
设计模式 Java Spring
Java 设计模式之责任链模式:优雅处理请求的艺术
责任链模式通过构建处理者链,使请求沿链传递直至被处理,实现发送者与接收者的解耦。适用于审批流程、日志处理等多级处理场景,提升系统灵活性与可扩展性。
722 2
|
JSON API 数据格式
【Azure APIM】如何把APIM中处理的请求的所有请求头保存在日志中?
Azure API Management 默认诊断日志不记录请求的 Header 和 Body 信息。为实现记录,可通过配置 Trace 策略解决。例如,使用 `context.Request.Headers` 和 `context.Request.Body` 获取相关信息,并以 JSON 或字符串格式保存。示例代码展示了如何将 Headers 转换为 JSON 或逗号分隔字符串形式记录。相关参考资料包括 Set Body Policy 和 Trace Policy 官方文档,帮助进一步了解与扩展功能。
292 36
|
SQL druid Oracle
【YashanDB知识库】yasdb jdbc驱动集成druid连接池,业务(java)日志中有token IDENTIFIER start异常
客户Java日志中出现异常,影响Druid的merge SQL功能(将SQL字面量替换为绑定变量以统计性能),但不影响正常业务流程。原因是Druid在merge SQL时传入null作为dbType,导致无法解析递归查询中的`start`关键字。
|
JSON Java 数据格式
java操作http请求针对不同提交方式(application/json和application/x-www-form-urlencoded)
java操作http请求针对不同提交方式(application/json和application/x-www-form-urlencoded)
355 25
java操作http请求针对不同提交方式(application/json和application/x-www-form-urlencoded)
|
Java Maven
java项目中jar启动执行日志报错:no main manifest attribute, in /www/wwwroot/snow-server/z-server.jar-jar打包的大小明显小于正常大小如何解决
在Java项目中,启动jar包时遇到“no main manifest attribute”错误,且打包大小明显偏小。常见原因包括:1) Maven配置中跳过主程序打包;2) 缺少Manifest文件或Main-Class属性。解决方案如下:
3210 8
java项目中jar启动执行日志报错:no main manifest attribute, in /www/wwwroot/snow-server/z-server.jar-jar打包的大小明显小于正常大小如何解决
|
Java 编译器 Spring
JAVA中切面的使用
AOP(面向切面编程)通过切面、通知、切入点和连接点实现模块化关注点分离。Spring AOP基于代理模式,使用JDK动态代理或CGLIB代理;AspectJ采用字节码增强,在编译或类加载时织入切面逻辑,性能更高。示例代码展示了如何在方法调用前后插入日志记录等操作。
|
XML JSON Java
Java中Log级别和解析
日志级别定义了日志信息的重要程度,从低到高依次为:TRACE(详细调试)、DEBUG(开发调试)、INFO(一般信息)、WARN(潜在问题)、ERROR(错误信息)和FATAL(严重错误)。开发人员可根据需要设置不同的日志级别,以控制日志输出量,避免影响性能或干扰问题排查。日志框架如Log4j 2由Logger、Appender和Layout组成,通过配置文件指定日志级别、输出目标和格式。
|
运维 Cloud Native Java
postman发起post请求遇到报错:java.io.FileNotFoundException (文件名、目录名或卷标语法不正确。)
遇到bug报错,多猜可能的原因,控制变量反复测试,直至找到问题的关键,然后再思考如何解决或者回避。 博客不应该只有代码和解决方案,重点应该在于给出解决方案的同时分享思维模式,只有思维才能可持续地解决问题,只有思维才是真正值得学习和分享的核心要素。如果这篇博客能给您带来一点帮助,麻烦您点个赞支持一下,还可以收藏起来
|
安全 Java API
java如何请求接口然后终止某个线程
通过本文的介绍,您应该能够理解如何在Java中请求接口并根据返回结果终止某个线程。合理使用标志位或 `interrupt`方法可以确保线程的安全终止,而处理好网络请求中的各种异常情况,可以提高程序的稳定性和可靠性。
286 6
|
人工智能 Oracle Java
解决 Java 打印日志吞异常堆栈的问题
前几天有同学找我查一个空指针问题,Java 打印日志时,异常堆栈信息被吞了,导致定位不到出问题的地方。
438 2