简介

调整后主要是提升简洁度和区分日志级别打印日志,配合@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以上版本)

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