|
|
|
@ -17,18 +17,26 @@
|
|
|
|
|
|
|
|
|
|
package org.apache.dolphinscheduler.api.audit; |
|
|
|
|
|
|
|
|
|
import org.apache.dolphinscheduler.api.audit.enums.AuditType; |
|
|
|
|
import org.apache.dolphinscheduler.api.audit.operator.AuditOperator; |
|
|
|
|
import org.apache.dolphinscheduler.api.utils.Result; |
|
|
|
|
import org.apache.dolphinscheduler.dao.entity.AuditLog; |
|
|
|
|
import org.apache.dolphinscheduler.dao.entity.User; |
|
|
|
|
import org.apache.dolphinscheduler.service.bean.SpringApplicationContext; |
|
|
|
|
|
|
|
|
|
import java.lang.reflect.Method; |
|
|
|
|
import java.util.List; |
|
|
|
|
import java.util.Map; |
|
|
|
|
|
|
|
|
|
import lombok.AllArgsConstructor; |
|
|
|
|
import lombok.Getter; |
|
|
|
|
import lombok.Setter; |
|
|
|
|
import lombok.extern.slf4j.Slf4j; |
|
|
|
|
|
|
|
|
|
import org.aspectj.lang.ProceedingJoinPoint; |
|
|
|
|
import org.aspectj.lang.annotation.Around; |
|
|
|
|
import org.aspectj.lang.JoinPoint; |
|
|
|
|
import org.aspectj.lang.annotation.AfterReturning; |
|
|
|
|
import org.aspectj.lang.annotation.AfterThrowing; |
|
|
|
|
import org.aspectj.lang.annotation.Aspect; |
|
|
|
|
import org.aspectj.lang.annotation.Before; |
|
|
|
|
import org.aspectj.lang.annotation.Pointcut; |
|
|
|
|
import org.aspectj.lang.reflect.MethodSignature; |
|
|
|
|
import org.springframework.stereotype.Component; |
|
|
|
@ -40,34 +48,74 @@ import io.swagger.v3.oas.annotations.Operation;
|
|
|
|
|
@Component |
|
|
|
|
public class OperatorLogAspect { |
|
|
|
|
|
|
|
|
|
private static final ThreadLocal<AuditContext> auditThreadLocal = new ThreadLocal<>(); |
|
|
|
|
|
|
|
|
|
@Pointcut("@annotation(org.apache.dolphinscheduler.api.audit.OperatorLog)") |
|
|
|
|
public void logPointCut() { |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
@Around("logPointCut()") |
|
|
|
|
public Object around(ProceedingJoinPoint point) throws Throwable { |
|
|
|
|
@Before("logPointCut()") |
|
|
|
|
public void before(JoinPoint point) { |
|
|
|
|
MethodSignature signature = (MethodSignature) point.getSignature(); |
|
|
|
|
Method method = signature.getMethod(); |
|
|
|
|
|
|
|
|
|
OperatorLog operatorLog = method.getAnnotation(OperatorLog.class); |
|
|
|
|
|
|
|
|
|
Operation operation = method.getAnnotation(Operation.class); |
|
|
|
|
|
|
|
|
|
if (operation == null) { |
|
|
|
|
log.warn("Operation is null of method: {}", method.getName()); |
|
|
|
|
return point.proceed(); |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
long beginTime = System.currentTimeMillis(); |
|
|
|
|
|
|
|
|
|
Map<String, Object> paramsMap = OperatorUtils.getParamsMap(point, signature); |
|
|
|
|
Result<?> result = (Result<?>) point.proceed(); |
|
|
|
|
User user = OperatorUtils.getUser(paramsMap); |
|
|
|
|
if (user == null) { |
|
|
|
|
log.error("user is null"); |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
AuditType auditType = operatorLog.auditType(); |
|
|
|
|
|
|
|
|
|
try { |
|
|
|
|
AuditOperator operator = SpringApplicationContext.getBean(operatorLog.auditType().getOperatorClass()); |
|
|
|
|
long latency = System.currentTimeMillis() - beginTime; |
|
|
|
|
operator.recordAudit(paramsMap, result, latency, operation, operatorLog); |
|
|
|
|
List<AuditLog> auditLogList = OperatorUtils.buildAuditLogList(operation.description(), auditType, user); |
|
|
|
|
operator.setRequestParam(auditType, auditLogList, paramsMap); |
|
|
|
|
AuditContext auditContext = |
|
|
|
|
new AuditContext(auditLogList, paramsMap, operatorLog, System.currentTimeMillis(), operator); |
|
|
|
|
auditThreadLocal.set(auditContext); |
|
|
|
|
} catch (Throwable throwable) { |
|
|
|
|
log.error("Record audit log error", throwable); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
@AfterReturning(value = "logPointCut()", returning = "returnValue") |
|
|
|
|
public void afterReturning(Object returnValue) { |
|
|
|
|
try { |
|
|
|
|
AuditContext auditContext = auditThreadLocal.get(); |
|
|
|
|
if (auditContext == null) { |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
auditContext.getOperator().recordAudit(auditContext, returnValue); |
|
|
|
|
} catch (Throwable throwable) { |
|
|
|
|
log.error("Record audit log error", throwable); |
|
|
|
|
} finally { |
|
|
|
|
auditThreadLocal.remove(); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
@AfterThrowing("logPointCut()") |
|
|
|
|
public void afterThrowing() { |
|
|
|
|
auditThreadLocal.remove(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
@Getter |
|
|
|
|
@Setter |
|
|
|
|
@AllArgsConstructor |
|
|
|
|
public static class AuditContext { |
|
|
|
|
|
|
|
|
|
return result; |
|
|
|
|
List<AuditLog> auditLogList; |
|
|
|
|
Map<String, Object> paramsMap; |
|
|
|
|
OperatorLog operatorLog; |
|
|
|
|
long beginTime; |
|
|
|
|
AuditOperator operator; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|