ealenxie / aop-log Goto Github PK
View Code? Open in Web Editor NEW项目正式命名为aop-log,基于Spring AOP,ThreadLocal实现方法埋点信息收集与处理。
License: Apache License 2.0
项目正式命名为aop-log,基于Spring AOP,ThreadLocal实现方法埋点信息收集与处理。
License: Apache License 2.0
可以增加traceId功能吗?
plugins {
id 'java'
id 'org.springframework.boot' version '3.2.4'
id 'io.spring.dependency-management' version '1.1.4'
}
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-data-jdbc'
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
implementation 'org.springframework.boot:spring-boot-starter-web'
runtimeOnly 'com.mysql:mysql-connector-j'
compileOnly 'org.projectlombok:lombok'
annotationProcessor 'org.projectlombok:lombok'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
// extend
implementation 'org.springdoc:springdoc-openapi-starter-webmvc-ui:2.3.0'
// Sa-Token 权限认证,在线文档:https://sa-token.cc
implementation 'cn.dev33:sa-token-spring-boot3-starter:1.37.0'
implementation 'org.hibernate.validator:hibernate-validator:8.0.1.Final'
implementation 'com.alibaba.fastjson2:fastjson2:2.0.45'
implementation 'com.github.ealenxie:aop-log:2.5'
}
@Slf4j
@Component
public class AopLogController implements LogCollector {
private ObjectMapper objectMapper = new ObjectMapper();
@Override
public void collect(LogData logData) {
try {
log.info(objectMapper.writeValueAsString(logData));
} catch (JsonProcessingException e) {
e.printStackTrace();
log.error("333");
}
}
}
@Slf4j
@Tag(name = "项目管理相关接口")
@RequiredArgsConstructor
@RequestMapping("/project/")
@RestController
@AopLog(tag = "测试接口")
public class ProjectController {
private final IProjectService projectService;
@GetMapping("/list")
private R list(){
return R.success( projectService.findAll());
}
@PostMapping("/submit")
private R submit(ProjectBaseDTO dto){
LogData.step("用户添加项目");
return R.success(projectService.save(dto));
}
@PostMapping("/remove")
private R remove(){
return R.success();
}
}
没有打印日志
打断点发现InetAddress.getLocalHost().getHostAddress()方法要执行将近5-8秒,怎么处理
目前的master可以发布一个2.5版本吗?一些bug修复了,可以发布了吧?
springboot 2.4.1
例如:LogData.step(String template, Object... args)
这样的话可以方便的携带步骤中的一些关键中间变量
DataExtractor代码的getRequest()方法中
在其中使用RequestContextHolder来获取request信息,发现异步调用时,主线程结束后,子线程就获取不到request,会报以上错误信息。
""""
com.fasterxml.jackson.databind.JsonMappingException: No thread-bound request found: Are you referring to request attributes outside of an actual web request, or processing a request outside of the originally receiving thread? If you are actually operating within a web request and still receive this message, your code is probably running outside of DispatcherServlet: In this case, use RequestContextListener or RequestContextFilter to expose the current request. (through reference chain: com.github.LogData["args"]->com.google.gson.internal.LinkedTreeMap[3]->com.google.gson.internal.LinkedTreeMap["request"]->com.sun.proxy.$Proxy163["secure"])
""""
解决办法是: .在开启新线程之前,将servletRequestAttributes设置为子线程共享
/**
* 获取HttpServletRequest对象
*
* @return HttpServletRequest
*/
public static HttpServletRequest getRequest() {
ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
RequestContextHolder.setRequestAttributes(attributes,true);//设置子线程共享
return attributes != null ? attributes.getRequest() : null;
}
调用链: ServiceA -> ServiceB -> ServiceC
@AopLog(type = "ServiceA", stackTraceOnErr = true)
@service
public class ServiceA implements IServiceA {
@resource
private IServiceB serviceB;
public void execute() {
LogData.step("A-Begin");
...
serviceB.execute();
LogData.step("A-End");
}
}
@AopLog(type = "ServiceB", stackTraceOnErr = true)
@service
public class ServiceB implements IServiceB {
@resource
private IServiceC serviceC;
public void execute() {
LogData.step("B-Begin");
...
serviceC.execute();
LogData.step("B-End");
}
}
@AopLog(type = "ServiceC", stackTraceOnErr = true)
@service
public class ServiceC implements IServiceC {
LogData.step("C-Begin");
...
LogData.step("C-End");
}
结果:
日志 B-End、C-End丢失
请教一下,在collect里面怎样获取logData中的header内容,header类似是Object,请教一下怎样转换?如header中有自定义的字段,例如"test": "123",怎样获取"test"的值。另外,想获取header其他自定义字段的值,如何设置?
@slf4j
@component
public class AopLogCollector implements LogCollector {
private ObjectMapper objectMapper = new ObjectMapper();
@Override
public void collect(LogData logData) {
try {
log.info(objectMapper.writeValueAsString(logData));
} catch (JsonProcessingException e) {
e.printStackTrace();
}
}
}
需要在方法执行之前执行一些操作,目前支持吗?
业务层使用@AopLog(type = "描述", stackTraceOnErr = true)进行注解,并在业务末尾进行清理(LogData.removeCurrent());采用自定义收集器方式发现LogData.getCostTime() == 0, 如果不清理LogData.getCostTime() 数据正常
1、经测试,spring spel 表达式对性能影响很大,在tag值为默认值undefined的情况下,该代码会使性能下降40%左右
data.setTag(elSupporter.getByExpression(signature.getMethod(), point.getTarget(), point.getArgs(), aopLog.getTag()).toString());
建议修改如下
if (!aopLog.getTag().equals("undefined")) {
data.setTag(elSupporter.getByExpression(signature.getMethod(), point.getTarget(), point.getArgs(), aopLog.getTag()).toString());
}
2、另,默认的异步线程池队列,对比log4j2的disruptor异步处理性能差异巨大,在比较 asyncMode==true && log4j2 asyn==true 和
asyncMode==false && log4j2 asyn==true的情况下,开启aop-log的异步日志记录对性能的损耗大约占到20%
AopLogProcessor中 if (!aopLog.isLogOnErr() || !data.isSuccess()) 该判断是否是一个bug,理论上应该是 if (!aopLog.isLogOnErr() && !data.isSuccess()) 的关系
那如果不加注解的全部输出日志,加注解的不输入日志怎么写
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.