推荐用 spring aop 环绕通知自动统计方法耗时并打印慢接口 warn 日志,核心是测时间(system.nanotime)、判阈值(如 500ms)、记日志(含方法签名、耗时、关键参数等上下文),支持与 micrometer 指标监控结合,兼顾统一性与可维护性。

在 Java 中统计方法执行耗时并打印慢接口告警日志,核心是“测时间 + 判阈值 + 打日志”,推荐用 环绕通知(AOP) 或 手动计时 + 条件日志,避免侵入业务逻辑,也便于统一维护。
用 Spring AOP 自动统计耗时并告警
适合 Controller 层或 Service 层的慢接口监控。定义一个切面,拦截指定包下的方法,自动记录耗时并在超时时打印 WARN 日志。
- 添加依赖(若未引入):
spring-boot-starter-aop - 定义切点,例如匹配所有
@RequestMapping或特定注解标记的方法 - 在环绕通知中用
System.nanoTime()精确计时(比currentTimeMillis更适合短耗时场景) - 设置耗时阈值(如 500ms),超过则用 SLF4J 打印 WARN 日志,包含类名、方法名、耗时、请求参数(可选)
示例关键代码:
```java@Around("@annotation(org.springframework.web.bind.annotation.RequestMapping) || @annotation(org.springframework.web.bind.annotation.GetMapping)")
public Object logExecutionTime(ProceedingJoinPoint joinPoint) throws Throwable {
long start = System.nanoTime();
Object result = joinPoint.proceed();
long end = System.nanoTime();
long durationMs = TimeUnit.NANOSECONDS.toMillis(end - start);
if (durationMs > 500) {
String signature = joinPoint.getSignature().toShortString();
log.warn("Slow interface detected: {} | cost: {} ms", signature, durationMs);
}
return result;
}
用 @Timed 注解(Micrometer + Spring Boot Actuator)
如果项目已集成 Micrometer,可直接使用 @Timed 统计指标,并配合 Prometheus + Grafana 告警;同时结合自定义日志切面实现“指标+日志”双保障。
- 添加依赖:
micrometer-registry-prometheus和spring-boot-starter-actuator - 在方法上加
@Timed(value = "api.duration", percentiles = {0.95}) - 再通过 AOP 补充日志逻辑——只对超阈值调用额外打告警日志,避免日志刷屏
手动计时(适合少量关键方法或无 AOP 环境)
在方法开头记录开始时间,结尾计算差值并判断。虽简单但易遗漏或写错,建议封装工具方法复用。
- 定义工具类:
StopWatchUtils.elapsedMs(Runnable)或elapsedMs(Supplier<t>)</t> - 业务方法内调用:
long cost = StopWatchUtils.elapsedMs(() -> doBusiness()) - 判断
if (cost > 1000) log.warn("XXX method slow: {}ms", cost) - 注意:避免在高并发下频繁拼接字符串,可用占位符日志(
log.warn("slow method: {}, cost: {}ms", methodName, cost))
告警日志内容建议
光打“耗时超了”不够,需提供上下文才方便排查:
- 方法签名(类名 + 方法名)
- 精确耗时(毫秒级,保留整数即可)
- 关键入参摘要(如 userId、orderId,避免打敏感/大对象)
- 线程名或 traceId(如有分布式链路追踪)
- 环境标识(如 dev/test/prod),避免测试日志干扰生产告警
不复杂但容易忽略细节,关键是把“测、判、记”三步收口到一处,后续扩展熔断、降级或上报也更顺畅。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











