From 13a15db7d272754327fa78c54787b27f858eb64b Mon Sep 17 00:00:00 2001 From: nagocoler Date: Mon, 11 Dec 2023 16:28:36 +0800 Subject: [PATCH] =?UTF-8?q?=E5=AE=8C=E6=88=90=E8=BF=90=E8=A1=8C=E6=97=B6?= =?UTF-8?q?=E6=95=B0=E6=8D=AE=E4=B8=8A=E6=8A=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- itbaima-monitor-client/pom.xml | 4 ++ .../example/config/QuartzConfiguration.java | 30 ++++++++++ .../com/example/entity/RuntimeDetail.java | 17 ++++++ .../java/com/example/task/MonitorJobBean.java | 26 ++++++++ .../java/com/example/utils/MonitorUtils.java | 60 +++++++++++++++++++ .../main/java/com/example/utils/NetUtils.java | 9 ++- .../example/controller/ClientController.java | 8 +++ .../entity/vo/request/RuntimeDetailVO.java | 25 ++++++++ .../com/example/filter/RequestLogFilter.java | 2 +- .../com/example/service/ClientService.java | 2 + .../service/impl/ClientServiceImpl.java | 10 +++- 11 files changed, 190 insertions(+), 3 deletions(-) create mode 100644 itbaima-monitor-client/src/main/java/com/example/config/QuartzConfiguration.java create mode 100644 itbaima-monitor-client/src/main/java/com/example/entity/RuntimeDetail.java create mode 100644 itbaima-monitor-client/src/main/java/com/example/task/MonitorJobBean.java create mode 100644 itbaima-monitor-server/src/main/java/com/example/entity/vo/request/RuntimeDetailVO.java diff --git a/itbaima-monitor-client/pom.xml b/itbaima-monitor-client/pom.xml index fedb25e..4e4531e 100644 --- a/itbaima-monitor-client/pom.xml +++ b/itbaima-monitor-client/pom.xml @@ -32,6 +32,10 @@ spring-boot-starter-test test + + org.springframework.boot + spring-boot-starter-quartz + com.alibaba.fastjson2 fastjson2 diff --git a/itbaima-monitor-client/src/main/java/com/example/config/QuartzConfiguration.java b/itbaima-monitor-client/src/main/java/com/example/config/QuartzConfiguration.java new file mode 100644 index 0000000..524d788 --- /dev/null +++ b/itbaima-monitor-client/src/main/java/com/example/config/QuartzConfiguration.java @@ -0,0 +1,30 @@ +package com.example.config; + +import com.example.task.MonitorJobBean; +import lombok.extern.slf4j.Slf4j; +import org.quartz.*; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +@Slf4j +@Configuration +public class QuartzConfiguration { + + @Bean + public JobDetail jobDetailFactoryBean() { + return JobBuilder.newJob(MonitorJobBean.class) + .withIdentity("monitor-task") + .storeDurably() + .build(); + } + + @Bean + public Trigger cronTriggerFactoryBean(JobDetail detail) { + CronScheduleBuilder cron = CronScheduleBuilder.cronSchedule("*/10 * * * * ?"); + return TriggerBuilder.newTrigger() + .forJob(detail) + .withIdentity("monitor-trigger") + .withSchedule(cron) + .build(); + } +} diff --git a/itbaima-monitor-client/src/main/java/com/example/entity/RuntimeDetail.java b/itbaima-monitor-client/src/main/java/com/example/entity/RuntimeDetail.java new file mode 100644 index 0000000..46bad3d --- /dev/null +++ b/itbaima-monitor-client/src/main/java/com/example/entity/RuntimeDetail.java @@ -0,0 +1,17 @@ +package com.example.entity; + +import lombok.Data; +import lombok.experimental.Accessors; + +@Data +@Accessors(chain = true) +public class RuntimeDetail { + long timestamp; + double cpuUsage; + double memoryUsage; + double diskUsage; + double networkUpload; + double networkDownload; + double diskRead; + double diskWrite; +} diff --git a/itbaima-monitor-client/src/main/java/com/example/task/MonitorJobBean.java b/itbaima-monitor-client/src/main/java/com/example/task/MonitorJobBean.java new file mode 100644 index 0000000..cf5be8a --- /dev/null +++ b/itbaima-monitor-client/src/main/java/com/example/task/MonitorJobBean.java @@ -0,0 +1,26 @@ +package com.example.task; + +import com.example.entity.RuntimeDetail; +import com.example.utils.MonitorUtils; +import com.example.utils.NetUtils; +import jakarta.annotation.Resource; +import org.quartz.JobExecutionContext; +import org.quartz.JobExecutionException; +import org.springframework.scheduling.quartz.QuartzJobBean; +import org.springframework.stereotype.Component; + +@Component +public class MonitorJobBean extends QuartzJobBean { + + @Resource + MonitorUtils monitor; + + @Resource + NetUtils net; + + @Override + protected void executeInternal(JobExecutionContext context) throws JobExecutionException { + RuntimeDetail runtimeDetail = monitor.monitorRuntimeDetail(); + net.updateRuntimeDetails(runtimeDetail); + } +} diff --git a/itbaima-monitor-client/src/main/java/com/example/utils/MonitorUtils.java b/itbaima-monitor-client/src/main/java/com/example/utils/MonitorUtils.java index 28292ce..54aa74f 100644 --- a/itbaima-monitor-client/src/main/java/com/example/utils/MonitorUtils.java +++ b/itbaima-monitor-client/src/main/java/com/example/utils/MonitorUtils.java @@ -1,9 +1,12 @@ package com.example.utils; import com.example.entity.BaseDetail; +import com.example.entity.RuntimeDetail; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Component; import oshi.SystemInfo; +import oshi.hardware.CentralProcessor; +import oshi.hardware.HWDiskStore; import oshi.hardware.HardwareAbstractionLayer; import oshi.hardware.NetworkIF; import oshi.software.os.OperatingSystem; @@ -12,6 +15,7 @@ import java.io.File; import java.io.IOException; import java.net.NetworkInterface; import java.util.Arrays; +import java.util.Date; import java.util.Objects; import java.util.Properties; @@ -40,6 +44,62 @@ public class MonitorUtils { .setIp(ip); } + public RuntimeDetail monitorRuntimeDetail() { + double statisticTime = 0.5; + try { + HardwareAbstractionLayer hardware = info.getHardware(); + NetworkIF networkInterface = Objects.requireNonNull(this.findNetworkInterface(hardware)); + CentralProcessor processor = hardware.getProcessor(); + double upload = networkInterface.getBytesSent(), download = networkInterface.getBytesRecv(); + double read = hardware.getDiskStores().stream().mapToLong(HWDiskStore::getReadBytes).sum(); + double write = hardware.getDiskStores().stream().mapToLong(HWDiskStore::getWriteBytes).sum(); + long[] ticks = processor.getSystemCpuLoadTicks(); + Thread.sleep((long) (statisticTime * 1000)); + networkInterface = Objects.requireNonNull(this.findNetworkInterface(hardware)); + upload = (networkInterface.getBytesSent() - upload) / statisticTime; + download = (networkInterface.getBytesRecv() - download) / statisticTime; + read = (hardware.getDiskStores().stream().mapToLong(HWDiskStore::getReadBytes).sum() - read) / statisticTime; + write = (hardware.getDiskStores().stream().mapToLong(HWDiskStore::getWriteBytes).sum() - write) / statisticTime; + double memory = (hardware.getMemory().getTotal() - hardware.getMemory().getAvailable()) / 1024.0 / 1024 / 1024; + double disk = Arrays.stream(File.listRoots()) + .mapToLong(file -> file.getTotalSpace() - file.getFreeSpace()).sum() / 1024.0 / 1024 / 1024; + return new RuntimeDetail() + .setCpuUsage(this.calculateCpuUsage(processor, ticks)) + .setMemoryUsage(memory) + .setDiskUsage(disk) + .setNetworkUpload(upload / 1024) + .setNetworkDownload(download / 1024) + .setDiskRead(read / 1024/ 1024) + .setDiskWrite(write / 1024 / 1024) + .setTimestamp(new Date().getTime()); + } catch (Exception e) { + log.error("读取运行时数据出现问题", e); + } + return null; + } + + private double calculateCpuUsage(CentralProcessor processor, long[] prevTicks) { + long[] ticks = processor.getSystemCpuLoadTicks(); + long nice = ticks[CentralProcessor.TickType.NICE.getIndex()] + - prevTicks[CentralProcessor.TickType.NICE.getIndex()]; + long irq = ticks[CentralProcessor.TickType.IRQ.getIndex()] + - prevTicks[CentralProcessor.TickType.IRQ.getIndex()]; + long softIrq = ticks[CentralProcessor.TickType.SOFTIRQ.getIndex()] + - prevTicks[CentralProcessor.TickType.SOFTIRQ.getIndex()]; + long steal = ticks[CentralProcessor.TickType.STEAL.getIndex()] + - prevTicks[CentralProcessor.TickType.STEAL.getIndex()]; + long cSys = ticks[CentralProcessor.TickType.SYSTEM.getIndex()] + - prevTicks[CentralProcessor.TickType.SYSTEM.getIndex()]; + long cUser = ticks[CentralProcessor.TickType.USER.getIndex()] + - prevTicks[CentralProcessor.TickType.USER.getIndex()]; + long ioWait = ticks[CentralProcessor.TickType.IOWAIT.getIndex()] + - prevTicks[CentralProcessor.TickType.IOWAIT.getIndex()]; + long idle = ticks[CentralProcessor.TickType.IDLE.getIndex()] + - prevTicks[CentralProcessor.TickType.IDLE.getIndex()]; + long totalCpu = cUser + nice + cSys + idle + ioWait + irq + softIrq + steal; + return (cSys + cUser) * 1.0 / totalCpu; + } + private NetworkIF findNetworkInterface(HardwareAbstractionLayer hardware) { try { for (NetworkIF network : hardware.getNetworkIFs()) { diff --git a/itbaima-monitor-client/src/main/java/com/example/utils/NetUtils.java b/itbaima-monitor-client/src/main/java/com/example/utils/NetUtils.java index 36670c6..706a503 100644 --- a/itbaima-monitor-client/src/main/java/com/example/utils/NetUtils.java +++ b/itbaima-monitor-client/src/main/java/com/example/utils/NetUtils.java @@ -4,12 +4,12 @@ import com.alibaba.fastjson2.JSONObject; import com.example.entity.BaseDetail; import com.example.entity.ConnectionConfig; import com.example.entity.Response; +import com.example.entity.RuntimeDetail; import jakarta.annotation.Resource; import lombok.extern.slf4j.Slf4j; import org.springframework.context.annotation.Lazy; import org.springframework.stereotype.Component; -import java.io.IOException; import java.net.URI; import java.net.http.HttpClient; import java.net.http.HttpRequest; @@ -62,6 +62,13 @@ public class NetUtils { } } + public void updateRuntimeDetails(RuntimeDetail detail) { + Response response = this.doPost("/runtime", detail); + if(!response.success()) { + log.warn("更新运行时状态时,接收到服务端的异常响应内容: {}", response.message()); + } + } + private Response doPost(String url, Object data) { try { String rawData = JSONObject.from(data).toJSONString(); diff --git a/itbaima-monitor-server/src/main/java/com/example/controller/ClientController.java b/itbaima-monitor-server/src/main/java/com/example/controller/ClientController.java index 3590f32..2c133a0 100644 --- a/itbaima-monitor-server/src/main/java/com/example/controller/ClientController.java +++ b/itbaima-monitor-server/src/main/java/com/example/controller/ClientController.java @@ -3,6 +3,7 @@ package com.example.controller; import com.example.entity.RestBean; import com.example.entity.dto.Client; import com.example.entity.vo.request.ClientDetailVO; +import com.example.entity.vo.request.RuntimeDetailVO; import com.example.service.ClientService; import com.example.utils.Const; import jakarta.annotation.Resource; @@ -28,4 +29,11 @@ public class ClientController { service.updateClientDetail(vo, client); return RestBean.success(); } + + @PostMapping("/runtime") + public RestBean updateRuntimeDetails(@RequestAttribute(Const.ATTR_CLIENT) Client client, + @RequestBody @Valid RuntimeDetailVO vo) { + service.updateRuntimeDetail(vo, client); + return RestBean.success(); + } } diff --git a/itbaima-monitor-server/src/main/java/com/example/entity/vo/request/RuntimeDetailVO.java b/itbaima-monitor-server/src/main/java/com/example/entity/vo/request/RuntimeDetailVO.java new file mode 100644 index 0000000..f2c6491 --- /dev/null +++ b/itbaima-monitor-server/src/main/java/com/example/entity/vo/request/RuntimeDetailVO.java @@ -0,0 +1,25 @@ +package com.example.entity.vo.request; + + +import jakarta.validation.constraints.NotNull; +import lombok.Data; + +@Data +public class RuntimeDetailVO { + @NotNull + long timestamp; + @NotNull + double cpuUsage; + @NotNull + double memoryUsage; + @NotNull + double diskUsage; + @NotNull + double networkUpload; + @NotNull + double networkDownload; + @NotNull + double diskRead; + @NotNull + double diskWrite; +} diff --git a/itbaima-monitor-server/src/main/java/com/example/filter/RequestLogFilter.java b/itbaima-monitor-server/src/main/java/com/example/filter/RequestLogFilter.java index 4ab82b6..52525e5 100644 --- a/itbaima-monitor-server/src/main/java/com/example/filter/RequestLogFilter.java +++ b/itbaima-monitor-server/src/main/java/com/example/filter/RequestLogFilter.java @@ -29,7 +29,7 @@ public class RequestLogFilter extends OncePerRequestFilter { @Resource SnowflakeIdGenerator generator; - private final Set ignores = Set.of("/swagger-ui", "/v3/api-docs"); + private final Set ignores = Set.of("/swagger-ui", "/v3/api-docs", "/monitor/runtime"); @Override protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException { diff --git a/itbaima-monitor-server/src/main/java/com/example/service/ClientService.java b/itbaima-monitor-server/src/main/java/com/example/service/ClientService.java index 86664e3..817f468 100644 --- a/itbaima-monitor-server/src/main/java/com/example/service/ClientService.java +++ b/itbaima-monitor-server/src/main/java/com/example/service/ClientService.java @@ -3,6 +3,7 @@ package com.example.service; import com.baomidou.mybatisplus.extension.service.IService; import com.example.entity.dto.Client; import com.example.entity.vo.request.ClientDetailVO; +import com.example.entity.vo.request.RuntimeDetailVO; public interface ClientService extends IService { String registerToken(); @@ -10,4 +11,5 @@ public interface ClientService extends IService { Client findClientByToken(String token); boolean verifyAndRegister(String token); void updateClientDetail(ClientDetailVO vo, Client client); + void updateRuntimeDetail(RuntimeDetailVO vo, Client client); } diff --git a/itbaima-monitor-server/src/main/java/com/example/service/impl/ClientServiceImpl.java b/itbaima-monitor-server/src/main/java/com/example/service/impl/ClientServiceImpl.java index 1da9867..83cbff3 100644 --- a/itbaima-monitor-server/src/main/java/com/example/service/impl/ClientServiceImpl.java +++ b/itbaima-monitor-server/src/main/java/com/example/service/impl/ClientServiceImpl.java @@ -4,6 +4,7 @@ import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.example.entity.dto.Client; import com.example.entity.dto.ClientDetail; import com.example.entity.vo.request.ClientDetailVO; +import com.example.entity.vo.request.RuntimeDetailVO; import com.example.mapper.ClientDetailMapper; import com.example.mapper.ClientMapper; import com.example.service.ClientService; @@ -76,9 +77,16 @@ public class ClientServiceImpl extends ServiceImpl impleme } } + private Map currentRuntime = new ConcurrentHashMap<>(); + + @Override + public void updateRuntimeDetail(RuntimeDetailVO vo, Client client) { + currentRuntime.put(client.getId(), vo); + System.out.println(vo); + } + private void addClientCache(Client client) { clientIdCache.put(client.getId(), client); - clientTokenCache.put(client.getToken(), client); } private int randomClientId() {