feat: 完成日志
This commit is contained in:
parent
0ab915a03e
commit
056c32e11a
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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<LoggingTextModifier> modifiers) {
|
||||
return new LoggingTextRegistry(modifiers);
|
||||
}
|
||||
|
||||
/**
|
||||
* 日志管理器,线程池
|
||||
*
|
||||
* @return 结果
|
||||
*/
|
||||
@Bean
|
||||
public LogManager logManager() {
|
||||
return new LogManager();
|
||||
}
|
||||
}
|
||||
|
@ -40,7 +40,10 @@ public class Log extends Domain {
|
||||
private Long period;
|
||||
|
||||
// 操作时间
|
||||
private Date createTime;
|
||||
private Date startTime;
|
||||
|
||||
// 完成时间
|
||||
private Date endTime;
|
||||
|
||||
// 操作人
|
||||
private String operator;
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user