mirror of
https://gitee.com/huoyo/ko-time.git
synced 2025-12-06 16:58:26 +08:00
add the additional outputs for the methods invoked
This commit is contained in:
parent
6534fa07e6
commit
6c7899ef9d
2
pom.xml
2
pom.xml
@ -6,7 +6,7 @@
|
||||
|
||||
<groupId>cn.langpy</groupId>
|
||||
<artifactId>ko-time</artifactId>
|
||||
<version>2.1.1</version>
|
||||
<version>2.2.0.BETA</version>
|
||||
<name>koTime</name>
|
||||
<description>koTime</description>
|
||||
<licenses>
|
||||
|
||||
12
src/main/java/cn/langpy/kotime/annotation/KoListener.java
Normal file
12
src/main/java/cn/langpy/kotime/annotation/KoListener.java
Normal file
@ -0,0 +1,12 @@
|
||||
package cn.langpy.kotime.annotation;
|
||||
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.lang.annotation.*;
|
||||
|
||||
@Target({ElementType.TYPE})
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Component
|
||||
public @interface KoListener {
|
||||
String value() default "";
|
||||
}
|
||||
@ -18,7 +18,6 @@ public class DefaultConfig {
|
||||
private Boolean exceptionEnable;
|
||||
private Boolean paramAnalyse;
|
||||
private String saveSaver;
|
||||
private Boolean saveAsync;
|
||||
private Integer threadNum;
|
||||
private String contextPath;
|
||||
private Boolean authEnable;
|
||||
@ -81,13 +80,7 @@ public class DefaultConfig {
|
||||
this.saveSaver = saveSaver;
|
||||
}
|
||||
|
||||
public Boolean getSaveAsync() {
|
||||
return saveAsync;
|
||||
}
|
||||
|
||||
public void setSaveAsync(Boolean saveAsync) {
|
||||
this.saveAsync = saveAsync;
|
||||
}
|
||||
|
||||
public Integer getThreadNum() {
|
||||
return threadNum;
|
||||
|
||||
@ -1,8 +1,12 @@
|
||||
package cn.langpy.kotime.config;
|
||||
|
||||
import cn.langpy.kotime.annotation.KoListener;
|
||||
import cn.langpy.kotime.handler.RunTimeHandler;
|
||||
import cn.langpy.kotime.service.InvokedHandler;
|
||||
import cn.langpy.kotime.util.Context;
|
||||
import org.springframework.aop.aspectj.AspectJExpressionPointcutAdvisor;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.ComponentScan;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
@ -11,6 +15,7 @@ import org.springframework.util.StringUtils;
|
||||
import javax.annotation.PostConstruct;
|
||||
import javax.annotation.Resource;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
/**
|
||||
* zhangchang
|
||||
*/
|
||||
@ -33,9 +38,7 @@ public class LoadConfig {
|
||||
private Boolean exceptionEnable;
|
||||
@Value("${koTime.save.saver:memory}")
|
||||
private String saveSaver;
|
||||
@Value("${koTime.save.async:false}")
|
||||
private Boolean saveAsync;
|
||||
@Value("${koTime.save.thread-num:4}")
|
||||
@Value("${koTime.save.thread-num:10}")
|
||||
private Integer threadNum;
|
||||
@Value("${server.port:8080}")
|
||||
private Integer serverPort;
|
||||
@ -44,28 +47,50 @@ public class LoadConfig {
|
||||
|
||||
@Resource
|
||||
private DefaultConfig defaultConfig;
|
||||
@Resource
|
||||
private ApplicationContext applicationContext;
|
||||
|
||||
|
||||
@PostConstruct
|
||||
public void function() {
|
||||
public void initConfig() {
|
||||
DefaultConfig config = new DefaultConfig();
|
||||
config.setLogEnable(defaultConfig.getLogEnable()==null?logEnable:defaultConfig.getLogEnable());
|
||||
config.setPointcut(defaultConfig.getPointcut()==null?pointcut:defaultConfig.getPointcut());
|
||||
config.setLogLanguage(defaultConfig.getLogLanguage()==null?logLanguage:defaultConfig.getLogLanguage());
|
||||
config.setThreshold(defaultConfig.getThreshold()==null?timeThreshold:defaultConfig.getThreshold());
|
||||
config.setExceptionEnable(defaultConfig.getExceptionEnable()==null?exceptionEnable:defaultConfig.getExceptionEnable());
|
||||
config.setSaveSaver(defaultConfig.getSaveSaver()==null?saveSaver:defaultConfig.getSaveSaver());
|
||||
config.setEnable(defaultConfig.getEnable()==null?kotimeEnable:defaultConfig.getEnable());
|
||||
config.setLogEnable(defaultConfig.getLogEnable() == null ? logEnable : defaultConfig.getLogEnable());
|
||||
config.setPointcut(defaultConfig.getPointcut() == null ? pointcut : defaultConfig.getPointcut());
|
||||
config.setLogLanguage(defaultConfig.getLogLanguage() == null ? logLanguage : defaultConfig.getLogLanguage());
|
||||
config.setThreshold(defaultConfig.getThreshold() == null ? timeThreshold : defaultConfig.getThreshold());
|
||||
config.setExceptionEnable(defaultConfig.getExceptionEnable() == null ? exceptionEnable : defaultConfig.getExceptionEnable());
|
||||
config.setSaveSaver(defaultConfig.getSaveSaver() == null ? saveSaver : defaultConfig.getSaveSaver());
|
||||
config.setEnable(defaultConfig.getEnable() == null ? kotimeEnable : defaultConfig.getEnable());
|
||||
config.setContextPath(defaultConfig.getContextPath());
|
||||
config.setAuthEnable(defaultConfig.getAuthEnable()==null?false:defaultConfig.getAuthEnable());
|
||||
config.setParamAnalyse(defaultConfig.getParamAnalyse()==null?true:defaultConfig.getParamAnalyse());
|
||||
config.setThreadNum(defaultConfig.getThreadNum() == null ? 10 : defaultConfig.getThreadNum());
|
||||
config.setAuthEnable(defaultConfig.getAuthEnable() == null ? false : defaultConfig.getAuthEnable());
|
||||
config.setParamAnalyse(defaultConfig.getParamAnalyse() == null ? true : defaultConfig.getParamAnalyse());
|
||||
if (null!=config) {
|
||||
config.setPointcut("("+config.getPointcut()+" ) && !@annotation(javax.websocket.server.ServerEndpoint) && !@annotation(cn.langpy.kotime.annotation.KoListener)");
|
||||
}
|
||||
Context.setConfig(config);
|
||||
log.info("kotime=>loading config");
|
||||
|
||||
if (StringUtils.hasText(config.getContextPath())) {
|
||||
log.info("kotime=>view:"+Context.getConfig().getContextPath()+"/koTime");
|
||||
}else {
|
||||
log.info("kotime=>view:http://localhost:" + serverPort+serverContext+"/koTime");
|
||||
log.info("kotime=>view:" + Context.getConfig().getContextPath() + "/koTime");
|
||||
} else {
|
||||
log.info("kotime=>view:http://localhost:" + serverPort + serverContext + "/koTime");
|
||||
}
|
||||
}
|
||||
|
||||
@PostConstruct
|
||||
public void initMethodHandlers() {
|
||||
String[] names = applicationContext.getBeanNamesForType(InvokedHandler.class);
|
||||
for (String name : names) {
|
||||
InvokedHandler bean = (InvokedHandler) applicationContext.getBean(name);
|
||||
if (null != bean) {
|
||||
KoListener annotation = bean.getClass().getAnnotation(KoListener.class);
|
||||
if (null==annotation) {
|
||||
continue;
|
||||
}
|
||||
log.info("kotime=>loading InvokedHandler:" + bean.getClass().getSimpleName());
|
||||
Context.addInvokedHandler(bean);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -73,7 +98,7 @@ public class LoadConfig {
|
||||
public AspectJExpressionPointcutAdvisor configurabledvisor() {
|
||||
log.info("kotime=>loading method listener");
|
||||
AspectJExpressionPointcutAdvisor advisor = new AspectJExpressionPointcutAdvisor();
|
||||
advisor.setExpression(defaultConfig.getPointcut()==null?pointcut:defaultConfig.getPointcut());
|
||||
advisor.setExpression(defaultConfig.getPointcut() == null ? pointcut : defaultConfig.getPointcut());
|
||||
advisor.setAdvice(new RunTimeHandler());
|
||||
return advisor;
|
||||
}
|
||||
|
||||
@ -4,11 +4,15 @@ import cn.langpy.kotime.model.ExceptionNode;
|
||||
import cn.langpy.kotime.service.GraphService;
|
||||
import cn.langpy.kotime.model.MethodNode;
|
||||
import cn.langpy.kotime.service.InvokeService;
|
||||
import cn.langpy.kotime.service.InvokedHandler;
|
||||
import cn.langpy.kotime.util.Context;
|
||||
import cn.langpy.kotime.util.MethodStack;
|
||||
import org.aopalliance.intercept.MethodInterceptor;
|
||||
import org.aopalliance.intercept.MethodInvocation;
|
||||
|
||||
import java.lang.reflect.Parameter;
|
||||
import java.util.concurrent.ThreadPoolExecutor;
|
||||
|
||||
/**
|
||||
* zhangchang
|
||||
*/
|
||||
@ -21,6 +25,8 @@ public class RunTimeHandler implements MethodInterceptor {
|
||||
return invocation.proceed();
|
||||
}
|
||||
boolean exceptionEnable = Context.getConfig().getExceptionEnable();
|
||||
Parameter[] parameters = invocation.getMethod().getParameters();
|
||||
ThreadPoolExecutor pool = Context.getThreadPoolExecutor();
|
||||
long begin = System.nanoTime();
|
||||
Object obj = null;
|
||||
MethodNode parent = InvokeService.getParentMethodNode();
|
||||
@ -37,10 +43,9 @@ public class RunTimeHandler implements MethodInterceptor {
|
||||
exception.setId(exception.getClassName() + exception.getName() + exception.getMessage());
|
||||
MethodNode current = InvokeService.getCurrentMethodNode(invocation, 0.0);
|
||||
if (current.getClassName().equals(e.getStackTrace()[0].getClassName())) {
|
||||
GraphService graphService = GraphService.getInstance();
|
||||
graphService.addMethodNode(current);
|
||||
graphService.addExceptionNode(exception);
|
||||
graphService.addExceptionRelation(current, exception);
|
||||
for (InvokedHandler invokedHandler : Context.getInvokedHandlers()) {
|
||||
pool.execute(()->invokedHandler.onInvoked(current,parent,parameters, invocation.getArguments()));
|
||||
}
|
||||
}
|
||||
MethodStack.clear();
|
||||
throw e;
|
||||
@ -50,12 +55,9 @@ public class RunTimeHandler implements MethodInterceptor {
|
||||
}
|
||||
long end = System.nanoTime();
|
||||
MethodNode current = InvokeService.getCurrentMethodNode(invocation, ((end - begin) / 1000000.0));
|
||||
GraphService graphService = GraphService.getInstance();
|
||||
graphService.addMethodNode(parent);
|
||||
graphService.addMethodNode(current);
|
||||
graphService.addMethodRelation(parent, current);
|
||||
if (Context.getConfig().getParamAnalyse()) {
|
||||
graphService.addParamAnalyse(current.getId(),invocation.getMethod().getParameters(), invocation.getArguments(),((end - begin) / 1000000.0));
|
||||
|
||||
for (InvokedHandler invokedHandler : Context.getInvokedHandlers()) {
|
||||
pool.execute(()->invokedHandler.onInvoked(current,parent,parameters, invocation.getArguments()));
|
||||
}
|
||||
MethodStack.clear();
|
||||
return obj;
|
||||
|
||||
16
src/main/java/cn/langpy/kotime/service/InvokedHandler.java
Normal file
16
src/main/java/cn/langpy/kotime/service/InvokedHandler.java
Normal file
@ -0,0 +1,16 @@
|
||||
package cn.langpy.kotime.service;
|
||||
|
||||
import cn.langpy.kotime.annotation.KoListener;
|
||||
import cn.langpy.kotime.model.MethodNode;
|
||||
|
||||
import java.lang.reflect.Parameter;
|
||||
|
||||
/**
|
||||
* zhangchang
|
||||
*/
|
||||
public interface InvokedHandler {
|
||||
/**
|
||||
* return the results of invoking a method.
|
||||
*/
|
||||
void onInvoked(MethodNode current, MethodNode parent, Parameter[] names, Object[] values);
|
||||
}
|
||||
22
src/main/java/cn/langpy/kotime/service/KoInvokedHandler.java
Normal file
22
src/main/java/cn/langpy/kotime/service/KoInvokedHandler.java
Normal file
@ -0,0 +1,22 @@
|
||||
package cn.langpy.kotime.service;
|
||||
|
||||
import cn.langpy.kotime.annotation.KoListener;
|
||||
import cn.langpy.kotime.model.MethodNode;
|
||||
import cn.langpy.kotime.util.Context;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.lang.reflect.Parameter;
|
||||
|
||||
@KoListener
|
||||
public final class KoInvokedHandler implements InvokedHandler{
|
||||
@Override
|
||||
public void onInvoked(MethodNode current, MethodNode parent, Parameter[] names, Object[] values) {
|
||||
GraphService graphService = GraphService.getInstance();
|
||||
graphService.addMethodNode(parent);
|
||||
graphService.addMethodNode(current);
|
||||
graphService.addMethodRelation(parent, current);
|
||||
if (Context.getConfig().getParamAnalyse()) {
|
||||
graphService.addParamAnalyse(current.getId(),names, values,current.getValue());
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,6 +1,13 @@
|
||||
package cn.langpy.kotime.util;
|
||||
|
||||
import cn.langpy.kotime.config.DefaultConfig;
|
||||
import cn.langpy.kotime.service.InvokedHandler;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.SynchronousQueue;
|
||||
import java.util.concurrent.ThreadPoolExecutor;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
* zhangchang
|
||||
@ -8,12 +15,16 @@ import cn.langpy.kotime.config.DefaultConfig;
|
||||
public class Context {
|
||||
|
||||
private static DefaultConfig config;
|
||||
private static List<InvokedHandler> invokedHandlers;
|
||||
private static ThreadPoolExecutor threadPoolExecutor;
|
||||
|
||||
static {
|
||||
config = new DefaultConfig();
|
||||
config.setLogEnable(false);
|
||||
config.setEnable(true);
|
||||
config.setLogLanguage("chinese");
|
||||
invokedHandlers = new ArrayList<>();
|
||||
threadPoolExecutor = new ThreadPoolExecutor(10, 1000,60L, TimeUnit.SECONDS,new SynchronousQueue<Runnable>());
|
||||
}
|
||||
|
||||
public static void setConfig(DefaultConfig koTimeConfig) {
|
||||
@ -24,4 +35,19 @@ public class Context {
|
||||
return config;
|
||||
}
|
||||
|
||||
public static void addInvokedHandler(InvokedHandler invokedHandler) {
|
||||
invokedHandlers.add(invokedHandler);
|
||||
}
|
||||
|
||||
public static List<InvokedHandler> getInvokedHandlers() {
|
||||
return invokedHandlers;
|
||||
}
|
||||
|
||||
public static ThreadPoolExecutor getThreadPoolExecutor() {
|
||||
return threadPoolExecutor;
|
||||
}
|
||||
|
||||
public static void setThreadPoolExecutor(ThreadPoolExecutor threadPoolExecutor) {
|
||||
Context.threadPoolExecutor = threadPoolExecutor;
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user