SpringBoot 日志框架自定义
·
简介
调整后主要是提升简洁度和区分日志级别打印日志,配合@Slf4j注解直接使用
maven 依赖(pom.xml)
<dependency>
<groupId>dom4j</groupId>
<artifactId>dom4j</artifactId>
<version>1.6.1</version>
</dependency>
日志打印细节和权限定义(logback.xml)
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<!-- 日志存放路径 -->
<property name="log.path" value="/opt/javaObject/lk-sbt-cjkz-server-log"/>
<!-- DEBUG级别日志文件-->
<appender name="file_debug" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${log.path}/sys-debug.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>${log.path}/sys-debug.%d{yyyy-MM-dd}.log</fileNamePattern>
<maxHistory>30</maxHistory>
<totalSizeCap>5GB</totalSizeCap>
</rollingPolicy>
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
<charset>UTF-8</charset>
</encoder>
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>DEBUG</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
</appender>
<!-- INFO级别日志文件 -->
<appender name="file_info" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${log.path}/sys-info.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>${log.path}/sys-info.%d{yyyy-MM-dd}.log</fileNamePattern>
<maxHistory>30</maxHistory>
<totalSizeCap>5GB</totalSizeCap>
</rollingPolicy>
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
<charset>UTF-8</charset>
</encoder>
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>INFO</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
</appender>
<!-- WARN级别日志文件 -->
<appender name="file_warn" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${log.path}/sys-warn.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>${log.path}/sys-warn.%d{yyyy-MM-dd}.log</fileNamePattern>
<maxHistory>30</maxHistory>
<totalSizeCap>5GB</totalSizeCap>
</rollingPolicy>
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
<charset>UTF-8</charset>
</encoder>
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>WARN</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
</appender>
<!-- ERROR级别日志文件 -->
<appender name="file_error" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${log.path}/sys-error.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>${log.path}/sys-error.%d{yyyy-MM-dd}.log</fileNamePattern>
<maxHistory>30</maxHistory>
<totalSizeCap>5GB</totalSizeCap>
</rollingPolicy>
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
<charset>UTF-8</charset>
</encoder>
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>ERROR</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
</appender>
<!-- 控制台输出 - 彩色日志格式 -->
<appender name="console" class="ch.qos.logback.core.ConsoleAppender">
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<!-- 彩色日志格式:时间 级别 线程 类名 消息 -->
<!-- 当前格式:时间 级别 线程 类名 消息 -->
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} %highlight(%-5level) %cyan([%thread]) %yellow(%logger{36}) - %msg%n</pattern>
<!-- 可选格式1:更丰富的颜色 -->
<!-- <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} %highlight(%-5level) %cyan([%thread]) %yellow(%logger{36}) %green(-) %msg%n</pattern> -->
<!-- 可选格式2:带方法名 -->
<!-- <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} %highlight(%-5level) %cyan([%thread]) %yellow(%logger{36}) %magenta(%method) - %msg%n</pattern> -->
<!-- 可选格式3:简洁格式 -->
<!-- <pattern>%d{HH:mm:ss.SSS} %highlight(%-5level) %cyan([%thread]) %yellow(%logger{36}) - %msg%n</pattern> -->
<charset>UTF-8</charset>
</encoder>
</appender>
<!-- 系统日志级别控制 - 过滤噪音日志 -->
<logger name="sun.rmi" level="WARN"/>
<logger name="sun.nio" level="WARN"/>
<logger name="sun.misc" level="WARN"/>
<logger name="jdk" level="WARN"/>
<logger name="java.lang.reflect" level="WARN"/>
<logger name="java.util" level="WARN"/>
<logger name="java.nio" level="WARN"/>
<logger name="org.reflections" level="WARN"/>
<logger name="org.apache.hc" level="WARN"/>
<logger name="org.apache.hc.client5.http" level="WARN"/>
<logger name="org.apache.http" level="WARN"/>
<logger name="org.springframework.cloud" level="INFO"/>
<logger name="com.netflix" level="WARN"/>
<logger name="com.netflix.discovery" level="WARN"/>
<logger name="com.netflix.eureka" level="INFO"/>
<logger name="org.apache.catalina" level="WARN"/>
<logger name="org.apache.tomcat" level="WARN"/>
<logger name="org.apache.commons" level="WARN"/>
<logger name="org.apache.log4j" level="WARN"/>
<logger name="io.netty" level="WARN"/>
<logger name="io.netty.util.ThreadPerTaskInvocator" level="WARN"/>
<!-- 过滤Spring Boot内部的噪音日志 -->
<logger name="org.springframework.boot" level="INFO"/>
<logger name="org.springframework.core" level="WARN"/>
<logger name="org.springframework.beans" level="WARN"/>
<logger name="org.springframework.web" level="WARN"/>
<logger name="org.springframework.context" level="WARN"/>
<logger name="org.springframework.scheduling" level="WARN"/>
<logger name="org.springframework.data" level="WARN"/>
<logger name="org.springframework.jdbc" level="WARN"/>
<logger name="org.springframework.transaction" level="WARN"/>
<!-- 过滤Jackson、解析器的噪音日志 -->
<logger name="com.fasterxml.jackson" level="WARN"/>
<logger name="com.fasterxml.jackson.databind" level="WARN"/>
<logger name="org.hibernate" level="WARN"/>
<logger name="javax.validation" level="WARN"/>
<logger name="org.hibernate.validator" level="WARN"/>
<!-- 过滤缓存、连接池相关日志 -->
<logger name="org.springframework.data.redis" level="WARN"/>
<logger name="redis.clients" level="WARN"/>
<logger name="org.apache.commons.dbcp" level="WARN"/>
<logger name="org.apache.commons.pool" level="WARN"/>
<logger name="com.zaxxer.hikari" level="WARN"/>
<!-- 过滤Swagger/Knife4j噪音 -->
<logger name="org.springdoc" level="WARN"/>
<logger name="com.github" level="WARN"/>
<!-- 过滤测试框架噪音 -->
<logger name="org.junit" level="WARN"/>
<logger name="org.mockito" level="WARN"/>
<!-- 过滤其他可能产生噪音的框架组件 -->
<logger name="org.springframework.aop" level="WARN"/>
<logger name="org.springframework.cache" level="WARN"/>
<logger name="org.springframework.kafka" level="WARN"/>
<logger name="org.springframework.integration" level="WARN"/>
<logger name="org.springframework.security" level="WARN"/>
<logger name="org.springframework.session" level="WARN"/>
<logger name="org.springframework.amqp" level="WARN"/>
<logger name="org.springframework.messaging" level="WARN"/>
<logger name="org.springframework.orm" level="WARN"/>
<logger name="org.springframework.cglib" level="WARN"/>
<logger name="net.bytebuddy" level="WARN"/>
<!-- 过滤Validation框架的相关噪音日志 -->
<logger name="javax.validation.Validator" level="WARN"/>
<logger name="org.springframework.validation.beanvalidation" level="WARN"/>
<logger name="org.springframework.validation.BeanPropertyBindingResult" level="WARN"/>
<logger name="org.springframework.boot.ConstrainedApplicationConfig" level="WARN"/>
<logger name="Validator" level="WARN"/>
<!-- 过滤Jackson反序列化时的验证噪音 -->
<logger name="com.fasterxml.jackson.module.paramnames" level="WARN"/>
<logger name="com.fasterxml.jackson.databind.deser." level="WARN"/>
<logger name="com.fasterxml.jackson.databind.jsontype." level="WARN"/>
<!-- 过滤JAXB/Jersey相关的噪音日志 -->
<logger name="com.sun.jersey" level="WARN"/>
<logger name="org.glassfish.jersey" level="WARN"/>
<logger name="org.glassfish.jaxb" level="WARN"/>
<logger name="com.sun.xml.bind" level="WARN"/>
<logger name="javax.xml.bind" level="WARN"/>
<logger name="com.sun.jersey.core.impl.provider.entity" level="WARN"/>
<logger name="c.s.j.c.s.component.ProviderServices" level="WARN"/>
<logger name="javax.ws.rs.core" level="WARN"/>
<logger name="jersey.client.impl.contentLength" level="WARN"/>
<!-- 过滤工具类噪音 -->
<logger name="lombok" level="WARN"/>
<logger name="org.apache.commons.beanutils" level="WARN"/>
<logger name="org.apache.commons.collections" level="WARN"/>
<logger name="org.apache.commons.configuration" level="WARN"/>
<logger name="org.apache.commons.digester" level="WARN"/>
<logger name="org.apache.commons.io" level="WARN"/>
<logger name="org.apache.commons.lang" level="WARN"/>
<logger name="org.apache.commons.pool" level="WARN"/>
<logger name="org.apache.commons.proxy" level="WARN"/>
<logger name="org.apache.commons.manager.timer" level="WARN"/>
<logger name="org.slf4j" level="WARN"/>
<!-- 设置更严格的日志级别以确保噪音被完全过滤 -->
<logger name="org.springframework" level="WARN"/>
<logger name="org.springframework.boot.autoconfigure" level="INFO"/>
<logger name="org.springframework.boot.SpringApplication" level="INFO"/>
<!-- 再增加一个通用配置,过滤所有的框架内部细节 -->
<logger name="RootCauseUsingConstructorBean" level="OFF"/>
<logger name="DefaultConnectionPoolProvider" level="WARN"/>
<logger name="DefaultServerView" level="WARN"/>
<logger name="DefaultConnectionIdentificationProvider" level="WARN"/>
<logger name="ForkJoinPool" level="WARN"/>
<logger name="CompletableFuture" level="WARN"/>
<!-- 根据您遇到的问题,添加更多针对性的过滤规则 -->
<logger name="s.d.s.p.bean.BeanModelProperty" level="WARN"/>
<logger name="org.springframework.data.rest.core.mapping.ObjectMappingConfigurer" level="WARN"/>
<logger name="org.springframework.data.repository" level="WARN"/>
<logger name="io.swagger" level="WARN"/>
<logger name="springfox" level="WARN"/>
<logger name="knife4j" level="WARN"/>
<logger name="org.springframework.boot.autoconfigure" level="INFO"/>
<logger name="org.springframework.boot.context.properties.ConfigurationPropertiesBindingPostProcessor" level="WARN"/>
<logger name="org.springframework.boot.BeanDefinitionOverrideChecker" level="WARN"/>
<!-- JVM运行时和垃圾回收相关噪音 -->
<logger name="jdk.internal" level="WARN"/>
<logger name="java.lang.management" level="WARN"/>
<logger name="java.util.concurrent.atomic" level="WARN"/>
<logger name="java.lang.StringBuilder" level="WARN"/>
<logger name="java.util.Arrays" level="WARN"/>
<logger name="java.lang.Class" level="WARN"/>
<logger name="java.lang.reflect.Method" level="WARN"/>
<!-- 消息传递机制日志清理 -->
<logger name="org.springframework.boot.logging.AbstractLoggingSystem" level="WARN"/>
<logger name="org.springframework.boot.context.event.EventPublishingRunListener" level="WARN"/>
<logger name="org.springframework.boot.context.embedded.tomcat" level="WARN"/>
<!-- 进一步清理更细粒度的框架噪音 -->
<logger name="org.springframework.context.annotation.ComponentScanBeanDefinitionParser" level="WARN"/>
<logger name="org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor" level="WARN"/>
<logger name="org.springframework.beans.factory.config.DependencyDescriptor" level="WARN"/>
<logger name="org.springframework.context.support.DefaultLifecycleProcessor" level="WARN"/>
<logger name="org.springframework.context.event.SimpleApplicationEventMulticaster" level="WARN"/>
<logger name="org.springframework.boot.web.servlet.support.SpringBootServletInitializer" level="WARN"/>
<!-- 根日志配置 -->
<root level="INFO">
<appender-ref ref="console" />
<appender-ref ref="file_debug" />
<appender-ref ref="file_info" />
<appender-ref ref="file_warn" />
<appender-ref ref="file_error" />
</root>
</configuration>
配置文件(application.yml)
logging:
level:
root: DEBUG
com.lk.back: DEBUG
pattern:
console: "%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n"
file: "%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n"
控制台输出效果(springboot2.2.5以上版本)

