|
|
|
@ -5,22 +5,18 @@ import com.fr.general.GeneralUtils;
|
|
|
|
|
import com.fr.intelli.measure.Estimator; |
|
|
|
|
import com.fr.intelli.metrics.Compute; |
|
|
|
|
import com.fr.intelli.metrics.MessageRecorderFactory; |
|
|
|
|
import com.fr.intelli.metrics.SessionBinder; |
|
|
|
|
import com.fr.intelli.metrics.SupervisoryConfig; |
|
|
|
|
import com.fr.intelli.record.Measurable; |
|
|
|
|
import com.fr.intelli.record.MeasureObject; |
|
|
|
|
import com.fr.intelli.record.MeasureUnit; |
|
|
|
|
import com.fr.log.FineLoggerFactory; |
|
|
|
|
import com.fr.measure.DBMeterFactory; |
|
|
|
|
import com.fr.stable.ArrayUtils; |
|
|
|
|
import com.fr.stable.StringUtils; |
|
|
|
|
import com.fr.stable.web.Session; |
|
|
|
|
import com.fr.stable.web.SessionProvider; |
|
|
|
|
import com.fr.third.net.bytebuddy.asm.Advice; |
|
|
|
|
import com.fr.third.net.bytebuddy.implementation.bytecode.assign.Assigner; |
|
|
|
|
import com.fr.web.core.SessionPoolManager; |
|
|
|
|
import com.fr.web.session.SessionLocalManager; |
|
|
|
|
|
|
|
|
|
import java.lang.annotation.Annotation; |
|
|
|
|
import java.lang.reflect.Method; |
|
|
|
|
import java.util.ArrayList; |
|
|
|
|
import java.util.Arrays; |
|
|
|
@ -33,32 +29,31 @@ import java.util.regex.Pattern;
|
|
|
|
|
* created by Harrison on 2022/03/07 |
|
|
|
|
**/ |
|
|
|
|
public class MonitorAdvice implements DesignerAnalyzerAdvice { |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private static final Pattern P = Pattern.compile("-?\\d+"); |
|
|
|
|
private static final int MIN_ERROR_CODE = 10000000; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@Advice.OnMethodEnter |
|
|
|
|
public static void onMethodEnter(@Advice.Origin Method method, |
|
|
|
|
@Advice.AllArguments(typing = Assigner.Typing.DYNAMIC) Object[] args, |
|
|
|
|
@Advice.Local("startTime") Long startTime, |
|
|
|
|
@Advice.Local("registeredSession") Boolean registeredSession) { |
|
|
|
|
|
|
|
|
|
@Advice.Local("sessionBinder") SessionBinder sessionBinder) { |
|
|
|
|
|
|
|
|
|
startTime = (System.currentTimeMillis()); |
|
|
|
|
registeredSession = (findSessionAnnotation(method, args)); |
|
|
|
|
sessionBinder = new SessionBinder(); |
|
|
|
|
sessionBinder.attachSession(method, args); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@Advice.OnMethodExit(onThrowable = Exception.class) |
|
|
|
|
public static void onMethodExit(@Advice.This(optional = true, typing = Assigner.Typing.DYNAMIC) Object self, |
|
|
|
|
@Advice.Origin Method method, |
|
|
|
|
@Advice.AllArguments(typing = Assigner.Typing.DYNAMIC) Object[] args, |
|
|
|
|
@Advice.Thrown(typing = Assigner.Typing.DYNAMIC) Exception e, |
|
|
|
|
@Advice.Local("startTime") Long startTime, |
|
|
|
|
@Advice.Local("registeredSession") Boolean registeredSession) throws Exception { |
|
|
|
|
|
|
|
|
|
@Advice.Local("sessionBinder") SessionBinder sessionBinder) throws Exception { |
|
|
|
|
|
|
|
|
|
String error = StringUtils.EMPTY; |
|
|
|
|
|
|
|
|
|
try { |
|
|
|
|
|
|
|
|
|
if (e != null) { |
|
|
|
|
try { |
|
|
|
|
error = getErrorContent(e); |
|
|
|
@ -95,14 +90,11 @@ public class MonitorAdvice implements DesignerAnalyzerAdvice {
|
|
|
|
|
} catch (Exception ignore) { |
|
|
|
|
//埋点信息入库失败应该不能影响业务流程
|
|
|
|
|
} finally { |
|
|
|
|
if (registeredSession) { |
|
|
|
|
// 如果上面记录了,这里就要释放
|
|
|
|
|
SessionLocalManager.releaseSession(); |
|
|
|
|
} |
|
|
|
|
sessionBinder.detachSession(); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public static String getErrorContent(Exception e) { |
|
|
|
|
int errorCode = GeneralUtils.objectToNumber( |
|
|
|
|
extractCodeFromString(e.getMessage()) |
|
|
|
@ -110,7 +102,7 @@ public class MonitorAdvice implements DesignerAnalyzerAdvice {
|
|
|
|
|
// 提取字符串中的第一个数字,最小的错误码为10000000
|
|
|
|
|
return e.getClass().getName() + ":" + (errorCode >= MIN_ERROR_CODE ? errorCode : StringUtils.EMPTY); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public static String extractCodeFromString(String errorMsg) { |
|
|
|
|
Matcher m = P.matcher(errorMsg); |
|
|
|
|
if (m.find()) { |
|
|
|
@ -118,38 +110,22 @@ public class MonitorAdvice implements DesignerAnalyzerAdvice {
|
|
|
|
|
} |
|
|
|
|
return StringUtils.EMPTY; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public static void recordSQLDetail(String uuid) { |
|
|
|
|
DBMeterFactory.getMeter().submit(uuid); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public static void recordSQL(Compute once, MeasureObject measureObject) { |
|
|
|
|
if (SupervisoryConfig.getInstance().isEnableMeasureSql() && once.computeSql()) { |
|
|
|
|
measureObject.sqlTime(SessionLocalManager.getSqlTime()); |
|
|
|
|
measureObject.sql(SessionLocalManager.getSql()); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public static void recordMemory(Compute once, Measurable measurable, MeasureObject measureObject) { |
|
|
|
|
if (SupervisoryConfig.getInstance().isEnableMeasureMemory() && once.computeMemory()) { |
|
|
|
|
MeasureUnit unit = measurable.measureUnit(); |
|
|
|
|
measureObject.memory(unit.measureMemory()); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
public static boolean findSessionAnnotation(Method method, Object[] args) { |
|
|
|
|
Annotation[][] all = method.getParameterAnnotations(); |
|
|
|
|
int len = ArrayUtils.getLength(args); |
|
|
|
|
for (int i = 0; i < len; i++) { |
|
|
|
|
Annotation[] current = all[i]; |
|
|
|
|
for (Annotation annotation : current) { |
|
|
|
|
if (annotation.annotationType().equals(Session.class)) { |
|
|
|
|
SessionLocalManager.setSession( |
|
|
|
|
SessionPoolManager.getSessionIDInfor(GeneralUtils.objectToString(args[i]), SessionProvider.class)); |
|
|
|
|
return true; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
return false; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|