org.rx.spring.BaseInterceptor Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of rxlib Show documentation
Show all versions of rxlib Show documentation
A set of utilities for Java
package org.rx.spring;
import io.netty.util.concurrent.FastThreadLocal;
import org.apache.commons.lang3.BooleanUtils;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.reflect.MethodSignature;
import org.rx.bean.FlagsEnum;
import org.rx.bean.ProceedEventArgs;
import org.rx.core.*;
import org.rx.exception.TraceHandler;
import java.util.List;
import static org.rx.core.Extends.as;
import static org.rx.core.Sys.*;
public abstract class BaseInterceptor implements EventPublisher {
static final int MAX_FIELD_SIZE = 1024 * 4;
static final FastThreadLocal idempotent = new FastThreadLocal<>();
public final Delegate onProcessing = Delegate.create(),
onProceed = Delegate.create(),
onError = Delegate.create();
@Override
public FlagsEnum eventFlags() {
return EventFlags.DYNAMIC_ATTACH.flags(EventFlags.QUIETLY);
}
protected final void enableTrace(String traceName) {
if (traceName == null) {
traceName = Constants.DEFAULT_TRACE_NAME;
}
RxConfig.ThreadPoolConfig conf = RxConfig.INSTANCE.getThreadPool();
conf.setTraceName(traceName);
ThreadPool.onTraceIdChanged.first((s, e) -> logCtx(conf.getTraceName(), e.getValue()));
}
protected String startTrace(JoinPoint joinPoint, String parentTraceId) {
return ThreadPool.startTrace(parentTraceId);
}
public Object doAround(ProceedingJoinPoint joinPoint) throws Throwable {
if (BooleanUtils.isTrue(idempotent.get())) {
return joinPoint.proceed();
}
idempotent.set(Boolean.TRUE);
String tn = RxConfig.INSTANCE.getThreadPool().getTraceName();
if (tn != null) {
logCtxIfAbsent(tn, startTrace(joinPoint, null));
}
try {
Signature signature = joinPoint.getSignature();
MethodSignature methodSignature = as(signature, MethodSignature.class);
boolean isVoid = methodSignature == null || methodSignature.getReturnType().equals(void.class);
ProceedEventArgs pe = new ProceedEventArgs(signature.getDeclaringType(), joinPoint.getArgs(), isVoid);
raiseEvent(onProcessing, pe);
if (pe.isCancel()) {
return joinPoint.proceed();
}
RxConfig conf = RxConfig.INSTANCE;
pe.setLogStrategy(conf.getLogStrategy());
pe.setLogTypeWhitelist(conf.getLogTypeWhitelist());
String paramSnapshot = jsonString(signature, pe.getParameters());
try {
pe.proceed(() -> joinPoint.proceed(pe.getParameters()));
} catch (Throwable e) {
pe.setError(e);
raiseEvent(onError, pe);
if (pe.getError() != null) {
throw pe.getError();
}
} finally {
TraceHandler.INSTANCE.saveMethodTrace(pe, signature.getName());
onLog(signature, pe, paramSnapshot);
raiseEvent(onProceed, pe);
}
return pe.getReturnValue();
} finally {
ThreadPool.endTrace();
clearLogCtx();
idempotent.remove();
}
}
protected void onLog(Signature signature, ProceedEventArgs eventArgs, String paramSnapshot) {
log(eventArgs, msg -> {
msg.appendLine("Call:\t%s", signature.getName());
msg.appendLine("Parameters:\t%s", paramSnapshot)
.appendLine("ReturnValue:\t%s\tElapsed=%s", jsonString(signature, eventArgs.getReturnValue()), Sys.formatNanosElapsed(eventArgs.getElapsedNanos()));
if (eventArgs.getError() != null) {
msg.appendLine("Error:\t%s", eventArgs.getError().getMessage());
}
});
}
private String jsonString(Signature signature, Object... args) {
if (Arrays.isEmpty(args)) {
return "{}";
}
List