接口监控
This commit is contained in:
parent
776d22784b
commit
7b52f60c9e
@ -11,7 +11,6 @@ import org.aspectj.lang.reflect.MethodSignature;
|
|||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
import java.util.Date;
|
|
||||||
|
|
||||||
@Aspect
|
@Aspect
|
||||||
@Component
|
@Component
|
||||||
@ -36,7 +35,7 @@ public class TaskAspect {
|
|||||||
@AfterReturning(pointcut = "scheduledPointcut()")
|
@AfterReturning(pointcut = "scheduledPointcut()")
|
||||||
public void afterReturningCall(JoinPoint joinPoint) {
|
public void afterReturningCall(JoinPoint joinPoint) {
|
||||||
long start = RequestIdUtil.getTime();
|
long start = RequestIdUtil.getTime();
|
||||||
long time = new Date().getTime() - start;
|
long time = System.currentTimeMillis() - start;
|
||||||
// 获取注解中的参数值
|
// 获取注解中的参数值
|
||||||
MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
|
MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
|
||||||
Method method = methodSignature.getMethod();
|
Method method = methodSignature.getMethod();
|
||||||
|
|||||||
@ -1,8 +1,11 @@
|
|||||||
package com.syzb.common.aspect;
|
package com.syzb.common.aspect;
|
||||||
|
|
||||||
import com.alibaba.fastjson.JSONObject;
|
import com.alibaba.fastjson.JSONObject;
|
||||||
|
import com.syzb.common.handler.BizException;
|
||||||
|
import com.syzb.common.result.ResponseStatus;
|
||||||
import com.syzb.common.util.RequestIdUtil;
|
import com.syzb.common.util.RequestIdUtil;
|
||||||
import com.syzb.common.util.logger.LoggerUtil;
|
import com.syzb.common.util.logger.LoggerUtil;
|
||||||
|
import com.syzb.monitor.service.MonitorService;
|
||||||
import org.apache.commons.lang3.exception.ExceptionUtils;
|
import org.apache.commons.lang3.exception.ExceptionUtils;
|
||||||
import org.aspectj.lang.JoinPoint;
|
import org.aspectj.lang.JoinPoint;
|
||||||
import org.aspectj.lang.annotation.*;
|
import org.aspectj.lang.annotation.*;
|
||||||
@ -12,17 +15,20 @@ import org.springframework.web.context.request.RequestContextHolder;
|
|||||||
import org.springframework.web.context.request.ServletRequestAttributes;
|
import org.springframework.web.context.request.ServletRequestAttributes;
|
||||||
import org.springframework.web.multipart.MultipartFile;
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
|
||||||
|
import javax.annotation.Resource;
|
||||||
import javax.servlet.ServletRequest;
|
import javax.servlet.ServletRequest;
|
||||||
import javax.servlet.ServletResponse;
|
import javax.servlet.ServletResponse;
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Date;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@Aspect
|
@Aspect
|
||||||
@Component
|
@Component
|
||||||
public class WebLogAspect {
|
public class WebLogAspect {
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private MonitorService monitorService;
|
||||||
|
|
||||||
@Pointcut("@annotation(org.springframework.web.bind.annotation.RequestMapping)")
|
@Pointcut("@annotation(org.springframework.web.bind.annotation.RequestMapping)")
|
||||||
private void requestPointcut() {
|
private void requestPointcut() {
|
||||||
}
|
}
|
||||||
@ -51,8 +57,9 @@ public class WebLogAspect {
|
|||||||
}
|
}
|
||||||
arguments.add(arg);
|
arguments.add(arg);
|
||||||
}
|
}
|
||||||
if (!request.getRequestURI().contains("/swagger") && !request.getRequestURI().contains("/v3/api-docs")) {
|
String uri = request.getRequestURI();
|
||||||
LoggerUtil.data.info(String.format("%s:param:%s", request.getRequestURI(), JSONObject.toJSONString(arguments)));
|
if (!uri.contains("/swagger") && !uri.contains("/v3/api-docs")) {
|
||||||
|
LoggerUtil.data.info(String.format("%s:param:%s", uri, JSONObject.toJSONString(arguments)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -60,22 +67,29 @@ public class WebLogAspect {
|
|||||||
@AfterReturning(returning = "returnOb", pointcut = "requestPointcut() || getPointcut() || postPointcut())")
|
@AfterReturning(returning = "returnOb", pointcut = "requestPointcut() || getPointcut() || postPointcut())")
|
||||||
public void afterReturningCall(JoinPoint joinPoint, Object returnOb) {
|
public void afterReturningCall(JoinPoint joinPoint, Object returnOb) {
|
||||||
long start = RequestIdUtil.getTime();
|
long start = RequestIdUtil.getTime();
|
||||||
long time = new Date().getTime() - start;
|
long time = System.currentTimeMillis() - start;
|
||||||
ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.currentRequestAttributes();
|
ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.currentRequestAttributes();
|
||||||
HttpServletRequest request = requestAttributes.getRequest();
|
HttpServletRequest request = requestAttributes.getRequest();
|
||||||
if (!request.getRequestURI().contains("/swagger") && !request.getRequestURI().contains("/v3/api-docs") && !(returnOb instanceof HttpEntity)) {
|
String uri = request.getRequestURI();
|
||||||
LoggerUtil.data.info(String.format("%s:耗时:%d", request.getRequestURI(), time));
|
if (!uri.contains("/swagger") && !uri.contains("/v3/api-docs") && !(returnOb instanceof HttpEntity)) {
|
||||||
LoggerUtil.data.info(String.format("%s:result:%s", request.getRequestURI(), JSONObject.toJSONString(returnOb)));
|
LoggerUtil.data.info(String.format("%s:耗时:%d", uri, time));
|
||||||
|
LoggerUtil.data.info(String.format("%s:result:%s", uri, JSONObject.toJSONString(returnOb)));
|
||||||
|
monitorService.add(uri, (int) time);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 异常通知
|
// 异常通知
|
||||||
@AfterThrowing(value = "requestPointcut() || getPointcut() || postPointcut()", throwing = "ex")
|
@AfterThrowing(value = "requestPointcut() || getPointcut() || postPointcut()", throwing = "ex")
|
||||||
public void afterThrowing(JoinPoint joinPoint, Exception ex) {
|
public void afterThrowing(JoinPoint joinPoint, Exception ex) {
|
||||||
|
long start = RequestIdUtil.getTime();
|
||||||
|
long time = System.currentTimeMillis() - start;
|
||||||
ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.currentRequestAttributes();
|
ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.currentRequestAttributes();
|
||||||
HttpServletRequest request = requestAttributes.getRequest();
|
HttpServletRequest request = requestAttributes.getRequest();
|
||||||
if (!request.getRequestURI().contains("/swagger") && !request.getRequestURI().contains("/v3/api-docs")) {
|
String uri = request.getRequestURI();
|
||||||
LoggerUtil.data.info(String.format("%s:exception:%s", request.getRequestURI(), ExceptionUtils.getStackTrace(ex)));
|
if (!uri.contains("/swagger") && !uri.contains("/v3/api-docs")) {
|
||||||
|
LoggerUtil.data.info(String.format("%s:exception:%s", uri, ExceptionUtils.getStackTrace(ex)));
|
||||||
|
Integer code = ex instanceof BizException ? ((BizException)ex).getErrorCode() : ResponseStatus.SYS_BUSY.code;
|
||||||
|
monitorService.add(uri, (int) time, code);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -4,8 +4,6 @@ import cn.hutool.core.util.RandomUtil;
|
|||||||
import cn.hutool.core.util.StrUtil;
|
import cn.hutool.core.util.StrUtil;
|
||||||
import org.slf4j.MDC;
|
import org.slf4j.MDC;
|
||||||
|
|
||||||
import java.util.Date;
|
|
||||||
|
|
||||||
public class RequestIdUtil {
|
public class RequestIdUtil {
|
||||||
|
|
||||||
public static void setValue(String str) {
|
public static void setValue(String str) {
|
||||||
@ -28,7 +26,7 @@ public class RequestIdUtil {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static void setTime() {
|
public static void setTime() {
|
||||||
MDC.put("requestTime", String.valueOf(new Date().getTime()));
|
MDC.put("requestTime", String.valueOf(System.currentTimeMillis()));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static long getTime() {
|
public static long getTime() {
|
||||||
|
|||||||
@ -0,0 +1,48 @@
|
|||||||
|
package com.syzb.monitor.controller;
|
||||||
|
|
||||||
|
import com.syzb.common.result.CommonResult;
|
||||||
|
import com.syzb.monitor.entity.InterfaceMonitor;
|
||||||
|
import com.syzb.monitor.query.MonitorQuery;
|
||||||
|
import com.syzb.monitor.service.MonitorService;
|
||||||
|
import io.swagger.annotations.Api;
|
||||||
|
import io.swagger.annotations.ApiParam;
|
||||||
|
import org.springframework.validation.annotation.Validated;
|
||||||
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestBody;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
|
import javax.annotation.Resource;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Api(tags = "monitor")
|
||||||
|
@RestController
|
||||||
|
public class MonitorController {
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private MonitorService monitorService;
|
||||||
|
|
||||||
|
@PostMapping("/admin/monitor/listIP")
|
||||||
|
public CommonResult<List<String>> listIP(@Validated @RequestBody @ApiParam(required = true) MonitorQuery query) {
|
||||||
|
List<String> list = monitorService.listIP(query);
|
||||||
|
return CommonResult.success(list);
|
||||||
|
}
|
||||||
|
|
||||||
|
@PostMapping("/admin/monitor/listInterface")
|
||||||
|
public CommonResult<List<String>> listInterface(@Validated @RequestBody @ApiParam(required = true) MonitorQuery query) {
|
||||||
|
List<String> list = monitorService.listInterface(query);
|
||||||
|
return CommonResult.success(list);
|
||||||
|
}
|
||||||
|
|
||||||
|
@PostMapping("/admin/monitor/listData")
|
||||||
|
public CommonResult<List<InterfaceMonitor>> listData(@Validated @RequestBody @ApiParam(required = true) MonitorQuery query) {
|
||||||
|
List<InterfaceMonitor> list = monitorService.listData(query);
|
||||||
|
return CommonResult.success(list);
|
||||||
|
}
|
||||||
|
|
||||||
|
@PostMapping("/admin/monitor/groupData")
|
||||||
|
public CommonResult<List<InterfaceMonitor>> groupData(@Validated @RequestBody @ApiParam(required = true) MonitorQuery query) {
|
||||||
|
List<InterfaceMonitor> list = monitorService.groupData(query);
|
||||||
|
return CommonResult.success(list);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
218
src/main/java/com/syzb/monitor/entity/InterfaceMonitor.java
Normal file
218
src/main/java/com/syzb/monitor/entity/InterfaceMonitor.java
Normal file
@ -0,0 +1,218 @@
|
|||||||
|
package com.syzb.monitor.entity;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableField;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableId;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <p>
|
||||||
|
* 接口监控统计表
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* @author helloSyzb
|
||||||
|
* @since 2025-04-09
|
||||||
|
*/
|
||||||
|
public class InterfaceMonitor implements Serializable {
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 统计时间
|
||||||
|
*/
|
||||||
|
private LocalDateTime time;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 接口名称
|
||||||
|
*/
|
||||||
|
@TableId("interface_name")
|
||||||
|
private String interfaceName;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 请求来源IP地址
|
||||||
|
*/
|
||||||
|
private String ip;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 接口调用总次数
|
||||||
|
*/
|
||||||
|
private Integer total;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 接口调用平均耗时(毫秒)
|
||||||
|
*/
|
||||||
|
@TableField("average_time")
|
||||||
|
private Integer averageTime;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 接口调用最大耗时(毫秒)
|
||||||
|
*/
|
||||||
|
@TableField("max_time")
|
||||||
|
private Integer maxTime;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 接口调用最小耗时(毫秒)
|
||||||
|
*/
|
||||||
|
@TableField("min_time")
|
||||||
|
private Integer minTime;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 接口调用失败次数
|
||||||
|
*/
|
||||||
|
private Integer failure;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 接口耗时超过10ms的次数
|
||||||
|
*/
|
||||||
|
@TableField("over_10ms")
|
||||||
|
private Integer over10ms;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 接口耗时超过50ms的次数
|
||||||
|
*/
|
||||||
|
@TableField("over_50ms")
|
||||||
|
private Integer over50ms;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 接口耗时超过100ms的次数
|
||||||
|
*/
|
||||||
|
@TableField("over_100ms")
|
||||||
|
private Integer over100ms;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 接口耗时超过500ms的次数
|
||||||
|
*/
|
||||||
|
@TableField("over_500ms")
|
||||||
|
private Integer over500ms;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 接口耗时超过1000ms的次数
|
||||||
|
*/
|
||||||
|
@TableField("over_1000ms")
|
||||||
|
private Integer over1000ms;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 接口耗时超过5000ms的次数
|
||||||
|
*/
|
||||||
|
@TableField("over_5000ms")
|
||||||
|
private Integer over5000ms;
|
||||||
|
|
||||||
|
public LocalDateTime getTime() {
|
||||||
|
return time;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTime(LocalDateTime time) {
|
||||||
|
this.time = time;
|
||||||
|
}
|
||||||
|
public String getInterfaceName() {
|
||||||
|
return interfaceName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setInterfaceName(String interfaceName) {
|
||||||
|
this.interfaceName = interfaceName;
|
||||||
|
}
|
||||||
|
public String getIp() {
|
||||||
|
return ip;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setIp(String ip) {
|
||||||
|
this.ip = ip;
|
||||||
|
}
|
||||||
|
public Integer getTotal() {
|
||||||
|
return total;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTotal(Integer total) {
|
||||||
|
this.total = total;
|
||||||
|
}
|
||||||
|
public Integer getAverageTime() {
|
||||||
|
return averageTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAverageTime(Integer averageTime) {
|
||||||
|
this.averageTime = averageTime;
|
||||||
|
}
|
||||||
|
public Integer getMaxTime() {
|
||||||
|
return maxTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMaxTime(Integer maxTime) {
|
||||||
|
this.maxTime = maxTime;
|
||||||
|
}
|
||||||
|
public Integer getMinTime() {
|
||||||
|
return minTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMinTime(Integer minTime) {
|
||||||
|
this.minTime = minTime;
|
||||||
|
}
|
||||||
|
public Integer getFailure() {
|
||||||
|
return failure;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setFailure(Integer failure) {
|
||||||
|
this.failure = failure;
|
||||||
|
}
|
||||||
|
public Integer getOver10ms() {
|
||||||
|
return over10ms;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setOver10ms(Integer over10ms) {
|
||||||
|
this.over10ms = over10ms;
|
||||||
|
}
|
||||||
|
public Integer getOver50ms() {
|
||||||
|
return over50ms;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setOver50ms(Integer over50ms) {
|
||||||
|
this.over50ms = over50ms;
|
||||||
|
}
|
||||||
|
public Integer getOver100ms() {
|
||||||
|
return over100ms;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setOver100ms(Integer over100ms) {
|
||||||
|
this.over100ms = over100ms;
|
||||||
|
}
|
||||||
|
public Integer getOver500ms() {
|
||||||
|
return over500ms;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setOver500ms(Integer over500ms) {
|
||||||
|
this.over500ms = over500ms;
|
||||||
|
}
|
||||||
|
public Integer getOver1000ms() {
|
||||||
|
return over1000ms;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setOver1000ms(Integer over1000ms) {
|
||||||
|
this.over1000ms = over1000ms;
|
||||||
|
}
|
||||||
|
public Integer getOver5000ms() {
|
||||||
|
return over5000ms;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setOver5000ms(Integer over5000ms) {
|
||||||
|
this.over5000ms = over5000ms;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "InterfaceMonitor{" +
|
||||||
|
"time=" + time +
|
||||||
|
", interfaceName=" + interfaceName +
|
||||||
|
", ip=" + ip +
|
||||||
|
", total=" + total +
|
||||||
|
", averageTime=" + averageTime +
|
||||||
|
", maxTime=" + maxTime +
|
||||||
|
", minTime=" + minTime +
|
||||||
|
", failure=" + failure +
|
||||||
|
", over10ms=" + over10ms +
|
||||||
|
", over50ms=" + over50ms +
|
||||||
|
", over100ms=" + over100ms +
|
||||||
|
", over500ms=" + over500ms +
|
||||||
|
", over1000ms=" + over1000ms +
|
||||||
|
", over5000ms=" + over5000ms +
|
||||||
|
"}";
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,16 @@
|
|||||||
|
package com.syzb.monitor.mapper;
|
||||||
|
|
||||||
|
import com.syzb.common.mapper.EasyBaseMapper;
|
||||||
|
import com.syzb.monitor.entity.InterfaceMonitor;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <p>
|
||||||
|
* 接口监控统计表 Mapper 接口
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* @author helloSyzb
|
||||||
|
* @since 2025-04-09
|
||||||
|
*/
|
||||||
|
public interface InterfaceMonitorMapper extends EasyBaseMapper<InterfaceMonitor> {
|
||||||
|
|
||||||
|
}
|
||||||
69
src/main/java/com/syzb/monitor/query/MonitorQuery.java
Normal file
69
src/main/java/com/syzb/monitor/query/MonitorQuery.java
Normal file
@ -0,0 +1,69 @@
|
|||||||
|
package com.syzb.monitor.query;
|
||||||
|
|
||||||
|
import javax.validation.constraints.NotNull;
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
|
||||||
|
public class MonitorQuery {
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
private LocalDateTime startTime;
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
private LocalDateTime endTime;
|
||||||
|
|
||||||
|
private String ip;
|
||||||
|
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
private String ticket;
|
||||||
|
|
||||||
|
private String groupBy;
|
||||||
|
|
||||||
|
public LocalDateTime getStartTime() {
|
||||||
|
return startTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setStartTime(LocalDateTime startTime) {
|
||||||
|
this.startTime = startTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
public LocalDateTime getEndTime() {
|
||||||
|
return endTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setEndTime(LocalDateTime endTime) {
|
||||||
|
this.endTime = endTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getIp() {
|
||||||
|
return ip;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setIp(String ip) {
|
||||||
|
this.ip = ip;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setName(String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getTicket() {
|
||||||
|
return ticket;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTicket(String ticket) {
|
||||||
|
this.ticket = ticket;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getGroupBy() {
|
||||||
|
return groupBy;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setGroupBy(String groupBy) {
|
||||||
|
this.groupBy = groupBy;
|
||||||
|
}
|
||||||
|
}
|
||||||
250
src/main/java/com/syzb/monitor/service/MonitorService.java
Normal file
250
src/main/java/com/syzb/monitor/service/MonitorService.java
Normal file
@ -0,0 +1,250 @@
|
|||||||
|
package com.syzb.monitor.service;
|
||||||
|
|
||||||
|
import cn.hutool.core.date.DatePattern;
|
||||||
|
import cn.hutool.core.util.StrUtil;
|
||||||
|
import cn.hutool.crypto.SecureUtil;
|
||||||
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||||
|
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||||
|
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||||
|
import com.hazelcast.core.HazelcastInstance;
|
||||||
|
import com.syzb.common.handler.BizException;
|
||||||
|
import com.syzb.common.result.ResponseStatus;
|
||||||
|
import com.syzb.monitor.entity.InterfaceMonitor;
|
||||||
|
import com.syzb.monitor.mapper.InterfaceMonitorMapper;
|
||||||
|
import com.syzb.monitor.query.MonitorQuery;
|
||||||
|
import com.syzb.monitor.vo.MonitorResult;
|
||||||
|
import org.springframework.scheduling.annotation.Scheduled;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import javax.annotation.PostConstruct;
|
||||||
|
import javax.annotation.Resource;
|
||||||
|
import java.time.LocalDate;
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
@Service
|
||||||
|
public class MonitorService {
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private HazelcastInstance hazelcastInstance;
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private InterfaceMonitorMapper interfaceMonitorMapper;
|
||||||
|
|
||||||
|
private String host;
|
||||||
|
|
||||||
|
// 记录保存天数
|
||||||
|
private static final int SAVE_DAY = 15;
|
||||||
|
|
||||||
|
@PostConstruct
|
||||||
|
private void loadHost() {
|
||||||
|
host = hazelcastInstance.getCluster().getLocalMember().getAddress().getHost();
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<MonitorResult> results = new ArrayList<>();
|
||||||
|
|
||||||
|
public void add(String name, Integer time) {
|
||||||
|
this.add(name, time, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void add(String name, Integer time, Integer code) {
|
||||||
|
this.results.add(new MonitorResult(name, time, code));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Scheduled(cron = "0 * * * * ?")
|
||||||
|
public void save() {
|
||||||
|
List<InterfaceMonitor> list = this.statistic();
|
||||||
|
interfaceMonitorMapper.insertBatchSomeColumn(list);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Scheduled(cron = "0 1 2 * * ?")
|
||||||
|
public void clear() {
|
||||||
|
LocalDateTime time = LocalDate.now().minusDays(SAVE_DAY).atStartOfDay();
|
||||||
|
LambdaQueryWrapper<InterfaceMonitor> wrapper = Wrappers.<InterfaceMonitor>lambdaQuery()
|
||||||
|
.lt(InterfaceMonitor::getTime, time);
|
||||||
|
interfaceMonitorMapper.delete(wrapper);
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<String> listIP(MonitorQuery query) {
|
||||||
|
checkTicket(query);
|
||||||
|
LocalDateTime startTime = query.getStartTime();
|
||||||
|
LocalDateTime endTime = query.getEndTime();
|
||||||
|
QueryWrapper<InterfaceMonitor> wrapper = Wrappers.<InterfaceMonitor>query()
|
||||||
|
.select("distinct ip")
|
||||||
|
.ge("time", startTime)
|
||||||
|
.lt("time", endTime)
|
||||||
|
.orderByAsc("ip");
|
||||||
|
List<InterfaceMonitor> list = interfaceMonitorMapper.selectList(wrapper);
|
||||||
|
return list.stream().map(InterfaceMonitor::getIp).collect(Collectors.toList());
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<String> listInterface(MonitorQuery query) {
|
||||||
|
checkTicket(query);
|
||||||
|
LocalDateTime startTime = query.getStartTime();
|
||||||
|
LocalDateTime endTime = query.getEndTime();
|
||||||
|
QueryWrapper<InterfaceMonitor> wrapper = Wrappers.<InterfaceMonitor>query()
|
||||||
|
.select("distinct interface_name")
|
||||||
|
.ge("time", startTime)
|
||||||
|
.lt("time", endTime)
|
||||||
|
.orderByAsc("interface_name");
|
||||||
|
List<InterfaceMonitor> list = interfaceMonitorMapper.selectList(wrapper);
|
||||||
|
return list.stream().map(InterfaceMonitor::getInterfaceName).collect(Collectors.toList());
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<InterfaceMonitor> listData(MonitorQuery query) {
|
||||||
|
checkTicket(query);
|
||||||
|
LocalDateTime startTime = query.getStartTime();
|
||||||
|
LocalDateTime endTime = query.getEndTime();
|
||||||
|
String ip = query.getIp();
|
||||||
|
String name = query.getName();
|
||||||
|
QueryWrapper<InterfaceMonitor> wrapper = Wrappers.<InterfaceMonitor>query()
|
||||||
|
.select("time", "sum(total) as total", "avg(average_time) as average_time", "max(max_time) as max_time", "min(min_time) as min_time",
|
||||||
|
"sum(failure) as failure", "sum(over_10ms) as over_10ms", "sum(over_50ms) as over_50ms", "sum(over_100ms) as over_100ms",
|
||||||
|
"sum(over_500ms) as over_500ms", "sum(over_1000ms) as over_1000ms", "sum(over_5000ms) as over_5000ms")
|
||||||
|
.ge("time", startTime)
|
||||||
|
.lt("time", endTime)
|
||||||
|
.eq(StrUtil.isNotEmpty(ip), "ip", ip)
|
||||||
|
.likeRight(StrUtil.isNotEmpty(name), "interface_name", name)
|
||||||
|
.groupBy("time")
|
||||||
|
.orderByAsc("time");
|
||||||
|
return interfaceMonitorMapper.selectList(wrapper);
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<InterfaceMonitor> groupData(MonitorQuery query) {
|
||||||
|
checkTicket(query);
|
||||||
|
LocalDateTime startTime = query.getStartTime();
|
||||||
|
LocalDateTime endTime = query.getEndTime();
|
||||||
|
String groupBy = query.getGroupBy();
|
||||||
|
String groupColumn;
|
||||||
|
if ("ip".equals(groupBy)) {
|
||||||
|
groupColumn = "ip";
|
||||||
|
} else if ("name".equals(groupBy)) {
|
||||||
|
groupColumn = "interface_name";
|
||||||
|
} else {
|
||||||
|
throw new BizException(ResponseStatus.OUTSYS_ERROR);
|
||||||
|
}
|
||||||
|
QueryWrapper<InterfaceMonitor> wrapper = Wrappers.<InterfaceMonitor>query()
|
||||||
|
.select(groupColumn,
|
||||||
|
"sum(total) as total", "avg(average_time) as average_time", "max(max_time) as max_time", "min(min_time) as min_time",
|
||||||
|
"sum(failure) as failure", "sum(over_10ms) as over_10ms", "sum(over_50ms) as over_50ms", "sum(over_100ms) as over_100ms",
|
||||||
|
"sum(over_500ms) as over_500ms", "sum(over_1000ms) as over_1000ms", "sum(over_5000ms) as over_5000ms")
|
||||||
|
.ge("time", startTime)
|
||||||
|
.lt("time", endTime)
|
||||||
|
.groupBy(groupColumn)
|
||||||
|
.orderByAsc(groupColumn);
|
||||||
|
return interfaceMonitorMapper.selectList(wrapper);
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<InterfaceMonitor> statistic() {
|
||||||
|
// 暂存当前结果列表并清空缓存
|
||||||
|
List<MonitorResult> list = results;
|
||||||
|
results = new ArrayList<>();
|
||||||
|
LocalDateTime now = LocalDateTime.now().withSecond(0).withNano(0);
|
||||||
|
|
||||||
|
// 按接口名汇总
|
||||||
|
Map<String, List<MonitorResult>> map = list.stream().collect(Collectors.groupingBy(result -> result.name));
|
||||||
|
|
||||||
|
// 按接口计算总次数、平均耗时、最大耗时、最小耗时、失败次数、各耗时区间次数
|
||||||
|
List<InterfaceMonitor> monitors = new ArrayList<>(map.size());
|
||||||
|
|
||||||
|
map.forEach((interfaceName, resultList) -> {
|
||||||
|
InterfaceMonitor monitor = new InterfaceMonitor();
|
||||||
|
monitor.setTime(now);
|
||||||
|
monitor.setInterfaceName(interfaceName);
|
||||||
|
monitor.setIp(host);
|
||||||
|
|
||||||
|
int total = resultList.size();
|
||||||
|
int failureCount = 0;
|
||||||
|
int totalTime = 0;
|
||||||
|
int maxTime = 0;
|
||||||
|
int minTime = 10000;
|
||||||
|
int over10ms = 0;
|
||||||
|
int over50ms = 0;
|
||||||
|
int over100ms = 0;
|
||||||
|
int over500ms = 0;
|
||||||
|
int over1000ms = 0;
|
||||||
|
int over5000ms = 0;
|
||||||
|
|
||||||
|
for (MonitorResult result : resultList) {
|
||||||
|
int time = result.time;
|
||||||
|
|
||||||
|
// 计算总时间用于后面计算平均值
|
||||||
|
totalTime += time;
|
||||||
|
|
||||||
|
// 计算最大最小时间
|
||||||
|
maxTime = Math.max(time, maxTime);
|
||||||
|
minTime = Math.min(time, minTime);
|
||||||
|
|
||||||
|
// 计算各时间区间次数
|
||||||
|
if (time >= 10) {
|
||||||
|
over10ms++;
|
||||||
|
if (time >= 50) {
|
||||||
|
over50ms++;
|
||||||
|
if (time >= 100) {
|
||||||
|
over100ms++;
|
||||||
|
if (time >= 500) {
|
||||||
|
over500ms++;
|
||||||
|
if (time >= 1000) {
|
||||||
|
over1000ms++;
|
||||||
|
if (time >= 5000) {
|
||||||
|
over5000ms++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 计算失败次数
|
||||||
|
if (result.code != null && result.code != 0) {
|
||||||
|
failureCount++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 设置计算结果
|
||||||
|
monitor.setTotal(total);
|
||||||
|
monitor.setFailure(failureCount);
|
||||||
|
|
||||||
|
if (total > 0) {
|
||||||
|
monitor.setAverageTime(totalTime / total);
|
||||||
|
monitor.setMaxTime(maxTime);
|
||||||
|
monitor.setMinTime(minTime);
|
||||||
|
} else {
|
||||||
|
monitor.setAverageTime(0);
|
||||||
|
monitor.setMaxTime(0);
|
||||||
|
monitor.setMinTime(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
monitor.setOver10ms(over10ms);
|
||||||
|
monitor.setOver50ms(over50ms);
|
||||||
|
monitor.setOver100ms(over100ms);
|
||||||
|
monitor.setOver500ms(over500ms);
|
||||||
|
monitor.setOver1000ms(over1000ms);
|
||||||
|
monitor.setOver5000ms(over5000ms);
|
||||||
|
|
||||||
|
monitors.add(monitor);
|
||||||
|
});
|
||||||
|
|
||||||
|
return monitors;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void checkTicket(MonitorQuery query) {
|
||||||
|
if (!query.getTicket().equals(getTicket())) {
|
||||||
|
throw new BizException(ResponseStatus.OUTSYS_ERROR);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String getTicket() {
|
||||||
|
String prefix = "hello_syzb_";
|
||||||
|
String date = LocalDate.now().format(DatePattern.PURE_DATE_FORMATTER);
|
||||||
|
return SecureUtil.md5(prefix + date);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
System.out.println(getTicket());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
15
src/main/java/com/syzb/monitor/vo/MonitorResult.java
Normal file
15
src/main/java/com/syzb/monitor/vo/MonitorResult.java
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
package com.syzb.monitor.vo;
|
||||||
|
|
||||||
|
public class MonitorResult {
|
||||||
|
// 接口名
|
||||||
|
public String name;
|
||||||
|
// 接口耗时
|
||||||
|
public Integer time;
|
||||||
|
// 接口返回码(0:成功;非0:失败)
|
||||||
|
public Integer code;
|
||||||
|
public MonitorResult(String name, Integer time, Integer code) {
|
||||||
|
this.name = name;
|
||||||
|
this.time = time;
|
||||||
|
this.code = code;
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user