mirror of
https://github.com/continew-org/continew-starter.git
synced 2025-09-09 20:57:23 +08:00
refactor(log): 优化日志模块
This commit is contained in:
@@ -33,6 +33,7 @@ import top.continew.starter.log.handler.InterceptorLogHandler;
|
||||
import top.continew.starter.log.handler.LogFilter;
|
||||
import top.continew.starter.log.handler.LogHandler;
|
||||
import top.continew.starter.log.interceptor.LogInterceptor;
|
||||
import top.continew.starter.log.model.LogProperties;
|
||||
|
||||
/**
|
||||
* 日志自动配置
|
||||
|
@@ -1,101 +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 top.continew.starter.web.util.SpringWebUtils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* 日志配置属性
|
||||
*
|
||||
* @author Charles7c
|
||||
* @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();
|
||||
|
||||
/**
|
||||
* 放行路由
|
||||
*/
|
||||
private List<String> excludePatterns = new ArrayList<>();
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
public List<String> getExcludePatterns() {
|
||||
return excludePatterns;
|
||||
}
|
||||
|
||||
public void setExcludePatterns(List<String> excludePatterns) {
|
||||
this.excludePatterns = excludePatterns;
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否匹配放行路由
|
||||
*
|
||||
* @param uri 请求 URI
|
||||
* @return 是否匹配
|
||||
*/
|
||||
public boolean isMatch(String uri) {
|
||||
return this.getExcludePatterns().stream().anyMatch(pattern -> SpringWebUtils.isMatch(uri, pattern));
|
||||
}
|
||||
}
|
@@ -1,148 +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.handler;
|
||||
|
||||
import cn.hutool.extra.spring.SpringUtil;
|
||||
import jakarta.servlet.FilterChain;
|
||||
import jakarta.servlet.ServletException;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import org.springframework.boot.autoconfigure.web.ServerProperties;
|
||||
import org.springframework.core.Ordered;
|
||||
import org.springframework.lang.NonNull;
|
||||
import org.springframework.web.filter.OncePerRequestFilter;
|
||||
import org.springframework.web.util.ContentCachingRequestWrapper;
|
||||
import org.springframework.web.util.ContentCachingResponseWrapper;
|
||||
import org.springframework.web.util.WebUtils;
|
||||
import top.continew.starter.log.autoconfigure.LogProperties;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* 日志过滤器
|
||||
*
|
||||
* @author Dave Syer(Spring Boot Actuator)
|
||||
* @author Wallace Wadge(Spring Boot Actuator)
|
||||
* @author Andy Wilkinson(Spring Boot Actuator)
|
||||
* @author Venil Noronha(Spring Boot Actuator)
|
||||
* @author Madhura Bhave(Spring Boot Actuator)
|
||||
* @author Charles7c
|
||||
* @since 1.1.0
|
||||
*/
|
||||
public class LogFilter extends OncePerRequestFilter implements Ordered {
|
||||
|
||||
private final LogProperties logProperties;
|
||||
|
||||
public LogFilter(LogProperties logProperties) {
|
||||
this.logProperties = logProperties;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getOrder() {
|
||||
return Ordered.LOWEST_PRECEDENCE - 10;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doFilterInternal(@NonNull HttpServletRequest request,
|
||||
@NonNull HttpServletResponse response,
|
||||
@NonNull FilterChain filterChain) throws ServletException, IOException {
|
||||
if (!this.isFilter(request)) {
|
||||
filterChain.doFilter(request, response);
|
||||
return;
|
||||
}
|
||||
boolean isMatch = logProperties.isMatch(request.getRequestURI());
|
||||
// 包装输入流,可重复读取
|
||||
if (!isMatch && this.isRequestWrapper(request)) {
|
||||
request = new ContentCachingRequestWrapper(request);
|
||||
}
|
||||
// 包装输出流,可重复读取
|
||||
boolean isResponseWrapper = !isMatch && this.isResponseWrapper(response);
|
||||
if (isResponseWrapper) {
|
||||
response = new ContentCachingResponseWrapper(response);
|
||||
}
|
||||
filterChain.doFilter(request, response);
|
||||
// 更新响应(不操作这一步,会导致接口响应空白)
|
||||
if (isResponseWrapper) {
|
||||
this.updateResponse(response);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否过滤请求
|
||||
*
|
||||
* @param request 请求对象
|
||||
* @return 是否过滤请求
|
||||
*/
|
||||
private boolean isFilter(HttpServletRequest request) {
|
||||
if (!isRequestValid(request)) {
|
||||
return false;
|
||||
}
|
||||
// 不拦截 /error
|
||||
ServerProperties serverProperties = SpringUtil.getBean(ServerProperties.class);
|
||||
return !request.getRequestURI().equals(serverProperties.getError().getPath());
|
||||
}
|
||||
|
||||
/**
|
||||
* 请求是否有效
|
||||
*
|
||||
* @param request 请求对象
|
||||
* @return true:是;false:否
|
||||
*/
|
||||
private boolean isRequestValid(HttpServletRequest request) {
|
||||
try {
|
||||
new URI(request.getRequestURL().toString());
|
||||
return true;
|
||||
} catch (URISyntaxException e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否需要包装输入流
|
||||
*
|
||||
* @param request 请求对象
|
||||
* @return true:是;false:否
|
||||
*/
|
||||
private boolean isRequestWrapper(HttpServletRequest request) {
|
||||
return !(request instanceof ContentCachingRequestWrapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否需要包装输出流
|
||||
*
|
||||
* @param response 响应对象
|
||||
* @return true:是;false:否
|
||||
*/
|
||||
private boolean isResponseWrapper(HttpServletResponse response) {
|
||||
return !(response instanceof ContentCachingResponseWrapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新响应
|
||||
*
|
||||
* @param response 响应对象
|
||||
* @throws IOException /
|
||||
*/
|
||||
private void updateResponse(HttpServletResponse response) throws IOException {
|
||||
ContentCachingResponseWrapper responseWrapper = WebUtils
|
||||
.getNativeResponse(response, ContentCachingResponseWrapper.class);
|
||||
Objects.requireNonNull(responseWrapper).copyBodyToResponse();
|
||||
}
|
||||
}
|
@@ -27,7 +27,7 @@ import org.springframework.lang.NonNull;
|
||||
import org.springframework.web.method.HandlerMethod;
|
||||
import org.springframework.web.servlet.HandlerInterceptor;
|
||||
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.handler.LogHandler;
|
||||
import top.continew.starter.log.model.LogRecord;
|
||||
|
Reference in New Issue
Block a user