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

本文涉及的产品
日志服务 SLS,月写入数据量 50GB 1个月
简介: 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);


相关实践学习
日志服务之使用Nginx模式采集日志
本文介绍如何通过日志服务控制台创建Nginx模式的Logtail配置快速采集Nginx日志并进行多维度分析。
相关文章
|
5天前
|
SQL 监控 Java
在IDEA 、springboot中使用切面aop实现日志信息的记录到数据库
这篇文章介绍了如何在IDEA和Spring Boot中使用AOP技术实现日志信息的记录到数据库的详细步骤和代码示例。
在IDEA 、springboot中使用切面aop实现日志信息的记录到数据库
|
3天前
|
数据采集 存储 监控
Haskell爬虫中日志记录:监控HTTP请求与响应
Haskell爬虫中日志记录:监控HTTP请求与响应
|
7天前
|
Java
SpringBoot 拦截器 统一日志 记录用户请求返回日志
SpringBoot 拦截器 统一日志 记录用户请求返回日志
7 0
|
1月前
|
存储 Web App开发 Java
《手把手教你》系列基础篇(九十五)-java+ selenium自动化测试-框架之设计篇-java实现自定义日志输出(详解教程)
【7月更文挑战第13天】这篇文章介绍了如何在Java中创建一个简单的自定义日志系统,以替代Log4j或logback。
133 5
|
25天前
PolarDB-SCC使用问题之线性Lamport时间戳如何保证强一致性
PolarDB-SCC使用问题之线性Lamport时间戳如何保证强一致性
|
29天前
|
分布式计算 Java MaxCompute
详解 Java 限流接口实现问题之在Spring框架中使用AOP来实现基于注解的限流问题如何解决
详解 Java 限流接口实现问题之在Spring框架中使用AOP来实现基于注解的限流问题如何解决
|
29天前
|
存储 Java
浅析JAVA日志中的性能实践与原理解释问题之测试日志内容大小对系统性能的影响问题如何解决
浅析JAVA日志中的性能实践与原理解释问题之测试日志内容大小对系统性能的影响问题如何解决
|
29天前
|
Java 程序员 Linux
浅析JAVA日志中的性能实践与原理解释问题之使用日志框架记录日志问题如何解决
浅析JAVA日志中的性能实践与原理解释问题之使用日志框架记录日志问题如何解决
|
4天前
|
数据采集 监控 数据安全/隐私保护
掌握Selenium爬虫的日志管理:调整–log-level选项的用法
在Selenium Web数据采集时,日志管理至关重要。通过调整`–log-level`参数可优化日志详细度,如设置为`INFO`记录一般操作信息。结合代理IP、Cookie及user-agent配置,不仅能提高采集成功率,还能规避反爬机制。合理选择日志级别有助于调试与性能平衡,在复杂的数据采集任务中保持程序稳定与可控。
掌握Selenium爬虫的日志管理:调整–log-level选项的用法
|
6天前
|
SQL 存储 JSON
更快更强,SLS 推出高性能 SPL 日志查询模式
从海量的日志数据中,按照各种灵活的条件进行即时查询搜索,是可观测场景下的基本需求。本文介绍了 SLS 新推出的高性能 SPL 日志查询模式,支持 Unix 风格级联管道式语法,以及各种丰富的 SQL 处理函数。同时通过计算下推、向量化计算等优化,使得 SPL 查询可以在数秒内处理亿级数据,并支持 SPL 过滤结果分布图、随机翻页等特性。
196 65