AOP环绕service入参和响应结果监控
package com.lk.back.config;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
/**
* AOP配置类
* 启用AspectJ自动代理功能
* @author CHENYB
* @version 1.0
*/
@Configuration
@EnableAspectJAutoProxy(proxyTargetClass = true)
public class AopConfig {
// AOP配置类,启用AspectJ自动代理
// proxyTargetClass = true 表示使用CGLIB代理,支持类代理
}
package com.lk.back.common.aspect;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
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.stereotype.Component;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Arrays;
/**
* @author CHENYB
* @version 1.0
* @date 2025-09-28
* @description
* Service方法日志切面;
* 用于监听所有service方法的入参和返回值;
* 默认输出debug级别日志,方便调试
*/
@Aspect
@Component
@Slf4j
public class ServiceLogAspect {
private final ObjectMapper objectMapper = new ObjectMapper();
private final DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS");
/**
* 定义切点:匹配service包下所有类的所有方法
*/
@Pointcut("execution(* com.lk.back.service..*.*(..))")
public void serviceMethods() {
}
/**
* 环绕通知:记录方法执行前后的日志
*/
@Around("serviceMethods()")
public Object logServiceMethod(ProceedingJoinPoint joinPoint) throws Throwable {
String className = joinPoint.getTarget().getClass().getSimpleName();
String methodName = joinPoint.getSignature().getName();
Object[] args = joinPoint.getArgs();
// 请求前日志
logRequest(className, methodName, args);
long startTime = System.currentTimeMillis();
Object result = null;
Throwable exception = null;
try {
// 执行目标方法
result = joinPoint.proceed();
return result;
} catch (Throwable e) {
exception = e;
throw e;
} finally {
long endTime = System.currentTimeMillis();
long executionTime = endTime - startTime;
// 请求后日志
logResponse(className, methodName, result, exception, executionTime);
}
}
/**
* 记录请求前日志
*/
private void logRequest(String className, String methodName, Object[] args) {
if (log.isDebugEnabled()) {
String currentTime = LocalDateTime.now().format(formatter);
String argsJson = formatArgs(args);
log.debug("<======= 业务处理 请求参数 === Time:{} - Class:{} - Method:{} - Parameters:{} =======>",
currentTime,className,methodName,argsJson);
}
}
/**
* 记录请求后日志
*/
private void logResponse(String className, String methodName, Object result,
Throwable exception, long executionTime) {
if (log.isDebugEnabled()) {
String currentTime = LocalDateTime.now().format(formatter);
String resultJson = formatResult(result);
log.debug("<======= 业务处理 返回报文 === Time:{} - Class:{} - Method:{} - Result:{} - Execution Time:{} =======>",
currentTime,className,methodName,resultJson,executionTime);
if (exception != null) {
log.debug("Exception: {}", exception.getMessage());
}
}
}
/**
* 格式化参数为JSON字符串
*/
private String formatArgs(Object[] args) {
if (args == null || args.length == 0) {
return "[]";
}
try {
// 如果只有一个参数,直接序列化
if (args.length == 1) {
return objectMapper.writeValueAsString(args[0]);
}
// 多个参数,序列化为数组
return objectMapper.writeValueAsString(args);
} catch (JsonProcessingException e) {
// 如果JSON序列化失败,使用toString方法
return Arrays.toString(args);
}
}
/**
* 格式化返回值为JSON字符串
*/
private String formatResult(Object result) {
if (result == null) {
return "null";
}
try {
return objectMapper.writeValueAsString(result);
} catch (JsonProcessingException e) {
// 如果JSON序列化失败,使用toString方法
return result.toString();
}
}
}
控制台效果(springboot2.2.5以上版本)

更多推荐
所有评论(0)