├── ezprofiler ├── ezprofiler-client │ ├── src │ │ ├── main │ │ │ ├── resources │ │ │ │ └── application.properties │ │ │ └── java │ │ │ │ └── com │ │ │ │ └── test │ │ │ │ ├── service │ │ │ │ └── UserService.java │ │ │ │ ├── config │ │ │ │ └── EzProfilerConfigure.java │ │ │ │ ├── MainApplication.java │ │ │ │ └── controller │ │ │ │ └── DemoController.java │ │ └── test │ │ │ ├── t.txt │ │ │ └── t2.txt │ └── pom.xml └── ezprofiler-spring-boot-starter │ ├── src │ └── main │ │ └── java │ │ └── com │ │ └── github │ │ └── xjs │ │ └── ezprofiler │ │ ├── annotation │ │ ├── EnableProfiler.java │ │ └── Profiler.java │ │ ├── mapping │ │ ├── PropertySourcedMapping.java │ │ └── PropertySourcedRequestMappingHandlerMapping.java │ │ ├── util │ │ └── WebUtil.java │ │ ├── scanner │ │ ├── ControllerAccessInfo.java │ │ ├── ProfileInfo.java │ │ ├── ProfilerQueue.java │ │ ├── MethodAccessInfo.java │ │ ├── ControllerScaner.java │ │ └── ProfileInfoHolder.java │ │ ├── config │ │ ├── EzProfilerConfiguration.java │ │ └── EzProfilerProperties.java │ │ └── controller │ │ └── EzProfilerController.java │ └── pom.xml ├── .gitignore └── README.md /ezprofiler/ezprofiler-client/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | ezprofiler.basepackage=com.test 2 | ezprofiler.enableBasic=true 3 | ezprofiler.username=xjs 4 | ezprofiler.password=123456 5 | #ezprofiler.url=/my/profiler 6 | spring.jackson.default-property-inclusion=non_null 7 | spring.jackson.date-format=yyyy-MM-dd HH:mm:ss 8 | spring.jackson.time-zone=GMT+8 -------------------------------------------------------------------------------- /ezprofiler/ezprofiler-client/src/main/java/com/test/service/UserService.java: -------------------------------------------------------------------------------- 1 | package com.test.service; 2 | 3 | import org.springframework.stereotype.Service; 4 | 5 | /** 6 | * @author 605162215@qq.com 7 | * 8 | * @date 2018年6月29日 下午3:14:41
9 | */ 10 | @Service 11 | public class UserService { 12 | 13 | public String getUserId() { 14 | return "hi"; 15 | } 16 | 17 | } 18 | -------------------------------------------------------------------------------- /ezprofiler/ezprofiler-client/src/main/java/com/test/config/EzProfilerConfigure.java: -------------------------------------------------------------------------------- 1 | package com.test.config; 2 | 3 | import org.springframework.context.annotation.Configuration; 4 | 5 | import com.github.xjs.ezprofiler.annotation.EnableProfiler; 6 | 7 | /** 8 | * @author 605162215@qq.com 9 | * 10 | * @date 2018年7月2日 上午8:17:17
11 | */ 12 | @EnableProfiler 13 | @Configuration 14 | public class EzProfilerConfigure { 15 | 16 | } 17 | -------------------------------------------------------------------------------- /ezprofiler/ezprofiler-client/src/main/java/com/test/MainApplication.java: -------------------------------------------------------------------------------- 1 | package com.test; 2 | import org.springframework.boot.SpringApplication; 3 | import org.springframework.boot.autoconfigure.SpringBootApplication; 4 | 5 | 6 | @SpringBootApplication 7 | public class MainApplication { 8 | 9 | public static void main(String[] args) throws Exception { 10 | SpringApplication.run(MainApplication.class, args); 11 | } 12 | 13 | } -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /ezprofiler/ezprofiler-spring-boot-starter/*.classpath 2 | /ezprofiler/ezprofiler-spring-boot-starter/*.gitignore 3 | /ezprofiler/ezprofiler-spring-boot-starter/*.project 4 | /ezprofiler/ezprofiler-spring-boot-starter/.settings 5 | /ezprofiler/ezprofiler-client/*.classpath 6 | /ezprofiler/ezprofiler-client/*.gitignore 7 | /ezprofiler/ezprofiler-client/*.project 8 | /ezprofiler/ezprofiler-client/.settings 9 | /ezprofiler/ezprofiler-client/bin 10 | -------------------------------------------------------------------------------- /ezprofiler/ezprofiler-spring-boot-starter/src/main/java/com/github/xjs/ezprofiler/annotation/EnableProfiler.java: -------------------------------------------------------------------------------- 1 | package com.github.xjs.ezprofiler.annotation; 2 | 3 | import java.lang.annotation.Retention; 4 | import java.lang.annotation.Target; 5 | 6 | import org.springframework.context.annotation.Import; 7 | 8 | import com.github.xjs.ezprofiler.config.EzProfilerConfiguration; 9 | 10 | /** 11 | * @author 605162215@qq.com 12 | * 13 | * @date 2018年7月2日 上午8:10:14
14 | */ 15 | @Retention(value = java.lang.annotation.RetentionPolicy.RUNTIME) 16 | @Target(value = { java.lang.annotation.ElementType.TYPE }) 17 | @Import({EzProfilerConfiguration.class}) 18 | public @interface EnableProfiler { 19 | } 20 | -------------------------------------------------------------------------------- /ezprofiler/ezprofiler-spring-boot-starter/src/main/java/com/github/xjs/ezprofiler/mapping/PropertySourcedMapping.java: -------------------------------------------------------------------------------- 1 | package com.github.xjs.ezprofiler.mapping; 2 | 3 | import java.lang.annotation.ElementType; 4 | import java.lang.annotation.Retention; 5 | import java.lang.annotation.RetentionPolicy; 6 | import java.lang.annotation.Target; 7 | 8 | import org.springframework.web.bind.annotation.Mapping; 9 | 10 | /** 11 | * @author 605162215@qq.com 12 | * 13 | * @date 2018年7月2日 上午8:42:22
14 | */ 15 | @Target({ ElementType.METHOD, ElementType.TYPE}) 16 | @Retention(RetentionPolicy.RUNTIME) 17 | @Mapping 18 | public @interface PropertySourcedMapping { 19 | String propertyKey(); 20 | String value(); 21 | } 22 | -------------------------------------------------------------------------------- /ezprofiler/ezprofiler-spring-boot-starter/src/main/java/com/github/xjs/ezprofiler/util/WebUtil.java: -------------------------------------------------------------------------------- 1 | package com.github.xjs.ezprofiler.util; 2 | 3 | import javax.servlet.http.HttpServletRequest; 4 | import javax.servlet.http.HttpServletResponse; 5 | 6 | /** 7 | * @author 605162215@qq.com 8 | * 9 | * @date 2018年4月12日 下午3:03:48 10 | */ 11 | public class WebUtil { 12 | 13 | public static void ret401(HttpServletRequest request, HttpServletResponse response){ 14 | String serverName = request.getServerName(); 15 | response.setStatus(401); 16 | response.setHeader("Cache-Control", "no-store"); 17 | response.setDateHeader("Expires", 0); 18 | response.setHeader("WWW-authenticate", "Basic Realm=\"" + serverName + "\""); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /ezprofiler/ezprofiler-spring-boot-starter/src/main/java/com/github/xjs/ezprofiler/annotation/Profiler.java: -------------------------------------------------------------------------------- 1 | package com.github.xjs.ezprofiler.annotation; 2 | 3 | import java.lang.annotation.ElementType; 4 | import java.lang.annotation.Retention; 5 | import java.lang.annotation.RetentionPolicy; 6 | import java.lang.annotation.Target; 7 | 8 | import org.springframework.core.annotation.AliasFor; 9 | 10 | /** 11 | * @author 605162215@qq.com 12 | * 13 | * @date 2018年4月12日 下午3:49:23
14 | */ 15 | @Retention(RetentionPolicy.RUNTIME) 16 | @Target({ElementType.TYPE, ElementType.METHOD}) 17 | public @interface Profiler { 18 | 19 | @AliasFor("enable") 20 | boolean value() default true; 21 | 22 | @AliasFor("value") 23 | boolean enable() default true; 24 | } 25 | -------------------------------------------------------------------------------- /ezprofiler/ezprofiler-spring-boot-starter/src/main/java/com/github/xjs/ezprofiler/scanner/ControllerAccessInfo.java: -------------------------------------------------------------------------------- 1 | package com.github.xjs.ezprofiler.scanner; 2 | 3 | import java.util.List; 4 | 5 | /** 6 | * @author 605162215@qq.com 7 | * 8 | * @date 2017年9月21日 下午3:03:48 9 | */ 10 | public class ControllerAccessInfo { 11 | private Class controllerClazz; 12 | private List methodInfos; 13 | public Class getControllerClazz() { 14 | return controllerClazz; 15 | } 16 | public void setControllerClazz(Class controllerClazz) { 17 | this.controllerClazz = controllerClazz; 18 | } 19 | public List getMethodInfos() { 20 | return methodInfos; 21 | } 22 | public void setMethodInfos(List methodInfos) { 23 | this.methodInfos = methodInfos; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /ezprofiler/ezprofiler-spring-boot-starter/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | com.github.xjs 7 | ezprofiler-spring-boot-starter 8 | 0.0.1-SNAPSHOT 9 | jar 10 | 11 | 1.8 12 | 13 | 14 | 15 | 16 | javax.servlet 17 | javax.servlet-api 18 | 3.0.1 19 | provided 20 | 21 | 22 | org.springframework 23 | spring-webmvc 24 | 4.3.10.RELEASE 25 | 26 | 27 | org.slf4j 28 | slf4j-api 29 | 1.7.25 30 | 31 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /ezprofiler/ezprofiler-spring-boot-starter/src/main/java/com/github/xjs/ezprofiler/config/EzProfilerConfiguration.java: -------------------------------------------------------------------------------- 1 | package com.github.xjs.ezprofiler.config; 2 | 3 | import org.springframework.beans.factory.annotation.Autowired; 4 | import org.springframework.context.annotation.Bean; 5 | import org.springframework.context.annotation.ComponentScan; 6 | import org.springframework.context.annotation.Configuration; 7 | import org.springframework.core.env.Environment; 8 | import org.springframework.web.servlet.HandlerMapping; 9 | 10 | import com.github.xjs.ezprofiler.controller.EzProfilerController; 11 | import com.github.xjs.ezprofiler.mapping.PropertySourcedRequestMappingHandlerMapping; 12 | 13 | /** 14 | * @author 605162215@qq.com 15 | * 16 | * @date 2018年7月2日 上午8:11:01
17 | */ 18 | @Configuration 19 | @ComponentScan(basePackages = 20 | { 21 | "com.github.xjs.ezprofiler.config", 22 | "com.github.xjs.ezprofiler.controller", 23 | "com.github.xjs.ezprofiler.scanner" }) 24 | public class EzProfilerConfiguration { 25 | 26 | @Autowired 27 | private EzProfilerProperties properties; 28 | 29 | @Bean 30 | public HandlerMapping ezprofilerControllerMapping(Environment environment) { 31 | return new PropertySourcedRequestMappingHandlerMapping(environment, new EzProfilerController(properties)); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /ezprofiler/ezprofiler-spring-boot-starter/src/main/java/com/github/xjs/ezprofiler/scanner/ProfileInfo.java: -------------------------------------------------------------------------------- 1 | package com.github.xjs.ezprofiler.scanner; 2 | 3 | import java.lang.reflect.Method; 4 | 5 | /** 6 | * @author 605162215@qq.com 7 | * 8 | * @date 2018年4月12日 下午4:11:29
9 | */ 10 | public class ProfileInfo { 11 | private String uri; 12 | private long start; 13 | private long end; 14 | private boolean occurError; 15 | private Class clazz; 16 | private Method method; 17 | public String getUri() { 18 | return uri; 19 | } 20 | public void setUri(String uri) { 21 | this.uri = uri; 22 | } 23 | public long getStart() { 24 | return start; 25 | } 26 | public void setStart(long start) { 27 | this.start = start; 28 | } 29 | public long getEnd() { 30 | return end; 31 | } 32 | public void setEnd(long end) { 33 | this.end = end; 34 | } 35 | public boolean isOccurError() { 36 | return occurError; 37 | } 38 | public void setOccurError(boolean occurError) { 39 | this.occurError = occurError; 40 | } 41 | public Class getClazz() { 42 | return clazz; 43 | } 44 | public void setClazz(Class clazz) { 45 | this.clazz = clazz; 46 | } 47 | public Method getMethod() { 48 | return method; 49 | } 50 | public void setMethod(Method method) { 51 | this.method = method; 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /ezprofiler/ezprofiler-client/pom.xml: -------------------------------------------------------------------------------- 1 | 3 | 4.0.0 4 | 5 | com.github.xjs 6 | ezprofiler-client 7 | 0.0.1-SNAPSHOT 8 | jar 9 | 10 | 11 | org.springframework.boot 12 | spring-boot-starter-parent 13 | 1.5.6.RELEASE 14 | 15 | 16 | 17 | UTF-8 18 | 19 | 20 | 21 | 22 | 23 | org.springframework.boot 24 | spring-boot-starter-web 25 | 26 | 27 | 28 | com.github.xjs 29 | ezprofiler-spring-boot-starter 30 | 0.0.1-SNAPSHOT 31 | 32 | 33 | 34 | 35 | 36 | ${project.artifactId} 37 | 38 | 39 | org.springframework.boot 40 | spring-boot-maven-plugin 41 | 42 | 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /ezprofiler/ezprofiler-client/src/main/java/com/test/controller/DemoController.java: -------------------------------------------------------------------------------- 1 | package com.test.controller; 2 | 3 | import java.util.Random; 4 | 5 | import org.springframework.beans.factory.annotation.Autowired; 6 | import org.springframework.web.bind.annotation.GetMapping; 7 | import org.springframework.web.bind.annotation.RestController; 8 | 9 | import com.github.xjs.ezprofiler.annotation.Profiler; 10 | import com.test.service.UserService; 11 | 12 | /** 13 | * @author 605162215@qq.com 14 | * 15 | * @date 2018年4月12日 下午3:33:09
16 | */ 17 | @RestController 18 | @Profiler 19 | public class DemoController { 20 | 21 | @GetMapping("/hello") 22 | public String hello() { 23 | return "hello"; 24 | } 25 | @GetMapping("/hello1") 26 | public String hello1() { 27 | Random rnd = new Random(); 28 | try{Thread.sleep(rnd.nextInt(1000));}catch(Exception e) {} 29 | return "hello1"; 30 | } 31 | 32 | @GetMapping("/hello2") 33 | public String hello2() { 34 | Random rnd = new Random(); 35 | try{Thread.sleep(rnd.nextInt(1000));}catch(Exception e) {} 36 | return "hello2"; 37 | } 38 | 39 | @GetMapping("/err") 40 | public String error() { 41 | Random rnd = new Random(); 42 | try{Thread.sleep(rnd.nextInt(1000));}catch(Exception e) {} 43 | throw new RuntimeException(); 44 | } 45 | 46 | @GetMapping("/world") 47 | @Profiler(false) 48 | public String world() { 49 | return "world"; 50 | } 51 | 52 | @Autowired 53 | UserService userService; 54 | 55 | @GetMapping("/user") 56 | public String user() { 57 | return userService.getUserId(); 58 | } 59 | 60 | } 61 | -------------------------------------------------------------------------------- /ezprofiler/ezprofiler-spring-boot-starter/src/main/java/com/github/xjs/ezprofiler/config/EzProfilerProperties.java: -------------------------------------------------------------------------------- 1 | package com.github.xjs.ezprofiler.config; 2 | 3 | import org.springframework.beans.factory.annotation.Value; 4 | import org.springframework.stereotype.Component; 5 | 6 | /** 7 | * @author 605162215@qq.com 8 | * 9 | * @date 2018年4月12日 下午2:59:56
10 | */ 11 | @Component 12 | public class EzProfilerProperties { 13 | 14 | @Value("${ezprofiler.enableBasic:true}") 15 | private boolean enableBasic = true; 16 | 17 | @Value("${ezprofiler.username:ezprofiler-admin}") 18 | private String username = "ezprofiler-admin"; 19 | 20 | @Value("${ezprofiler.password:ezprofiler-admin}") 21 | private String password = "ezprofiler-admin"; 22 | 23 | @Value("${ezprofiler.url:/profiler}") 24 | private String url = "/profiler"; 25 | 26 | @Value("${ezprofiler.basepackage:com}") 27 | private String basePackage="com"; 28 | 29 | public boolean isEnableBasic() { 30 | return enableBasic; 31 | } 32 | public void setEnableBasic(boolean enableBasic) { 33 | this.enableBasic = enableBasic; 34 | } 35 | public String getUsername() { 36 | return username; 37 | } 38 | public void setUsername(String username) { 39 | this.username = username; 40 | } 41 | public String getPassword() { 42 | return password; 43 | } 44 | public void setPassword(String password) { 45 | this.password = password; 46 | } 47 | public String getUrl() { 48 | return url; 49 | } 50 | public void setUrl(String url) { 51 | this.url = url; 52 | } 53 | public String getBasePackage() { 54 | return basePackage; 55 | } 56 | public void setBasePackage(String basePackage) { 57 | this.basePackage = basePackage; 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /ezprofiler/ezprofiler-spring-boot-starter/src/main/java/com/github/xjs/ezprofiler/scanner/ProfilerQueue.java: -------------------------------------------------------------------------------- 1 | package com.github.xjs.ezprofiler.scanner; 2 | 3 | import java.util.concurrent.BlockingQueue; 4 | import java.util.concurrent.Executors; 5 | import java.util.concurrent.LinkedBlockingQueue; 6 | import java.util.concurrent.ThreadFactory; 7 | import java.util.concurrent.atomic.AtomicBoolean; 8 | 9 | import org.slf4j.Logger; 10 | import org.slf4j.LoggerFactory; 11 | 12 | /** 13 | * @author 605162215@qq.com 14 | * 15 | * @date 2017年9月21日 下午3:02:30
16 | * 17 | * 工作队列 18 | */ 19 | public class ProfilerQueue{ 20 | 21 | private static Logger log = LoggerFactory.getLogger(ProfilerQueue.class); 22 | 23 | private BlockingQueue queue; 24 | private final ThreadFactory threadFactory; 25 | private Thread thread; 26 | private AtomicBoolean started = new AtomicBoolean(false); 27 | private volatile boolean shouldContinue = false; 28 | 29 | public ProfilerQueue() { 30 | this(null); 31 | } 32 | 33 | public ProfilerQueue(final ThreadFactory tf) { 34 | this.queue = new LinkedBlockingQueue(); 35 | this.threadFactory = tf == null ? Executors.defaultThreadFactory() : tf; 36 | this.thread = null; 37 | } 38 | 39 | public void start() { 40 | if (started.getAndSet(true)) { 41 | return; 42 | } 43 | log.info("WorkingQueue start"); 44 | shouldContinue = true; 45 | thread = threadFactory.newThread(new Runnable() { 46 | public void run() { 47 | while (shouldContinue) { 48 | try { 49 | ProfileInfo req = queue.take(); 50 | ProfileInfoHolder.addProfilerInfo(req); 51 | } catch (Exception e) { 52 | e.printStackTrace(); 53 | } 54 | } 55 | } 56 | }); 57 | thread.start(); 58 | } 59 | 60 | public void stop() { 61 | started.set(false); 62 | shouldContinue = false; 63 | thread.interrupt(); 64 | log.info("WorkingQueue end"); 65 | } 66 | 67 | public void addProfileInfo(ProfileInfo info) { 68 | if (!started.get()) { 69 | start(); 70 | } 71 | queue.add(info); 72 | } 73 | } -------------------------------------------------------------------------------- /ezprofiler/ezprofiler-spring-boot-starter/src/main/java/com/github/xjs/ezprofiler/controller/EzProfilerController.java: -------------------------------------------------------------------------------- 1 | package com.github.xjs.ezprofiler.controller; 2 | 3 | import java.util.Base64; 4 | import java.util.Map; 5 | 6 | import javax.servlet.http.HttpServletRequest; 7 | import javax.servlet.http.HttpServletResponse; 8 | 9 | import org.springframework.web.bind.annotation.RequestMapping; 10 | import org.springframework.web.bind.annotation.RestController; 11 | 12 | import com.github.xjs.ezprofiler.annotation.Profiler; 13 | import com.github.xjs.ezprofiler.config.EzProfilerProperties; 14 | import com.github.xjs.ezprofiler.mapping.PropertySourcedMapping; 15 | import com.github.xjs.ezprofiler.scanner.ProfileInfoHolder; 16 | import com.github.xjs.ezprofiler.util.WebUtil; 17 | 18 | /** 19 | * @author 605162215@qq.com 20 | * 21 | * @date 2018年4月12日 下午3:02:53
22 | */ 23 | @RestController 24 | @Profiler(false) 25 | public class EzProfilerController { 26 | 27 | public static final String DEFAULT_URL = "/profiler"; 28 | 29 | private EzProfilerProperties properties; 30 | 31 | public EzProfilerController(EzProfilerProperties properties) { 32 | this.properties = properties; 33 | } 34 | 35 | @RequestMapping(DEFAULT_URL) 36 | @PropertySourcedMapping(propertyKey="ezprofiler.url",value="${ezprofiler.url}") 37 | public Map ezprofiler(HttpServletRequest request, HttpServletResponse response) { 38 | boolean enableBasic = properties.isEnableBasic(); 39 | if(!enableBasic) { 40 | return ProfileInfoHolder.getAllAccessInfo(); 41 | } 42 | String auth = request.getHeader("Authorization"); 43 | if ((auth != null) && (auth.length() > 6)) { 44 | auth = auth.substring(6, auth.length()); 45 | auth = new String(Base64.getDecoder().decode(auth)); 46 | String authServer = properties.getUsername()+":"+properties.getPassword(); 47 | if(auth.equals(authServer)) { 48 | return ProfileInfoHolder.getAllAccessInfo(); 49 | }else { 50 | WebUtil.ret401(request, response); 51 | return null; 52 | } 53 | } else { 54 | WebUtil.ret401(request, response); 55 | return null; 56 | } 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ezprofiler 2 | 3 | ## 微信扫一扫关注公众号:爪哇优太儿 4 | ![扫一扫加关注](https://img-blog.csdnimg.cn/20190524100820287.jpg?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2dvbGRlbmZpc2gxOTE5,size_16,color_FFFFFF,t_7) 5 | 6 | ## 统计Controller的方法执行时间 7 | 8 | ## 使用方式 9 | 10 | 1. 安装依赖 11 | ```sh 12 | 下载源码,命令行执行:maven clean install 13 | ``` 14 | 15 | 2. 添加依赖 16 | ```xml 17 | 18 | com.github.xjs 19 | ezprofiler-spring-boot-starter 20 | 0.0.1-SNAPSHOT 21 | 22 | ``` 23 | 3. 添加配置 24 | ```java 25 | @EnableProfiler 26 | @Configuration 27 | public class EzProfilerConfigure { 28 | } 29 | ``` 30 | 4.项目启动以后,访问浏览器 http://localhost:8080/profiler , 输出结果类似: 31 | ```json 32 | { 33 | "DemoController": [{ 34 | "method": "hello",//方法名 35 | "uri": "/hello", //url路径 36 | "invokeCount": 2, //总的调用次数 37 | "okCount": 2, //总的成功的次数 38 | "errorCount": 0, //总的失败的次数 39 | "minMills": 0, //最小用时 40 | "maxMills": 0, //最大用时 41 | "avgMills": 0, //平均用时 42 | "maxInvokeAt": "2018-08-09 10:28:08", //最大用时发生时间点 43 | "lastDayCount": 2, //最近一天总调用次数 44 | "lastDayOkCount": 2,//最近一天成功次数 45 | "lastDayErrorCount": 0,//最近一天失败次数 46 | "lastDayMinMills": 0,//最近一天最小用时 47 | "lastDayMaxMills": 0,//最近一天最大用时 48 | "lastDayAvgMills": 0,//最近一天平均用时 49 | "lastDayMaxInvokeAt": "2018-08-09 10:28:12",//最近一天最大用时发生时间点 50 | "lastMills": 0, //上次用时 51 | "lastInvokeAt": "2018-08-09 10:30:11"//上次调用时间点 52 | }] 53 | } 54 | ``` 55 | 56 | ## 其他配置 57 | 58 | 1. 默认会统计所有Controller的所有方法,可以在不想被统计的Controller类或者方法上添加@Profiler(false)注解,方法的优先级高于类的优先级 59 | ```java 60 | @GetMapping("/world") 61 | @Profiler(false) 62 | public String world() { 63 | return "world"; 64 | } 65 | ``` 66 | 2. 默认会给统计接口加上权限验证,默认的用户名:ezprofiler-admin,密码:ezprofiler-admin,可以自定义: 67 | ```html 68 | ezprofiler.enableBasic=true 69 | ezprofiler.username=xjs 70 | ezprofiler.password=123456 71 | ``` 72 | 3. 默认的profiler的访问路径是/profiler,可以自定义: 73 | ```html 74 | ezprofiler.url=/my/profiler 75 | ``` 76 | 4.可以自定义要扫描的controller的base package,默认是com 77 | ```html 78 | ezprofiler.basepackage=com.github.xjs.controller 79 | ``` 80 | -------------------------------------------------------------------------------- /ezprofiler/ezprofiler-client/src/test/t.txt: -------------------------------------------------------------------------------- 1 | ssistantAccount 2 | : 3 | null 4 | assistantAccountName 5 | : 6 | null 7 | assistantAccountNo 8 | : 9 | null 10 | assistantAccountType 11 | : 12 | null 13 | assistantAccountTypeName 14 | : 15 | null 16 | assistantAccountTypeNo 17 | : 18 | null 19 | assistantTypes 20 | : 21 | [] 22 | balanceid 23 | : 24 | 135847 25 | bank 26 | : 27 | null 28 | bankAccount 29 | : 30 | null 31 | bookId 32 | : 33 | null 34 | currency 35 | : 36 | "KRW" 37 | currencyCode 38 | : 39 | null 40 | dfAccumulate 41 | : 42 | 0 43 | dfActualBalance 44 | : 45 | 0 46 | dfbalance 47 | : 48 | 0 49 | dfbalanceOrg 50 | : 51 | 0 52 | dfcurrency 53 | : 54 | 0 55 | dflj 56 | : 57 | 0 58 | dfljsl 59 | : 60 | 0 61 | dfljwb 62 | : 63 | 0 64 | dfnumber 65 | : 66 | 0 67 | dir 68 | : 69 | "1" 70 | endbalance 71 | : 72 | 202 73 | endbalanceOrg 74 | : 75 | 0 76 | endcurrency 77 | : 78 | 0 79 | endnumber 80 | : 81 | 0 82 | hasAssistantDetail 83 | : 84 | false 85 | id 86 | : 87 | 100352 88 | initbalance 89 | : 90 | 202 91 | initbalanceOrg 92 | : 93 | 0 94 | initcurrency 95 | : 96 | 0 97 | initnumber 98 | : 99 | 0 100 | isAssistantAccount 101 | : 102 | "false" 103 | isForeignCurrency 104 | : 105 | "true" 106 | isaccountingNum 107 | : 108 | "false" 109 | isentry 110 | : 111 | "false" 112 | isinit 113 | : 114 | "false" 115 | jfAccumulate 116 | : 117 | 0 118 | jfActualBalance 119 | : 120 | 0 121 | jfbalance 122 | : 123 | 0 124 | jfbalanceOrg 125 | : 126 | 0 127 | jfcurrency 128 | : 129 | 0 130 | jflj 131 | : 132 | 0 133 | jfljsl 134 | : 135 | 0 136 | jfljwb 137 | : 138 | 0 139 | jfnumber 140 | : 141 | 0 142 | level 143 | : 144 | 2 145 | measuringUnit 146 | : 147 | "" 148 | parentNo 149 | : 150 | "1002" 151 | period 152 | : 153 | null 154 | relationDetail 155 | : 156 | null 157 | status 158 | : 159 | "0" 160 | subjectAssistantId 161 | : 162 | null 163 | subjectAssistantRelation 164 | : 165 | null 166 | subjectId 167 | : 168 | 100352 169 | subjectLeaf 170 | : 171 | "true" 172 | subjectNo 173 | : 174 | "100202" 175 | subjectText 176 | : 177 | "韩币" 178 | subtypeCode 179 | : 180 | "zichan" 181 | tag 182 | : 183 | null 184 | version 185 | : 186 | "2016" -------------------------------------------------------------------------------- /ezprofiler/ezprofiler-client/src/test/t2.txt: -------------------------------------------------------------------------------- 1 | assistantAccount 2 | : 3 | null 4 | assistantAccountName 5 | : 6 | null 7 | assistantAccountNo 8 | : 9 | null 10 | assistantAccountType 11 | : 12 | null 13 | assistantAccountTypeName 14 | : 15 | null 16 | assistantAccountTypeNo 17 | : 18 | null 19 | assistantTypes 20 | : 21 | [] 22 | balanceid 23 | : 24 | null 25 | bank 26 | : 27 | null 28 | bankAccount 29 | : 30 | null 31 | bookId 32 | : 33 | null 34 | currency 35 | : 36 | "USD" 37 | currencyCode 38 | : 39 | null 40 | dfAccumulate 41 | : 42 | 0 43 | dfActualBalance 44 | : 45 | 0 46 | dfbalance 47 | : 48 | 0 49 | dfbalanceOrg 50 | : 51 | 0 52 | dfcurrency 53 | : 54 | 0 55 | dflj 56 | : 57 | 0 58 | dfljsl 59 | : 60 | 0 61 | dfljwb 62 | : 63 | 0 64 | dfnumber 65 | : 66 | 0 67 | dir 68 | : 69 | "1" 70 | endbalance 71 | : 72 | 0 73 | endbalanceOrg 74 | : 75 | 0 76 | endcurrency 77 | : 78 | 0 79 | endnumber 80 | : 81 | 0 82 | hasAssistantDetail 83 | : 84 | false 85 | id 86 | : 87 | 667001 88 | initbalance 89 | : 90 | 0 91 | initbalanceOrg 92 | : 93 | 0 94 | initcurrency 95 | : 96 | 0 97 | initnumber 98 | : 99 | 0 100 | isAssistantAccount 101 | : 102 | "false" 103 | isForeignCurrency 104 | : 105 | "true" 106 | isaccountingNum 107 | : 108 | "false" 109 | isentry 110 | : 111 | "false" 112 | isinit 113 | : 114 | "false" 115 | jfAccumulate 116 | : 117 | 0 118 | jfActualBalance 119 | : 120 | 0 121 | jfbalance 122 | : 123 | 0 124 | jfbalanceOrg 125 | : 126 | 0 127 | jfcurrency 128 | : 129 | 0 130 | jflj 131 | : 132 | 0 133 | jfljsl 134 | : 135 | 0 136 | jfljwb 137 | : 138 | 0 139 | jfnumber 140 | : 141 | 0 142 | level 143 | : 144 | 2 145 | measuringUnit 146 | : 147 | "" 148 | parentNo 149 | : 150 | "1122" 151 | period 152 | : 153 | null 154 | relationDetail 155 | : 156 | null 157 | status 158 | : 159 | "0" 160 | subjectAssistantId 161 | : 162 | null 163 | subjectAssistantRelation 164 | : 165 | null 166 | subjectId 167 | : 168 | 667001 169 | subjectLeaf 170 | : 171 | "true" 172 | subjectNo 173 | : 174 | "112213" 175 | subjectText 176 | : 177 | "塔吉克斯坦 NORMA GROUP INC" 178 | subtypeCode 179 | : 180 | "zichan" 181 | tag 182 | : 183 | null 184 | version 185 | : 186 | "2016" -------------------------------------------------------------------------------- /ezprofiler/ezprofiler-spring-boot-starter/src/main/java/com/github/xjs/ezprofiler/scanner/MethodAccessInfo.java: -------------------------------------------------------------------------------- 1 | package com.github.xjs.ezprofiler.scanner; 2 | 3 | import java.util.Date; 4 | 5 | /** 6 | * @author 605162215@qq.com 7 | * 8 | * @date 2017年9月21日 下午3:30:10 9 | */ 10 | public class MethodAccessInfo { 11 | private String method; 12 | private String uri; 13 | //历史的调用信息 14 | private long invokeCount; 15 | private long okCount; 16 | private long errorCount; 17 | private long minMills; 18 | private long maxMills; 19 | private long avgMills; 20 | private Date maxInvokeAt; 21 | //最近一天的调用信息 22 | private long lastDayCount; 23 | private long lastDayOkCount; 24 | private long lastDayErrorCount; 25 | private long lastDayMinMills; 26 | private long lastDayMaxMills; 27 | private long lastDayAvgMills; 28 | private Date lastDayMaxInvokeAt; 29 | //上一次的调用信息 30 | private long lastMills; 31 | private Date lastInvokeAt; 32 | public String getMethod() { 33 | return method; 34 | } 35 | public void setMethod(String method) { 36 | this.method = method; 37 | } 38 | public String getUri() { 39 | return uri; 40 | } 41 | public void setUri(String uri) { 42 | this.uri = uri; 43 | } 44 | public long getInvokeCount() { 45 | return invokeCount; 46 | } 47 | public void setInvokeCount(long invokeCount) { 48 | this.invokeCount = invokeCount; 49 | } 50 | public long getOkCount() { 51 | return okCount; 52 | } 53 | public void setOkCount(long okCount) { 54 | this.okCount = okCount; 55 | } 56 | public long getErrorCount() { 57 | return errorCount; 58 | } 59 | public void setErrorCount(long errorCount) { 60 | this.errorCount = errorCount; 61 | } 62 | public long getMinMills() { 63 | return minMills; 64 | } 65 | public void setMinMills(long minMills) { 66 | this.minMills = minMills; 67 | } 68 | public long getMaxMills() { 69 | return maxMills; 70 | } 71 | public void setMaxMills(long maxMills) { 72 | this.maxMills = maxMills; 73 | } 74 | public long getAvgMills() { 75 | return avgMills; 76 | } 77 | public void setAvgMills(long avgMills) { 78 | this.avgMills = avgMills; 79 | } 80 | public Date getMaxInvokeAt() { 81 | return maxInvokeAt; 82 | } 83 | public void setMaxInvokeAt(Date maxInvokeAt) { 84 | this.maxInvokeAt = maxInvokeAt; 85 | } 86 | public long getLastDayCount() { 87 | return lastDayCount; 88 | } 89 | public void setLastDayCount(long lastDayCount) { 90 | this.lastDayCount = lastDayCount; 91 | } 92 | public long getLastDayOkCount() { 93 | return lastDayOkCount; 94 | } 95 | public void setLastDayOkCount(long lastDayOkCount) { 96 | this.lastDayOkCount = lastDayOkCount; 97 | } 98 | public long getLastDayErrorCount() { 99 | return lastDayErrorCount; 100 | } 101 | public void setLastDayErrorCount(long lastDayErrorCount) { 102 | this.lastDayErrorCount = lastDayErrorCount; 103 | } 104 | public long getLastDayMinMills() { 105 | return lastDayMinMills; 106 | } 107 | public void setLastDayMinMills(long lastDayMinMills) { 108 | this.lastDayMinMills = lastDayMinMills; 109 | } 110 | public long getLastDayMaxMills() { 111 | return lastDayMaxMills; 112 | } 113 | public void setLastDayMaxMills(long lastDayMaxMills) { 114 | this.lastDayMaxMills = lastDayMaxMills; 115 | } 116 | public long getLastDayAvgMills() { 117 | return lastDayAvgMills; 118 | } 119 | public void setLastDayAvgMills(long lastDayAvgMills) { 120 | this.lastDayAvgMills = lastDayAvgMills; 121 | } 122 | public Date getLastDayMaxInvokeAt() { 123 | return lastDayMaxInvokeAt; 124 | } 125 | public void setLastDayMaxInvokeAt(Date lastDayMaxInvokeAt) { 126 | this.lastDayMaxInvokeAt = lastDayMaxInvokeAt; 127 | } 128 | public long getLastMills() { 129 | return lastMills; 130 | } 131 | public void setLastMills(long lastMills) { 132 | this.lastMills = lastMills; 133 | } 134 | public Date getLastInvokeAt() { 135 | return lastInvokeAt; 136 | } 137 | public void setLastInvokeAt(Date lastInvokeAt) { 138 | this.lastInvokeAt = lastInvokeAt; 139 | } 140 | } 141 | -------------------------------------------------------------------------------- /ezprofiler/ezprofiler-spring-boot-starter/src/main/java/com/github/xjs/ezprofiler/scanner/ControllerScaner.java: -------------------------------------------------------------------------------- 1 | package com.github.xjs.ezprofiler.scanner; 2 | 3 | import java.lang.reflect.Method; 4 | 5 | import org.aopalliance.intercept.MethodInterceptor; 6 | import org.aopalliance.intercept.MethodInvocation; 7 | import org.slf4j.Logger; 8 | import org.slf4j.LoggerFactory; 9 | import org.springframework.aop.framework.ProxyFactory; 10 | import org.springframework.beans.BeansException; 11 | import org.springframework.beans.factory.annotation.Autowired; 12 | import org.springframework.beans.factory.config.BeanPostProcessor; 13 | import org.springframework.core.annotation.AnnotatedElementUtils; 14 | import org.springframework.core.annotation.AnnotationUtils; 15 | import org.springframework.stereotype.Controller; 16 | import org.springframework.stereotype.Service; 17 | import org.springframework.web.bind.annotation.RequestMapping; 18 | 19 | import com.github.xjs.ezprofiler.annotation.Profiler; 20 | import com.github.xjs.ezprofiler.config.EzProfilerProperties; 21 | 22 | /** 23 | * @author 605162215@qq.com 24 | * 25 | * @date 2018年6月29日 下午12:59:59
26 | */ 27 | @Service 28 | public class ControllerScaner implements BeanPostProcessor{ 29 | 30 | private static Logger log = LoggerFactory.getLogger(ControllerScaner.class); 31 | 32 | @Autowired 33 | EzProfilerProperties properties; 34 | 35 | private ProfilerQueue queue = new ProfilerQueue(); 36 | 37 | public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { 38 | return bean; 39 | } 40 | 41 | /** 42 | * 拦截Controller和RestController类,生成他们的子类 43 | * */ 44 | public Object postProcessAfterInitialization(final Object bean, final String beanName) throws BeansException { 45 | final Class beanClass = bean.getClass(); 46 | final String beanClassName = beanClass.getName(); 47 | String basePackage = properties.getBasePackage();// env.getProperty("ezprofiler.basepackage", "com"); 48 | if(!beanClassName.startsWith(basePackage)) { 49 | return bean; 50 | } 51 | if(beanClassName.startsWith("org.springframework") || beanClassName.indexOf("EzProfilerController")>=0) { 52 | return bean; 53 | } 54 | if(!AnnotatedElementUtils.hasAnnotation(beanClass, Controller.class)) { 55 | return bean; 56 | } 57 | Profiler profiler = AnnotationUtils.findAnnotation(beanClass, Profiler.class); 58 | if(profiler!=null && !profiler.enable()) {//类上没有启用profiler 59 | return bean; 60 | } 61 | log.info("find controller:{}", beanName); 62 | ProxyFactory proxyFactory = new ProxyFactory(); 63 | proxyFactory.setTarget(bean); 64 | proxyFactory.addAdvice(new MethodInterceptor() { 65 | public Object invoke(MethodInvocation invocation) throws Throwable { 66 | Method method = invocation.getMethod(); 67 | Profiler methodProfiler = AnnotationUtils.findAnnotation(method, Profiler.class); 68 | //方法上没有启用 69 | if(methodProfiler != null && !methodProfiler.enable()) { 70 | return method.invoke(bean, invocation.getArguments()); 71 | } 72 | //不是一个requestMapping方法 73 | RequestMapping requestMappingAnnotation = AnnotatedElementUtils.getMergedAnnotation(method, RequestMapping.class); 74 | if(requestMappingAnnotation == null) { 75 | return method.invoke(bean, invocation.getArguments()); 76 | } 77 | //开始统计 78 | String uri = ""; 79 | long startAt = 0; 80 | long endAt = 0; 81 | boolean occurError=true; 82 | try { 83 | uri = requestMappingAnnotation.value()[0]; 84 | startAt = System.currentTimeMillis(); 85 | Object result = method.invoke(bean, invocation.getArguments()); 86 | endAt = System.currentTimeMillis(); 87 | occurError = false; 88 | return result; 89 | }catch(Exception e) { 90 | endAt = System.currentTimeMillis(); 91 | occurError = true; 92 | throw e; 93 | }finally { 94 | ProfileInfo info = new ProfileInfo(); 95 | info.setStart(startAt); 96 | info.setEnd(endAt); 97 | info.setUri(uri); 98 | info.setClazz(beanClass); 99 | info.setMethod(method); 100 | info.setOccurError(occurError); 101 | //入队 102 | queue.addProfileInfo(info); 103 | } 104 | } 105 | }); 106 | return proxyFactory.getProxy(); 107 | } 108 | 109 | } 110 | -------------------------------------------------------------------------------- /ezprofiler/ezprofiler-spring-boot-starter/src/main/java/com/github/xjs/ezprofiler/mapping/PropertySourcedRequestMappingHandlerMapping.java: -------------------------------------------------------------------------------- 1 | package com.github.xjs.ezprofiler.mapping; 2 | 3 | import java.lang.reflect.Method; 4 | import java.util.LinkedHashMap; 5 | import java.util.Map; 6 | 7 | import javax.servlet.http.HttpServletRequest; 8 | 9 | import org.slf4j.Logger; 10 | import org.slf4j.LoggerFactory; 11 | import org.springframework.core.Ordered; 12 | import org.springframework.core.annotation.AnnotationUtils; 13 | import org.springframework.core.env.Environment; 14 | import org.springframework.stereotype.Controller; 15 | import org.springframework.util.ReflectionUtils; 16 | import org.springframework.web.bind.annotation.RequestMapping; 17 | import org.springframework.web.bind.annotation.RestController; 18 | import org.springframework.web.method.HandlerMethod; 19 | import org.springframework.web.servlet.HandlerMapping; 20 | import org.springframework.web.servlet.mvc.method.RequestMappingInfo; 21 | import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping; 22 | import org.springframework.web.util.UriTemplate; 23 | 24 | /** 25 | * @author 605162215@qq.com 26 | * 27 | * @date 2018年7月2日 上午8:21:14
28 | */ 29 | public class PropertySourcedRequestMappingHandlerMapping extends RequestMappingHandlerMapping { 30 | 31 | private final static Logger logger = LoggerFactory.getLogger(PropertySourcedRequestMappingHandlerMapping.class); 32 | private final Map handlerMethods = new LinkedHashMap(); 33 | private final Environment environment; 34 | private final Object handler; 35 | 36 | public PropertySourcedRequestMappingHandlerMapping(Environment environment, Object handler) { 37 | this.environment = environment; 38 | this.handler = handler; 39 | } 40 | 41 | @Override 42 | protected void initHandlerMethods() { 43 | setOrder(Ordered.HIGHEST_PRECEDENCE + 1000); 44 | Class clazz = handler.getClass(); 45 | if (isHandler(clazz)) { 46 | for (Method method : clazz.getMethods()) { 47 | if(ReflectionUtils.isObjectMethod(method)) { 48 | continue; 49 | } 50 | PropertySourcedMapping mapper = AnnotationUtils.getAnnotation(method, PropertySourcedMapping.class); 51 | if (mapper != null) { 52 | RequestMappingInfo mapping = getMappingForMethod(method, clazz); 53 | HandlerMethod handlerMethod = createHandlerMethod(handler, method); 54 | String mappingPath = mappingPath(mapper); 55 | if (mappingPath != null) { 56 | logger.info(String.format("Mapped URL path [%s] onto method [%s]", mappingPath, handlerMethod.toString())); 57 | handlerMethods.put(mappingPath, handlerMethod); 58 | } else { 59 | for (String path : mapping.getPatternsCondition().getPatterns()) { 60 | logger.info(String.format("Mapped URL path [%s] onto method [%s]", path, handlerMethod.toString())); 61 | handlerMethods.put(path, handlerMethod); 62 | } 63 | } 64 | } 65 | } 66 | } 67 | } 68 | 69 | private String mappingPath(final PropertySourcedMapping mapper) { 70 | String propertyKey = mapper.propertyKey();// ezprofiler.url 71 | String propertyValue = environment.getProperty(propertyKey);// my.profiler 72 | if (propertyValue != null) { 73 | String realKey = String.format("${%s}", propertyKey); 74 | return propertyValue.replace(realKey, propertyValue); 75 | } 76 | return null; 77 | } 78 | 79 | @Override 80 | protected boolean isHandler(Class beanType) { 81 | return ((AnnotationUtils.findAnnotation(beanType, RestController.class) != null) 82 | || (AnnotationUtils.findAnnotation(beanType, RequestMapping.class) != null) 83 | || (AnnotationUtils.findAnnotation(beanType, Controller.class) != null)); 84 | } 85 | 86 | @Override 87 | protected HandlerMethod lookupHandlerMethod(String urlPath, HttpServletRequest request) throws Exception { 88 | logger.debug("looking up handler for path: " + urlPath); 89 | HandlerMethod handlerMethod = handlerMethods.get(urlPath); 90 | if (handlerMethod != null) { 91 | return handlerMethod; 92 | } 93 | for (String path : handlerMethods.keySet()) { 94 | UriTemplate template = new UriTemplate(path); 95 | if (template.matches(urlPath)) { 96 | request.setAttribute(HandlerMapping.URI_TEMPLATE_VARIABLES_ATTRIBUTE, template.match(urlPath)); 97 | return handlerMethods.get(path); 98 | } 99 | } 100 | return null; 101 | } 102 | } 103 | -------------------------------------------------------------------------------- /ezprofiler/ezprofiler-spring-boot-starter/src/main/java/com/github/xjs/ezprofiler/scanner/ProfileInfoHolder.java: -------------------------------------------------------------------------------- 1 | package com.github.xjs.ezprofiler.scanner; 2 | 3 | import java.lang.reflect.Method; 4 | import java.util.ArrayList; 5 | import java.util.Date; 6 | import java.util.HashMap; 7 | import java.util.List; 8 | import java.util.Map; 9 | import java.util.concurrent.ConcurrentHashMap; 10 | 11 | /** 12 | * @author 605162215@qq.com 13 | * 14 | * @date 2017年9月21日 下午3:02:30
15 | * 16 | */ 17 | public class ProfileInfoHolder { 18 | 19 | private static ConcurrentHashMap, ControllerAccessInfo> map = new ConcurrentHashMap, ControllerAccessInfo>(); 20 | 21 | @SuppressWarnings("deprecation") 22 | public static void addProfilerInfo(ProfileInfo pi) { 23 | long startAt = pi.getStart(); 24 | long endAt = pi.getEnd(); 25 | long useTime = endAt - startAt; 26 | String uri = pi.getUri(); 27 | boolean occurError = pi.isOccurError(); 28 | Class controllerClazz = pi.getClazz(); 29 | Method method = pi.getMethod(); 30 | ControllerAccessInfo cai = map.get(controllerClazz); 31 | if(cai == null) { 32 | cai = new ControllerAccessInfo(); 33 | cai.setControllerClazz(controllerClazz); 34 | map.put(controllerClazz, cai); 35 | } 36 | List mais = cai.getMethodInfos(); 37 | if(mais == null) { 38 | mais = new ArrayList(); 39 | cai.setMethodInfos(mais); 40 | } 41 | MethodAccessInfo mai = getMethodAccessInfo(mais, method); 42 | if(mai == null) {//第一次调用 43 | mai = new MethodAccessInfo(); 44 | mai.setMethod(method.getName()); 45 | mai.setUri(uri); 46 | mai.setInvokeCount(1); 47 | mai.setLastDayCount(1); 48 | if(occurError) { 49 | mai.setErrorCount(1); 50 | mai.setLastDayErrorCount(1); 51 | }else { 52 | mai.setOkCount(1); 53 | mai.setLastDayOkCount(1); 54 | } 55 | mai.setMinMills(useTime); 56 | mai.setMaxMills(useTime); 57 | mai.setAvgMills(useTime); 58 | mai.setMaxInvokeAt(new Date()); 59 | mai.setLastDayMinMills(useTime); 60 | mai.setLastDayMaxMills(useTime); 61 | mai.setLastDayAvgMills(useTime); 62 | mai.setLastDayMaxInvokeAt(new Date()); 63 | mai.setLastMills(useTime); 64 | mai.setLastInvokeAt(new Date()); 65 | mais.add(mai); 66 | }else {//之前已经有调用 67 | Date lastInvokeTime = mai.getLastInvokeAt(); 68 | Date now = new Date(); 69 | if(lastInvokeTime.getMonth() != now.getMonth() || lastInvokeTime.getDay() != now.getDay()) {//第二天重新计算 70 | mai.setLastDayCount(0); 71 | mai.setLastDayErrorCount(0); 72 | mai.setLastDayOkCount(0); 73 | mai.setLastDayAvgMills(useTime); 74 | mai.setLastDayMinMills(useTime); 75 | mai.setLastDayMaxMills(useTime); 76 | mai.setLastDayMaxInvokeAt(new Date()); 77 | } 78 | if(useTime < mai.getMinMills()) { 79 | mai.setMinMills(useTime); 80 | } 81 | if(useTime < mai.getLastDayMinMills()) { 82 | mai.setLastDayMinMills(useTime); 83 | } 84 | if(useTime > mai.getMaxMills()) { 85 | mai.setMaxMills(useTime); 86 | mai.setMaxInvokeAt(new Date()); 87 | } 88 | if(useTime > mai.getLastDayMaxMills()) { 89 | mai.setLastDayMaxMills(useTime); 90 | mai.setLastDayMaxInvokeAt(new Date()); 91 | } 92 | mai.setInvokeCount(mai.getInvokeCount() + 1); 93 | mai.setLastDayCount(mai.getLastDayCount() + 1); 94 | if(occurError) { 95 | mai.setErrorCount(mai.getErrorCount()+1); 96 | mai.setLastDayErrorCount(mai.getLastDayErrorCount()+1); 97 | }else { 98 | mai.setOkCount(mai.getOkCount()+1); 99 | mai.setLastDayOkCount(mai.getLastDayOkCount()+1); 100 | } 101 | mai.setAvgMills((mai.getAvgMills()+useTime)/2); 102 | mai.setLastDayAvgMills((mai.getLastDayAvgMills()+useTime)/2); 103 | mai.setLastInvokeAt(new Date()); 104 | mai.setLastMills(useTime); 105 | } 106 | } 107 | 108 | private static MethodAccessInfo getMethodAccessInfo(List mais, Method method) { 109 | for(MethodAccessInfo mai : mais) { 110 | if(method.getName().equals(mai.getMethod())) { 111 | return mai; 112 | } 113 | } 114 | return null; 115 | } 116 | 117 | public static Map getAllAccessInfo() { 118 | Map result = new HashMap(); 119 | for(Map.Entry, ControllerAccessInfo> entry : map.entrySet()) { 120 | ControllerAccessInfo cai = entry.getValue(); 121 | result.put(cai.getControllerClazz().getSimpleName(), cai.getMethodInfos()); 122 | } 123 | return result; 124 | } 125 | } 126 | --------------------------------------------------------------------------------