前言
在AOP切面注入RequestId,拦截Controller、Service方法,打印入参出参耗时等,方便排查问题。
可以在服务上通过RequestId查询一次调用链日志:
可以使用 Linux grep 命令查询日志:
grep 命令用于查找文件里符合条件的字符串。
日志文件太大无法直接 cat 查看,可以用grep
常用参数:
- -A
- -C
- -E : 将样式为延伸的正则表达式来使用。
eg:
查询 包含 trainSegment/detail 的字符串的前后10行
grep -C 10 trainSegment/detail webapi-info-VM-130-116-centos.log
正则
grep -E -C 30 “keyword1. keyword2. ” webapi-info-VM-130-116-centos.log
代码
Controller
/**
* @author lihaoyang
* @date 2021/3/17
*/
@RestController
public class HiController {
@Autowired
HiServiceImpl hiService;
@GetMapping("get")
public String get(String msg) {
String rs = hiService.getHi(msg);
return rs;
}
}
Service
@Service
public class HiServiceImpl {
public String getHi(String msg) {
return "service: >>>>> " + msg;
}
}
切面类
RequestId切面
@Aspect
@Component
@Slf4j
@Order(-10)
public class ControllerRequestIdAspect {
@Pointcut("execution(public * com.nb.log.controller..*.*(..))")
public void controllerPoint() {
}
@Around("controllerPoint()")
public Object doControllerPointAround(ProceedingJoinPoint joinPoint) throws Throwable {
String requestId = UUID.randomUUID().toString();
MDC.put("requestId", requestId);
Object result = null;
try {
result = joinPoint.proceed();
} finally {
MDC.remove("requestId");
}
return result;
}
}
Controller切面
package com.nb.log.aop;
import com.alibaba.fastjson.JSONObject;
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.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import javax.servlet.http.HttpServletRequest;
import java.util.Arrays;
/**
* controller切面
*/
@Aspect
@Slf4j
@Component
@Order(0)
public class ControllerLogAspect {
@Pointcut("execution(public * com.nb.log.controller..*.*(..))")
public void controllerPoint() {}
@Around("controllerPoint()")
public Object doControllerAround(ProceedingJoinPoint joinPoint) throws Throwable {
long startTime = System.currentTimeMillis();
Object result = null;
try {
HttpServletRequest request =
((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
Object[] params = joinPoint.getArgs();
log.info("Controller层 className={}, methodName={}, params={},url={},ip={}",
joinPoint.getSignature().getDeclaringTypeName(), joinPoint.getSignature().getName(),
Arrays.toString(params), request.getRequestURL(), IpUtil.getIpAddr(request));
result = joinPoint.proceed();
} finally {
log.info("Controller层 耗时={}(ms), className={}, methodName={}, result={}",
System.currentTimeMillis() - startTime, joinPoint.getSignature().getDeclaringTypeName(),
joinPoint.getSignature().getName(), JSONObject.toJSONString(result));
}
return result;
}
}
Service切面
package com.nb.log.aop;
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.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import java.util.Arrays;
/**
* service层切面日志
*/
@Aspect
@Slf4j
@Order(0)
@Component
public class ServiceLogAspect {
@Pointcut("execution(public * com.nb.log.service..*ServiceImpl.*(..))")
public void servicePoint() {
}
@Around("servicePoint()")
public Object doServiceAround(ProceedingJoinPoint joinPoint) throws Throwable {
long startTime = System.currentTimeMillis();
Object result = null;
try {
Object[] params = joinPoint.getArgs();
log.info("Service层 className={}, methodName={}, params={}", joinPoint.getSignature().getDeclaringTypeName(), joinPoint.getSignature().getName(), Arrays.toString(params));
result = joinPoint.proceed();
}
finally {
log.info("Service层 耗时={}(ms), className={}, methodName={}", System.currentTimeMillis() - startTime, joinPoint.getSignature().getDeclaringTypeName(), joinPoint.getSignature().getName());
}
return result;
}
}
log4j2.xml
xml version="1.0" encoding="UTF-8"?> <configuration status="warn" monitorInterval="30"> <Properties> <property name="log_pattern">%d{yyyy-MM-dd HH:mm:ss.SSS} [%level] -%X{filter} <%t|%C{1.}.%M(%L)> -%X{requestId} %m%n%exproperty> <property name="project">remix-collectorproperty> <property name="basePath">D:/log/${project}/property> <property name="rolling_file_name">${basePath}/%d{yyyy-MM-dd}-%iproperty> <property name="every_file_size">500 MBproperty> Properties> <appenders> <console name="Console" target="SYSTEM_OUT"> <PatternLayout pattern="${log_pattern}"/> console> <RollingFile name="RollingFile" fileName="${basePath}/${project}-info-${hostName}.log" filePattern="${basePath}/${project}-info-${hostName}-%d{yyyy-MM-dd}-%i.log"> <Filters> <ThresholdFilter level="INFO" onMatch="ACCEPT" onMismatch="DENY"/> <ThresholdFilter level="WARN" onMatch="ACCEPT" onMismatch="NEUTRAL"/> <ThresholdFilter level="ERROR" onMatch="DENY" onMismatch="NEUTRAL"/> Filters> <PatternLayout pattern="${log_pattern}"/> <Policies> <TimeBasedTriggeringPolicy/> <SizeBasedTriggeringPolicy size="${every_file_size}"/> Policies> <DefaultRolloverStrategy> <Delete basePath="${basePath}" maxDepth="1"> <IfFileName glob="*.log" /> <IfLastModified age="3d"> IfLastModified> Delete> DefaultRolloverStrategy> RollingFile> <RollingFile name="RollingFileWarn" fileName="${basePath}/${project}-warn-${hostName}.log" filePattern="${rolling_file_name}-warn-${hostName}-%d{yyyy-MM-dd}-%i.log"> <Filters> <ThresholdFilter level="WARN" onMatch="ACCEPT" onMismatch="DENY"/> <ThresholdFilter level="ERROR" onMatch="DENY" onMismatch="NEUTRAL"/> Filters> <PatternLayout pattern="${log_pattern}"/> <Policies> <TimeBasedTriggeringPolicy modulate="true" interval="24"/> <SizeBasedTriggeringPolicy/> Policies> <DefaultRolloverStrategy max="20"/> RollingFile> <RollingFile name="RollingFileError" fileName="${basePath}/${project}-error-${hostName}.log" filePattern="${rolling_file_name}-error-${hostName}-%d{yyyy-MM-dd}-%i.log"> <Filters> <ThresholdFilter level="ERROR" onMatch="ACCEPT" onMismatch="DENY" /> Filters> <PatternLayout pattern="${log_pattern}"/> <SizeBasedTriggeringPolicy size="${every_file_size}"/> RollingFile> appenders> <loggers> <logger name="druid.sql.Statement" level="debug" additivity="false"> <AppenderRef ref="Console"/> <AppenderRef ref="druidSqlAppender"/> <AppenderRef ref="invokeAppender"/> logger> <logger name="druid.sql.ResultSet" level="debug" additivity="false"> <AppenderRef ref="Console"/> <AppenderRef ref="druidSqlAppender"/> <AppenderRef ref="invokeAppender"/> logger> <logger name="com.nb.log.controller" level="INFO"> logger> <root level="info"> <appender-ref ref="Console"/> <appender-ref ref="RollingFile"/> <appender-ref ref="RollingFileWarn"/> <appender-ref ref="RollingFileError"/> root> loggers> configuration>
maven pom.xml
xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0modelVersion> <groupId>com.nbgroupId> <artifactId>nb-logartifactId> <version>0.0.1-SNAPSHOTversion> <name>nb-logname> <description>Demo project for Spring Bootdescription> <properties> <java.version>1.8java.version> <project.build.sourceEncoding>UTF-8project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8project.reporting.outputEncoding> <spring-boot.version>2.3.7.RELEASEspring-boot.version> properties> <dependencies> <dependency> <groupId>org.springframework.bootgroupId> <artifactId>spring-boot-starter-webartifactId> dependency> <dependency> <groupId>org.springframework.bootgroupId> <artifactId>spring-boot-starter-webartifactId> <exclusions> <exclusion> <groupId>org.springframework.bootgroupId> <artifactId>spring-boot-starter-loggingartifactId> exclusion> exclusions> dependency> <dependency> <groupId>org.springframework.bootgroupId> <artifactId>spring-boot-starter-log4j2artifactId> dependency> <dependency> <groupId>org.springframework.bootgroupId> <artifactId>spring-boot-starter-aopartifactId> dependency> <dependency> <groupId>com.alibabagroupId> <artifactId>fastjsonartifactId> <version>1.2.75version> dependency> <dependency> <groupId>org.projectlombokgroupId> <artifactId>lombokartifactId> <version>1.18.18version> <scope>providedscope> dependency> <dependency> <groupId>org.springframework.bootgroupId> <artifactId>spring-boot-starter-testartifactId> <scope>testscope> <exclusions> <exclusion> <groupId>org.junit.vintagegroupId> <artifactId>junit-vintage-engineartifactId> exclusion> exclusions> dependency> dependencies> <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.bootgroupId> <artifactId>spring-boot-dependenciesartifactId> <version>${spring-boot.version}version> <type>pomtype> <scope>importscope> dependency> dependencies> dependencyManagement> <build> <plugins> <plugin> <groupId>org.apache.maven.pluginsgroupId> <artifactId>maven-compiler-pluginartifactId> <version>3.8.1version> <configuration> <source>1.8source> <target>1.8target> <encoding>UTF-8encoding> configuration> plugin> <plugin> <groupId>org.springframework.bootgroupId> <artifactId>spring-boot-maven-pluginartifactId> <version>2.3.7.RELEASEversion> <configuration> <mainClass>com.nb.log.NbLogApplicationmainClass> configuration> <executions> <execution> <id>repackageid> <goals> <goal>repackagegoal> goals> execution> executions> plugin> plugins> build> project>
完整代码
https://gitee.com/haoyangli/mdc-log.git
Original: https://www.cnblogs.com/lihaoyang/p/15612808.html
Author: 我俩绝配
Title: SpringBoot+log4j2+MDC+AOP记录requestId
原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/541013/
转载文章受原作者版权保护。转载请注明原作者出处!