From 056c32e11a74254aadd67ae0ed5f6097fde5cbd6 Mon Sep 17 00:00:00 2001 From: wangyu <727842003@qq.com> Date: Thu, 14 Jan 2021 14:47:15 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E5=AE=8C=E6=88=90=E6=97=A5=E5=BF=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../framework/logging/advice/LogAdvice.java | 21 +-- .../logging/config/LoggingConfig.java | 15 +- .../flyfish/framework/logging/domain/Log.java | 5 +- .../framework/logging/service/LogContext.java | 128 ++++++++++++++++++ .../framework/logging/service/LogManager.java | 89 +++++------- 5 files changed, 193 insertions(+), 65 deletions(-) create mode 100644 flyfish-logging/src/main/java/com/flyfish/framework/logging/service/LogContext.java diff --git a/flyfish-logging/src/main/java/com/flyfish/framework/logging/advice/LogAdvice.java b/flyfish-logging/src/main/java/com/flyfish/framework/logging/advice/LogAdvice.java index 48cb901..002fef9 100644 --- a/flyfish-logging/src/main/java/com/flyfish/framework/logging/advice/LogAdvice.java +++ b/flyfish-logging/src/main/java/com/flyfish/framework/logging/advice/LogAdvice.java @@ -1,6 +1,8 @@ package com.flyfish.framework.logging.advice; +import com.flyfish.framework.logging.service.LogContext; import com.flyfish.framework.logging.service.LogManager; +import lombok.RequiredArgsConstructor; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Aspect; @@ -14,10 +16,10 @@ import javax.annotation.Resource; * @author wangyu */ @Aspect +@RequiredArgsConstructor public class LogAdvice { - @Resource - private LogManager logManager; + private final LogManager logManager; /** * 切入注解 @@ -36,17 +38,20 @@ public class LogAdvice { */ @Around("pointCut()") public Object process(ProceedingJoinPoint joinPoint) throws Throwable { - Object[] args = joinPoint.getArgs(); - Throwable e = null; - Object result = null; + // 构建上下文 + LogContext context = LogContext.of(joinPoint); try { - result = joinPoint.proceed(args); + Object result = joinPoint.proceed(joinPoint.getArgs()); + context.setResult(result); return result; } catch (Throwable throwable) { - e = throwable; + context.setError(throwable); throw throwable; } finally { - logManager.tryLog(joinPoint, result, e); + if (context.isValid()) { + context.end(); + logManager.tryLog(context); + } } } } diff --git a/flyfish-logging/src/main/java/com/flyfish/framework/logging/config/LoggingConfig.java b/flyfish-logging/src/main/java/com/flyfish/framework/logging/config/LoggingConfig.java index 8e4e909..577b996 100644 --- a/flyfish-logging/src/main/java/com/flyfish/framework/logging/config/LoggingConfig.java +++ b/flyfish-logging/src/main/java/com/flyfish/framework/logging/config/LoggingConfig.java @@ -1,6 +1,7 @@ package com.flyfish.framework.logging.config; import com.flyfish.framework.logging.advice.LogAdvice; +import com.flyfish.framework.logging.service.LogManager; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.EnableAspectJAutoProxy; @@ -20,8 +21,8 @@ public class LoggingConfig { * @return 结果 */ @Bean - public LogAdvice logAdvice() { - return new LogAdvice(); + public LogAdvice logAdvice(LogManager manager) { + return new LogAdvice(manager); } /** @@ -33,4 +34,14 @@ public class LoggingConfig { public LoggingTextRegistry loggingTextRegistry(List modifiers) { return new LoggingTextRegistry(modifiers); } + + /** + * 日志管理器,线程池 + * + * @return 结果 + */ + @Bean + public LogManager logManager() { + return new LogManager(); + } } diff --git a/flyfish-logging/src/main/java/com/flyfish/framework/logging/domain/Log.java b/flyfish-logging/src/main/java/com/flyfish/framework/logging/domain/Log.java index 002f327..acb02b0 100644 --- a/flyfish-logging/src/main/java/com/flyfish/framework/logging/domain/Log.java +++ b/flyfish-logging/src/main/java/com/flyfish/framework/logging/domain/Log.java @@ -40,7 +40,10 @@ public class Log extends Domain { private Long period; // 操作时间 - private Date createTime; + private Date startTime; + + // 完成时间 + private Date endTime; // 操作人 private String operator; diff --git a/flyfish-logging/src/main/java/com/flyfish/framework/logging/service/LogContext.java b/flyfish-logging/src/main/java/com/flyfish/framework/logging/service/LogContext.java new file mode 100644 index 0000000..83aaa83 --- /dev/null +++ b/flyfish-logging/src/main/java/com/flyfish/framework/logging/service/LogContext.java @@ -0,0 +1,128 @@ +package com.flyfish.framework.logging.service; + +import com.flyfish.framework.annotations.Operation; +import com.flyfish.framework.beans.meta.RestBean; +import com.flyfish.framework.context.UserContext; +import com.flyfish.framework.domain.base.Domain; +import com.flyfish.framework.logging.domain.DomainDescriptions; +import com.flyfish.framework.utils.ReflectionUtils; +import lombok.AccessLevel; +import lombok.Data; +import lombok.Setter; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; +import org.aspectj.lang.ProceedingJoinPoint; +import org.aspectj.lang.Signature; +import org.aspectj.lang.reflect.MethodSignature; +import org.springframework.core.annotation.AnnotationUtils; +import org.springframework.data.util.CastUtils; + +import java.util.Optional; + +/** + * 日志上下文,线程协作好帮手 + * + * @author wangyu + */ +@Data +@Slf4j +public class LogContext { + + private static final LogContext UN_SUPPORT = new LogContext(); + + private long startTime; + + private long endTime; + + @Setter(AccessLevel.NONE) + private Throwable error; + + @Setter(AccessLevel.NONE) + private Object result; + + private Object[] args; + + private String module; + + private String business; + + private String signature; + + private String user; + + private boolean valid = false; + + public static LogContext unSupport() { + return UN_SUPPORT; + } + + /** + * 通过切入点创建 + * + * @param joinPoint 切入点 + * @return 结果 + */ + public static LogContext of(ProceedingJoinPoint joinPoint) { + Signature signature = joinPoint.getSignature(); + if (signature instanceof MethodSignature) { + MethodSignature methodSignature = (MethodSignature) signature; + Operation operation = AnnotationUtils.findAnnotation(methodSignature.getMethod(), Operation.class); + if (null != operation) { + LogContext context = new LogContext(); + context.startTime = System.currentTimeMillis(); + context.module = determineModule(operation, joinPoint.getTarget().getClass()); + context.business = operation.value(); + context.signature = joinPoint.getSignature().getName(); + context.args = joinPoint.getArgs(); + context.valid = true; + log.info("监测到支持的切点:{}, {}", context.module, operation.value()); + return context; + } + } + return UN_SUPPORT; + } + + /** + * 确定模块 + * + * @param operation 模块 + * @return 结果 + */ + private static String determineModule(Operation operation, Class targetClass) { + String module = operation.module(); + if (StringUtils.isBlank(module)) { + return ReflectionUtils.getGenericType(targetClass) + .flatMap(clazz -> { + DomainDescriptions description = DomainDescriptions.getByClass(CastUtils.cast(clazz)); + if (null != description) { + return Optional.of(description.getName()); + } + return Optional.ofNullable(AnnotationUtils.findAnnotation(clazz, RestBean.class)) + .map(RestBean::name); + }) + .orElse("未知模块"); + } + return module; + } + + public void setResult(Object result) { + if (valid) { + this.result = result; + } + } + + public void setError(Throwable error) { + if (valid) { + this.error = error; + } + } + + public boolean isSuccess() { + return null == error; + } + + public void end() { + this.user = UserContext.sharedContext().map(UserContext::currentUser).map(Domain::getName).orElse("未知"); + this.endTime = System.currentTimeMillis(); + } +} diff --git a/flyfish-logging/src/main/java/com/flyfish/framework/logging/service/LogManager.java b/flyfish-logging/src/main/java/com/flyfish/framework/logging/service/LogManager.java index c30ff6e..4af8883 100644 --- a/flyfish-logging/src/main/java/com/flyfish/framework/logging/service/LogManager.java +++ b/flyfish-logging/src/main/java/com/flyfish/framework/logging/service/LogManager.java @@ -1,81 +1,55 @@ package com.flyfish.framework.logging.service; import com.alibaba.fastjson.JSON; -import com.flyfish.framework.annotations.Operation; -import com.flyfish.framework.beans.meta.RestBean; -import com.flyfish.framework.context.UserContext; -import com.flyfish.framework.domain.base.Domain; -import com.flyfish.framework.logging.domain.DomainDescriptions; import com.flyfish.framework.logging.domain.Log; -import com.flyfish.framework.utils.ReflectionUtils; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.ArrayUtils; -import org.apache.commons.lang3.StringUtils; -import org.aspectj.lang.ProceedingJoinPoint; -import org.aspectj.lang.Signature; -import org.aspectj.lang.reflect.MethodSignature; -import org.springframework.core.annotation.AnnotationUtils; -import org.springframework.data.util.CastUtils; -import org.springframework.stereotype.Service; +import org.springframework.beans.factory.DisposableBean; import javax.annotation.Resource; +import java.util.Date; import java.util.Optional; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; /** * 日志管理器 * * @author wangyu */ -@Service @Slf4j -public class LogManager { +public class LogManager implements DisposableBean { + // 固定线程池 + private final ExecutorService executorService = Executors.newFixedThreadPool(20); @Resource private LogService logService; /** * 尝试记录日志 * - * @param joinPoint 接入点 - * @param e 异常 + * @param context 上下文 */ - public void tryLog(ProceedingJoinPoint joinPoint, Object result, Throwable e) { - Signature signature = joinPoint.getSignature(); - if (signature instanceof MethodSignature) { - MethodSignature methodSignature = (MethodSignature) signature; - Operation operation = AnnotationUtils.findAnnotation(methodSignature.getMethod(), Operation.class); - if (null != operation) { - String module = operation.module(); - Class targetClass = joinPoint.getTarget().getClass(); - if (StringUtils.isBlank(module)) { - module = ReflectionUtils.getGenericType(targetClass) - .flatMap(clazz -> { - DomainDescriptions description = DomainDescriptions.getByClass(CastUtils.cast(clazz)); - if (null != description) { - return Optional.of(description.getName()); - } - return Optional.ofNullable(AnnotationUtils.findAnnotation(clazz, RestBean.class)) - .map(RestBean::name); - }) - .orElse("未知模块"); - } - log.info("监测到支持的切点:{}, {}", module, operation.value()); - // 构建日志 - Log log = new Log(); - log.setSuccess(null == e); - log.setBody(bodyString(joinPoint.getArgs())); - log.setModule(module); - log.setBusiness(operation.value()); - log.setError(Optional.ofNullable(e).map(JSON::toJSONString).orElse(null)); - log.setResponse(Optional.ofNullable(result).map(JSON::toJSONString).orElse(null)); - log.setOperator(UserContext.sharedContext().map(UserContext::currentUser).map(Domain::getName).orElse("未知")); - log.setSignature(joinPoint.getSignature().getName()); - // 先不拼接 - log.setUri(null); - // 写入日志 - logService.create(log); - } - } + public void tryLog(LogContext context) { + executorService.execute(() -> { + // 构建日志 + Log log = new Log(); + log.setSuccess(context.isSuccess()); + log.setBody(bodyString(context.getArgs())); + log.setModule(context.getModule()); + log.setBusiness(context.getBusiness()); + log.setError(Optional.ofNullable(context.getError()).map(JSON::toJSONString).orElse(null)); + log.setResponse(Optional.ofNullable(context.getResult()).map(JSON::toJSONString).orElse(null)); + log.setOperator(context.getUser()); + log.setSignature(context.getSignature()); + log.setPeriod(context.getEndTime() - context.getStartTime()); + log.setStartTime(new Date(context.getStartTime())); + log.setEndTime(new Date(context.getEndTime())); + // 先不拼接 + log.setUri(null); + // 写入日志 + logService.create(log); + }); } private String bodyString(Object[] args) { @@ -87,4 +61,11 @@ public class LogManager { } return JSON.toJSONString(args); } + + @Override + public void destroy() { + if (!executorService.isShutdown()) { + executorService.shutdownNow(); + } + } }