mirror of
				https://github.com/continew-org/continew-starter.git
				synced 2025-11-04 18:59:22 +08:00 
			
		
		
		
	refactor(log): 优化日志模块
This commit is contained in:
		@@ -26,7 +26,7 @@ import org.slf4j.Logger;
 | 
				
			|||||||
import org.slf4j.LoggerFactory;
 | 
					import org.slf4j.LoggerFactory;
 | 
				
			||||||
import org.springframework.web.context.request.RequestContextHolder;
 | 
					import org.springframework.web.context.request.RequestContextHolder;
 | 
				
			||||||
import org.springframework.web.context.request.ServletRequestAttributes;
 | 
					import org.springframework.web.context.request.ServletRequestAttributes;
 | 
				
			||||||
import top.continew.starter.log.autoconfigure.LogProperties;
 | 
					import top.continew.starter.log.model.LogProperties;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import java.time.Duration;
 | 
					import java.time.Duration;
 | 
				
			||||||
import java.time.Instant;
 | 
					import java.time.Instant;
 | 
				
			||||||
@@ -51,42 +51,42 @@ public class AccessLogAspect {
 | 
				
			|||||||
    /**
 | 
					    /**
 | 
				
			||||||
     * 切点 - 匹配所有控制器层的 GET 请求方法
 | 
					     * 切点 - 匹配所有控制器层的 GET 请求方法
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    @Pointcut("within(@org.springframework.web.bind.annotation.RequestMapping *)")
 | 
					    @Pointcut("@annotation(org.springframework.web.bind.annotation.RequestMapping)")
 | 
				
			||||||
    public void pointcut() {
 | 
					    public void pointcut() {
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
     * 切点 - 匹配所有控制器层的 GET 请求方法
 | 
					     * 切点 - 匹配所有控制器层的 GET 请求方法
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    @Pointcut("within(@org.springframework.web.bind.annotation.GetMapping *)")
 | 
					    @Pointcut("@annotation(org.springframework.web.bind.annotation.GetMapping)")
 | 
				
			||||||
    public void pointcutGet() {
 | 
					    public void pointcutGet() {
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
     * 切点 - 匹配所有控制器层的 POST 请求方法
 | 
					     * 切点 - 匹配所有控制器层的 POST 请求方法
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    @Pointcut("within(@org.springframework.web.bind.annotation.PostMapping *)")
 | 
					    @Pointcut("@annotation(org.springframework.web.bind.annotation.PostMapping)")
 | 
				
			||||||
    public void pointcutPost() {
 | 
					    public void pointcutPost() {
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
     * 切点 - 匹配所有控制器层的 PUT 请求方法
 | 
					     * 切点 - 匹配所有控制器层的 PUT 请求方法
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    @Pointcut("within(@org.springframework.web.bind.annotation.PutMapping *)")
 | 
					    @Pointcut("@annotation(org.springframework.web.bind.annotation.PutMapping)")
 | 
				
			||||||
    public void pointcutPut() {
 | 
					    public void pointcutPut() {
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
     * 切点 - 匹配所有控制器层的 DELETE 请求方法
 | 
					     * 切点 - 匹配所有控制器层的 DELETE 请求方法
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    @Pointcut("within(@org.springframework.web.bind.annotation.DeleteMapping *)")
 | 
					    @Pointcut("@annotation(org.springframework.web.bind.annotation.DeleteMapping)")
 | 
				
			||||||
    public void pointcutDelete() {
 | 
					    public void pointcutDelete() {
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
     * 切点 - 匹配所有控制器层的 PATCH 请求方法
 | 
					     * 切点 - 匹配所有控制器层的 PATCH 请求方法
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    @Pointcut("within(@org.springframework.web.bind.annotation.PatchMapping *)")
 | 
					    @Pointcut("@annotation(org.springframework.web.bind.annotation.PatchMapping)")
 | 
				
			||||||
    public void pointcutPatch() {
 | 
					    public void pointcutPatch() {
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -16,6 +16,7 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
package top.continew.starter.log.aspect;
 | 
					package top.continew.starter.log.aspect;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import cn.hutool.core.annotation.AnnotationUtil;
 | 
				
			||||||
import cn.hutool.core.text.CharSequenceUtil;
 | 
					import cn.hutool.core.text.CharSequenceUtil;
 | 
				
			||||||
import jakarta.servlet.http.HttpServletRequest;
 | 
					import jakarta.servlet.http.HttpServletRequest;
 | 
				
			||||||
import jakarta.servlet.http.HttpServletResponse;
 | 
					import jakarta.servlet.http.HttpServletResponse;
 | 
				
			||||||
@@ -30,10 +31,11 @@ import org.slf4j.LoggerFactory;
 | 
				
			|||||||
import org.springframework.web.context.request.RequestContextHolder;
 | 
					import org.springframework.web.context.request.RequestContextHolder;
 | 
				
			||||||
import org.springframework.web.context.request.ServletRequestAttributes;
 | 
					import org.springframework.web.context.request.ServletRequestAttributes;
 | 
				
			||||||
import top.continew.starter.log.annotation.Log;
 | 
					import top.continew.starter.log.annotation.Log;
 | 
				
			||||||
import top.continew.starter.log.autoconfigure.LogProperties;
 | 
					 | 
				
			||||||
import top.continew.starter.log.dao.LogDao;
 | 
					import top.continew.starter.log.dao.LogDao;
 | 
				
			||||||
import top.continew.starter.log.handler.LogHandler;
 | 
					import top.continew.starter.log.handler.LogHandler;
 | 
				
			||||||
 | 
					import top.continew.starter.log.model.LogProperties;
 | 
				
			||||||
import top.continew.starter.log.model.LogRecord;
 | 
					import top.continew.starter.log.model.LogRecord;
 | 
				
			||||||
 | 
					import top.continew.starter.web.util.SpringWebUtils;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import java.lang.reflect.Method;
 | 
					import java.lang.reflect.Method;
 | 
				
			||||||
import java.time.Instant;
 | 
					import java.time.Instant;
 | 
				
			||||||
@@ -76,13 +78,13 @@ public class LogAspect {
 | 
				
			|||||||
    @Around("pointcut()")
 | 
					    @Around("pointcut()")
 | 
				
			||||||
    public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
 | 
					    public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
 | 
				
			||||||
        Instant startTime = Instant.now();
 | 
					        Instant startTime = Instant.now();
 | 
				
			||||||
        // 非 Web 环境不记录
 | 
					        // 指定规则不记录
 | 
				
			||||||
        ServletRequestAttributes attributes = (ServletRequestAttributes)RequestContextHolder.getRequestAttributes();
 | 
					        HttpServletRequest request = SpringWebUtils.getRequest();
 | 
				
			||||||
        if (attributes == null || attributes.getResponse() == null) {
 | 
					        Method targetMethod = this.getMethod(joinPoint);
 | 
				
			||||||
 | 
					        Class<?> targetClass = joinPoint.getTarget().getClass();
 | 
				
			||||||
 | 
					        if (!isRequestRecord(targetMethod, targetClass)) {
 | 
				
			||||||
            return joinPoint.proceed();
 | 
					            return joinPoint.proceed();
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        HttpServletRequest request = attributes.getRequest();
 | 
					 | 
				
			||||||
        HttpServletResponse response = attributes.getResponse();
 | 
					 | 
				
			||||||
        String errorMsg = null;
 | 
					        String errorMsg = null;
 | 
				
			||||||
        // 开始记录
 | 
					        // 开始记录
 | 
				
			||||||
        LogRecord.Started startedLogRecord = logHandler.start(startTime, request);
 | 
					        LogRecord.Started startedLogRecord = logHandler.start(startTime, request);
 | 
				
			||||||
@@ -95,8 +97,7 @@ public class LogAspect {
 | 
				
			|||||||
        } finally {
 | 
					        } finally {
 | 
				
			||||||
            try {
 | 
					            try {
 | 
				
			||||||
                Instant endTime = Instant.now();
 | 
					                Instant endTime = Instant.now();
 | 
				
			||||||
                Method targetMethod = this.getMethod(joinPoint);
 | 
					                HttpServletResponse response = SpringWebUtils.getResponse();
 | 
				
			||||||
                Class<?> targetClass = joinPoint.getTarget().getClass();
 | 
					 | 
				
			||||||
                LogRecord logRecord = logHandler.finish(startedLogRecord, endTime, response, logProperties
 | 
					                LogRecord logRecord = logHandler.finish(startedLogRecord, endTime, response, logProperties
 | 
				
			||||||
                    .getIncludes(), targetMethod, targetClass);
 | 
					                    .getIncludes(), targetMethod, targetClass);
 | 
				
			||||||
                // 记录异常信息
 | 
					                // 记录异常信息
 | 
				
			||||||
@@ -111,6 +112,32 @@ public class LogAspect {
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 是否要记录日志
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @param targetMethod 目标方法
 | 
				
			||||||
 | 
					     * @param targetClass  目标类
 | 
				
			||||||
 | 
					     * @return true:需要记录;false:不需要记录
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    private boolean isRequestRecord(Method targetMethod, Class<?> targetClass) {
 | 
				
			||||||
 | 
					        // 非 Web 环境不记录
 | 
				
			||||||
 | 
					        ServletRequestAttributes attributes = (ServletRequestAttributes)RequestContextHolder.getRequestAttributes();
 | 
				
			||||||
 | 
					        if (attributes == null || attributes.getResponse() == null) {
 | 
				
			||||||
 | 
					            return false;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        // 如果接口匹配排除列表,不记录日志
 | 
				
			||||||
 | 
					        if (logProperties.isMatch(attributes.getRequest().getRequestURI())) {
 | 
				
			||||||
 | 
					            return false;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        // 如果接口方法或类上有 @Log 注解,且要求忽略该接口,则不记录日志
 | 
				
			||||||
 | 
					        Log methodLog = AnnotationUtil.getAnnotation(targetMethod, Log.class);
 | 
				
			||||||
 | 
					        if (null != methodLog && methodLog.ignore()) {
 | 
				
			||||||
 | 
					            return false;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        Log classLog = AnnotationUtil.getAnnotation(targetClass, Log.class);
 | 
				
			||||||
 | 
					        return null == classLog || !classLog.ignore();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
     * 获取方法
 | 
					     * 获取方法
 | 
				
			||||||
     *
 | 
					     *
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -30,7 +30,9 @@ import top.continew.starter.log.aspect.LogAspect;
 | 
				
			|||||||
import top.continew.starter.log.dao.LogDao;
 | 
					import top.continew.starter.log.dao.LogDao;
 | 
				
			||||||
import top.continew.starter.log.dao.impl.DefaultLogDaoImpl;
 | 
					import top.continew.starter.log.dao.impl.DefaultLogDaoImpl;
 | 
				
			||||||
import top.continew.starter.log.handler.AopLogHandler;
 | 
					import top.continew.starter.log.handler.AopLogHandler;
 | 
				
			||||||
 | 
					import top.continew.starter.log.handler.LogFilter;
 | 
				
			||||||
import top.continew.starter.log.handler.LogHandler;
 | 
					import top.continew.starter.log.handler.LogHandler;
 | 
				
			||||||
 | 
					import top.continew.starter.log.model.LogProperties;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * 日志自动配置
 | 
					 * 日志自动配置
 | 
				
			||||||
@@ -52,6 +54,15 @@ public class LogAutoConfiguration {
 | 
				
			|||||||
        this.logProperties = logProperties;
 | 
					        this.logProperties = logProperties;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 日志过滤器
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    @Bean
 | 
				
			||||||
 | 
					    @ConditionalOnMissingBean
 | 
				
			||||||
 | 
					    public LogFilter logFilter() {
 | 
				
			||||||
 | 
					        return new LogFilter(logProperties);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
     * 日志切面
 | 
					     * 日志切面
 | 
				
			||||||
     *
 | 
					     *
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,76 +0,0 @@
 | 
				
			|||||||
/*
 | 
					 | 
				
			||||||
 * Copyright (c) 2022-present Charles7c Authors. All Rights Reserved.
 | 
					 | 
				
			||||||
 * <p>
 | 
					 | 
				
			||||||
 * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 3.0;
 | 
					 | 
				
			||||||
 * you may not use this file except in compliance with the License.
 | 
					 | 
				
			||||||
 * You may obtain a copy of the License at
 | 
					 | 
				
			||||||
 * <p>
 | 
					 | 
				
			||||||
 * http://www.gnu.org/licenses/lgpl.html
 | 
					 | 
				
			||||||
 * <p>
 | 
					 | 
				
			||||||
 * Unless required by applicable law or agreed to in writing, software
 | 
					 | 
				
			||||||
 * distributed under the License is distributed on an "AS IS" BASIS,
 | 
					 | 
				
			||||||
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
					 | 
				
			||||||
 * See the License for the specific language governing permissions and
 | 
					 | 
				
			||||||
 * limitations under the License.
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
package top.continew.starter.log.autoconfigure;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import org.springframework.boot.context.properties.ConfigurationProperties;
 | 
					 | 
				
			||||||
import top.continew.starter.core.constant.PropertiesConstants;
 | 
					 | 
				
			||||||
import top.continew.starter.log.enums.Include;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import java.util.Set;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * 日志配置属性
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * @author Charles7c
 | 
					 | 
				
			||||||
 * @author echo
 | 
					 | 
				
			||||||
 * @since 1.1.0
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
@ConfigurationProperties(PropertiesConstants.LOG)
 | 
					 | 
				
			||||||
public class LogProperties {
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /**
 | 
					 | 
				
			||||||
     * 是否启用日志
 | 
					 | 
				
			||||||
     */
 | 
					 | 
				
			||||||
    private boolean enabled = true;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /**
 | 
					 | 
				
			||||||
     * 是否打印日志,开启后可打印访问日志(类似于 Nginx access log)
 | 
					 | 
				
			||||||
     * <p>
 | 
					 | 
				
			||||||
     * 不记录日志也支持开启打印访问日志
 | 
					 | 
				
			||||||
     * </p>
 | 
					 | 
				
			||||||
     */
 | 
					 | 
				
			||||||
    private Boolean isPrint = false;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /**
 | 
					 | 
				
			||||||
     * 包含信息
 | 
					 | 
				
			||||||
     */
 | 
					 | 
				
			||||||
    private Set<Include> includes = Include.defaultIncludes();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    public boolean isEnabled() {
 | 
					 | 
				
			||||||
        return enabled;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    public void setEnabled(boolean enabled) {
 | 
					 | 
				
			||||||
        this.enabled = enabled;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    public Boolean getIsPrint() {
 | 
					 | 
				
			||||||
        return isPrint;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    public void setIsPrint(Boolean print) {
 | 
					 | 
				
			||||||
        isPrint = print;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    public Set<Include> getIncludes() {
 | 
					 | 
				
			||||||
        return includes;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    public void setIncludes(Set<Include> includes) {
 | 
					 | 
				
			||||||
        this.includes = includes;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@@ -28,7 +28,7 @@ import org.springframework.web.filter.OncePerRequestFilter;
 | 
				
			|||||||
import org.springframework.web.util.ContentCachingRequestWrapper;
 | 
					import org.springframework.web.util.ContentCachingRequestWrapper;
 | 
				
			||||||
import org.springframework.web.util.ContentCachingResponseWrapper;
 | 
					import org.springframework.web.util.ContentCachingResponseWrapper;
 | 
				
			||||||
import org.springframework.web.util.WebUtils;
 | 
					import org.springframework.web.util.WebUtils;
 | 
				
			||||||
import top.continew.starter.log.autoconfigure.LogProperties;
 | 
					import top.continew.starter.log.model.LogProperties;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import java.io.IOException;
 | 
					import java.io.IOException;
 | 
				
			||||||
import java.net.URI;
 | 
					import java.net.URI;
 | 
				
			||||||
@@ -14,7 +14,7 @@
 | 
				
			|||||||
 * limitations under the License.
 | 
					 * limitations under the License.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
package top.continew.starter.log.autoconfigure;
 | 
					package top.continew.starter.log.model;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import org.springframework.boot.context.properties.ConfigurationProperties;
 | 
					import org.springframework.boot.context.properties.ConfigurationProperties;
 | 
				
			||||||
import top.continew.starter.core.constant.PropertiesConstants;
 | 
					import top.continew.starter.core.constant.PropertiesConstants;
 | 
				
			||||||
@@ -33,6 +33,7 @@ import top.continew.starter.log.handler.InterceptorLogHandler;
 | 
				
			|||||||
import top.continew.starter.log.handler.LogFilter;
 | 
					import top.continew.starter.log.handler.LogFilter;
 | 
				
			||||||
import top.continew.starter.log.handler.LogHandler;
 | 
					import top.continew.starter.log.handler.LogHandler;
 | 
				
			||||||
import top.continew.starter.log.interceptor.LogInterceptor;
 | 
					import top.continew.starter.log.interceptor.LogInterceptor;
 | 
				
			||||||
 | 
					import top.continew.starter.log.model.LogProperties;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * 日志自动配置
 | 
					 * 日志自动配置
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -27,7 +27,7 @@ import org.springframework.lang.NonNull;
 | 
				
			|||||||
import org.springframework.web.method.HandlerMethod;
 | 
					import org.springframework.web.method.HandlerMethod;
 | 
				
			||||||
import org.springframework.web.servlet.HandlerInterceptor;
 | 
					import org.springframework.web.servlet.HandlerInterceptor;
 | 
				
			||||||
import top.continew.starter.log.annotation.Log;
 | 
					import top.continew.starter.log.annotation.Log;
 | 
				
			||||||
import top.continew.starter.log.autoconfigure.LogProperties;
 | 
					import top.continew.starter.log.model.LogProperties;
 | 
				
			||||||
import top.continew.starter.log.dao.LogDao;
 | 
					import top.continew.starter.log.dao.LogDao;
 | 
				
			||||||
import top.continew.starter.log.handler.LogHandler;
 | 
					import top.continew.starter.log.handler.LogHandler;
 | 
				
			||||||
import top.continew.starter.log.model.LogRecord;
 | 
					import top.continew.starter.log.model.LogRecord;
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user