refactor(log): 新增 LogHandler 提升日志模块的复用性

This commit is contained in:
2024-12-23 20:51:42 +08:00
parent 265c669eda
commit 0d334523e9
9 changed files with 460 additions and 238 deletions

View File

@@ -0,0 +1,143 @@
/*
* 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.core.annotation.AnnotationUtil;
import cn.hutool.core.text.CharSequenceUtil;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import top.continew.starter.log.annotation.Log;
import top.continew.starter.log.enums.Include;
import top.continew.starter.log.http.recordable.impl.RecordableServletHttpRequest;
import top.continew.starter.log.http.recordable.impl.RecordableServletHttpResponse;
import top.continew.starter.log.model.LogRecord;
import java.lang.reflect.Method;
import java.time.Instant;
import java.util.HashSet;
import java.util.Set;
/**
* 日志处理器基类
*
* @author Charles7c
* @since 2.8.0
*/
public abstract class AbstractLogHandler implements LogHandler {
@Override
public LogRecord.Started start(Instant startTime, HttpServletRequest request) {
return LogRecord.start(startTime, new RecordableServletHttpRequest(request));
}
@Override
public LogRecord finish(LogRecord.Started started,
Instant endTime,
HttpServletResponse response,
Set<Include> includes,
Method targetMethod,
Class<?> targetClass) {
Set<Include> includeSet = this.getIncludes(includes, targetMethod, targetClass);
LogRecord logRecord = this.finish(started, endTime, response, includeSet);
// 记录日志描述
if (includeSet.contains(Include.DESCRIPTION)) {
this.logDescription(logRecord, targetMethod);
}
// 记录所属模块
if (includeSet.contains(Include.MODULE)) {
this.logModule(logRecord, targetMethod, targetClass);
}
return logRecord;
}
@Override
public LogRecord finish(LogRecord.Started started,
Instant endTime,
HttpServletResponse response,
Set<Include> includes) {
return started.finish(endTime, new RecordableServletHttpResponse(response, response.getStatus()), includes);
}
/**
* 记录日志描述
*
* @param logRecord 日志记录
* @param targetMethod 目标方法
*/
@Override
public void logDescription(LogRecord logRecord, Method targetMethod) {
Log methodLog = AnnotationUtil.getAnnotation(targetMethod, Log.class);
// 例如:@Log("新增部门") -> 新增部门
if (null != methodLog && CharSequenceUtil.isNotBlank(methodLog.value())) {
logRecord.setDescription(methodLog.value());
}
}
/**
* 记录所属模块
*
* @param logRecord 日志记录
* @param targetMethod 目标方法
* @param targetClass 目标类
*/
@Override
public void logModule(LogRecord logRecord, Method targetMethod, Class<?> targetClass) {
Log methodLog = AnnotationUtil.getAnnotation(targetMethod, Log.class);
// 例如:@Log(module = "部门管理") -> 部门管理
// 方法级注解优先级高于类级注解
if (null != methodLog && CharSequenceUtil.isNotBlank(methodLog.module())) {
logRecord.setModule(methodLog.module());
return;
}
Log classLog = AnnotationUtil.getAnnotation(targetClass, Log.class);
if (null != classLog && CharSequenceUtil.isNotBlank(classLog.module())) {
logRecord.setModule(classLog.module());
}
}
@Override
public Set<Include> getIncludes(Set<Include> includes, Method targetMethod, Class<?> targetClass) {
Log classLog = AnnotationUtil.getAnnotation(targetClass, Log.class);
Set<Include> includeSet = new HashSet<>(includes);
if (null != classLog) {
this.processInclude(includeSet, classLog);
}
// 方法级注解优先级高于类级注解
Log methodLog = AnnotationUtil.getAnnotation(targetMethod, Log.class);
if (null != methodLog) {
this.processInclude(includeSet, methodLog);
}
return includeSet;
}
/**
* 处理日志包含信息
*
* @param includes 日志包含信息
* @param logAnnotation Log 注解
*/
private void processInclude(Set<Include> includes, Log logAnnotation) {
Include[] includeArr = logAnnotation.includes();
if (includeArr.length > 0) {
includes.addAll(Set.of(includeArr));
}
Include[] excludeArr = logAnnotation.excludes();
if (excludeArr.length > 0) {
includes.removeAll(Set.of(excludeArr));
}
}
}

View File

@@ -0,0 +1,100 @@
/*
* 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 jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import top.continew.starter.log.enums.Include;
import top.continew.starter.log.model.LogRecord;
import java.lang.reflect.Method;
import java.time.Instant;
import java.util.Set;
/**
* 日志处理器
*
* @author Charles7c
* @since 2.8.0
*/
public interface LogHandler {
/**
* 开始日志记录
*
* @param startTime 开始时间
* @param request 请求对象
* @return 日志记录器
*/
LogRecord.Started start(Instant startTime, HttpServletRequest request);
/**
* 结束日志记录
*
* @param started 开始日志记录器
* @param endTime 结束时间
* @param response 响应对象
* @param includes 包含信息
* @return 日志记录
*/
LogRecord finish(LogRecord.Started started, Instant endTime, HttpServletResponse response, Set<Include> includes);
/**
* 结束日志记录
*
* @param started 开始日志记录器-
* @param endTime 结束时间
* @param response 响应对象
* @param includes 包含信息
* @param targetMethod 目标方法
* @param targetClass 目标类
* @return 日志记录
*/
LogRecord finish(LogRecord.Started started,
Instant endTime,
HttpServletResponse response,
Set<Include> includes,
Method targetMethod,
Class<?> targetClass);
/**
* 记录日志描述
*
* @param logRecord 日志记录
* @param targetMethod 目标方法
*/
void logDescription(LogRecord logRecord, Method targetMethod);
/**
* 记录所属模块
*
* @param logRecord 日志记录
* @param targetMethod 目标方法
* @param targetClass 目标类
*/
void logModule(LogRecord logRecord, Method targetMethod, Class<?> targetClass);
/**
* 获取日志包含信息
*
* @param includes 默认包含信息
* @param targetMethod 目标方法
* @param targetClass 目标类
* @return 日志包含信息
*/
Set<Include> getIncludes(Set<Include> includes, Method targetMethod, Class<?> targetClass);
}