diff --git a/agent/src/main/java/io/wdd/agent/config/utils/AgentCommonThreadPool.java b/agent/src/main/java/io/wdd/agent/config/utils/AgentCommonThreadPool.java new file mode 100644 index 0000000..5754f3e --- /dev/null +++ b/agent/src/main/java/io/wdd/agent/config/utils/AgentCommonThreadPool.java @@ -0,0 +1,32 @@ +package io.wdd.agent.config.utils; + +import com.google.common.util.concurrent.ThreadFactoryBuilder; + +import java.util.concurrent.*; + +public class AgentCommonThreadPool { + + public static ExecutorService pool; + + + static { + + ThreadFactory threadFactory = new ThreadFactoryBuilder() + .setNameFormat("agent-pool-%d") + .setDaemon(false) + .build(); + + + // construct the thread pool + pool = new ThreadPoolExecutor( + 5, + 10, + 500, + TimeUnit.MILLISECONDS, + new ArrayBlockingQueue<>(8,true), + threadFactory, + new ThreadPoolExecutor.AbortPolicy() + ); + + } +} diff --git a/agent/src/main/java/io/wdd/agent/status/hardware/AgentStatusCollector.java b/agent/src/main/java/io/wdd/agent/status/hardware/AgentStatusCollector.java new file mode 100644 index 0000000..43f9117 --- /dev/null +++ b/agent/src/main/java/io/wdd/agent/status/hardware/AgentStatusCollector.java @@ -0,0 +1,85 @@ +package io.wdd.agent.status.hardware; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import io.wdd.agent.status.hardware.cpu.CpuInfo; +import io.wdd.agent.status.hardware.memory.MemoryInfo; +import io.wdd.agent.status.redisReporter.AgentStatus; +import lombok.extern.slf4j.Slf4j; +import org.springframework.data.redis.core.RedisTemplate; +import org.springframework.stereotype.Service; +import oshi.SystemInfo; +import oshi.hardware.HardwareAbstractionLayer; +import oshi.software.os.OperatingSystem; + +import javax.annotation.Resource; +import java.time.LocalDateTime; +import java.util.Collections; +import java.util.List; + +@Service +@Slf4j +public class AgentStatusCollector { + + @Resource + RedisTemplate redisTemplate; + + @Resource + ObjectMapper objectMapper; + + + private static final SystemInfo systemInfo; + /** + * 硬件信息 + */ + private static final HardwareAbstractionLayer hardware; + /** + * 系统信息 + */ + private static final OperatingSystem os; + + private static final List AgentStatusCache = Collections.singletonList(new AgentStatus()); + + static { + systemInfo = new SystemInfo(); + hardware = systemInfo.getHardware(); + os = systemInfo.getOperatingSystem(); + } + + + + public AgentStatus collect(){ + + AgentStatus agentStatus = AgentStatusCache.get(0); + + + /* CPU */ + // help gc + agentStatus.setCpuInfo(new CpuInfo(hardware.getProcessor(), 1000)); + + /* Memory */ + agentStatus.setMemoryInfo(new MemoryInfo().build(hardware.getMemory())); + + /* Storage */ + agentStatus.setDiskStoreInfo(hardware.getDiskStores()); + + return agentStatus; + + } + + + private void sendAgentStatusToRedis(){ + + try { + + + log.info("time is [{}] , and agent status are [{}]", LocalDateTime.now(), objectMapper.writerWithDefaultPrettyPrinter().writeValueAsString(collect())); + + } catch (JsonProcessingException e) { + throw new RuntimeException(e); + } + + } + + +} diff --git a/agent/src/main/java/io/wdd/agent/status/hardware/config/DataUnit.java b/agent/src/main/java/io/wdd/agent/status/hardware/config/DataUnit.java new file mode 100644 index 0000000..777e57d --- /dev/null +++ b/agent/src/main/java/io/wdd/agent/status/hardware/config/DataUnit.java @@ -0,0 +1,64 @@ +package io.wdd.agent.status.hardware.config; + +import org.springframework.util.unit.DataSize; + +/** + * 数据单位封装

+ * 此类来自于:Spring-framework + * + *

+ *     BYTES      1B      2^0     1
+ *     KILOBYTES  1KB     2^10    1,024
+ *     MEGABYTES  1MB     2^20    1,048,576
+ *     GIGABYTES  1GB     2^30    1,073,741,824
+ *     TERABYTES  1TB     2^40    1,099,511,627,776
+ * 
+ * + * @author Sam Brannen,Stephane Nicoll + * @since 5.3.10 + */ +public enum DataUnit { + + /** + * Bytes, 后缀表示为: {@code B}. + */ + BYTES("B", DataSize.ofBytes(1)), + + /** + * Kilobytes, 后缀表示为: {@code KB}. + */ + KILOBYTES("KB", DataSize.ofKilobytes(1)), + + /** + * Megabytes, 后缀表示为: {@code MB}. + */ + MEGABYTES("MB", DataSize.ofMegabytes(1)), + + /** + * Gigabytes, 后缀表示为: {@code GB}. + */ + GIGABYTES("GB", DataSize.ofGigabytes(1)), + + /** + * Terabytes, 后缀表示为: {@code TB}. + */ + TERABYTES("TB", DataSize.ofTerabytes(1)); + + public static final String[] UNIT_NAMES = new String[]{"B", "KB", "MB", "GB", "TB", "PB", "EB"}; + + private final String suffix; + + private final DataSize size; + + + DataUnit(String suffix, DataSize size) { + this.suffix = suffix; + this.size = size; + } + + DataSize size() { + return this.size; + } + + +} \ No newline at end of file diff --git a/agent/src/main/java/io/wdd/agent/status/hardware/config/FormatUtils.java b/agent/src/main/java/io/wdd/agent/status/hardware/config/FormatUtils.java new file mode 100644 index 0000000..5081041 --- /dev/null +++ b/agent/src/main/java/io/wdd/agent/status/hardware/config/FormatUtils.java @@ -0,0 +1,33 @@ +package io.wdd.agent.status.hardware.config; + +import java.text.DecimalFormat; + +public class FormatUtils { + + + /** + * 格式化输出百分比 + * + * @param rate + * @return + */ + public static String formatRate(double rate) { + return new DecimalFormat("#.##%").format(rate); + } + + /** + * 格式化输出大小 B/KB/MB... + * + * @param size + * @return + */ + public static String formatData(long size) { + if (size <= 0L) { + return "0B"; + } else { + int digitGroups = Math.min(DataUnit.UNIT_NAMES.length - 1, (int) (Math.log10((double) size) / Math.log10(1024.0D))); + return (new DecimalFormat("#,##0.##")).format((double) size / Math.pow(1024.0D, digitGroups)) + " " + DataUnit.UNIT_NAMES[digitGroups]; + } + } + +} diff --git a/agent/src/main/java/io/wdd/agent/status/hardware/cpu/CpuInfo.java b/agent/src/main/java/io/wdd/agent/status/hardware/cpu/CpuInfo.java new file mode 100644 index 0000000..ebe3925 --- /dev/null +++ b/agent/src/main/java/io/wdd/agent/status/hardware/cpu/CpuInfo.java @@ -0,0 +1,95 @@ +package io.wdd.agent.status.hardware.cpu; + +import oshi.hardware.CentralProcessor; + +import java.text.DecimalFormat; + +public class CpuInfo { + + + private static final DecimalFormat LOAD_FORMAT = new DecimalFormat("#.00"); + + /** + * CPU核心数 + */ + private Integer cpuNum; + + /** + * CPU总的使用率 + */ + private double toTal; + + /** + * CPU系统使用率 + */ + private double sys; + + /** + * CPU用户使用率 + */ + private double user; + + /** + * CPU当前等待率 + */ + private double wait; + + /** + * CPU当前空闲率 + */ + private double free; + + /** + * CPU型号信息 + */ + private String cpuModel; + + /** + * CPU型号信息 + */ + private CpuTicks ticks; + + public CpuInfo(CentralProcessor processor, long waitingTime){ + this.init(processor, waitingTime); + } + + + /** + * 获取指定等待时间内系统CPU 系统使用率、用户使用率、利用率等等 相关信息 + * + * @param processor {@link CentralProcessor} + * @param waitingTime 设置等待时间,单位毫秒 + * @since 5.7.12 + */ + private void init(CentralProcessor processor, long waitingTime) { + + final CpuTicks ticks = new CpuTicks(processor, waitingTime); + this.ticks = ticks; + + this.cpuNum = processor.getLogicalProcessorCount(); + this.cpuModel = processor.toString(); + + final long totalCpu = ticks.totalCpu(); + this.toTal = totalCpu; + this.sys = formatDouble(ticks.cSys, totalCpu); + this.user = formatDouble(ticks.user, totalCpu); + this.wait = formatDouble(ticks.ioWait, totalCpu); + this.free = formatDouble(ticks.idle, totalCpu); + } + + /** + * 获取每个CPU核心的tick,计算方式为 100 * tick / totalCpu + * + * @param tick tick + * @param totalCpu CPU总数 + * @return 平均每个CPU核心的tick + * @since 5.7.12 + */ + private static double formatDouble(long tick, long totalCpu) { + if (0 == totalCpu) { + return 0D; + } + return Double.parseDouble(LOAD_FORMAT.format(tick <= 0 ? 0 : (100d * tick / totalCpu))); + } + +} diff --git a/agent/src/main/java/io/wdd/agent/status/hardware/cpu/CpuTicks.java b/agent/src/main/java/io/wdd/agent/status/hardware/cpu/CpuTicks.java new file mode 100644 index 0000000..38029c9 --- /dev/null +++ b/agent/src/main/java/io/wdd/agent/status/hardware/cpu/CpuTicks.java @@ -0,0 +1,100 @@ +package io.wdd.agent.status.hardware.cpu; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.Getter; +import lombok.NoArgsConstructor; +import oshi.hardware.CentralProcessor; +import oshi.util.Util; + +@Data +@NoArgsConstructor +@AllArgsConstructor +public class CpuTicks { + + long idle; + + long nice; + + long irq; + + long softIrq; + + long steal; + + long cSys; + + long user; + + long ioWait; + + private static int IDLEIndex; + private static int NICEIndex; + private static int IRQIndex; + private static int SOFTIRQIndex; + private static int STEALIndex; + private static int SYSTEMIndex; + private static int USERIndex; + private static int IOWAITIndex; + + static { + + IDLEIndex = CentralProcessor.TickType.IDLE.getIndex(); + NICEIndex = CentralProcessor.TickType.NICE.getIndex(); + IRQIndex =CentralProcessor.TickType.IRQ.getIndex(); + SOFTIRQIndex = CentralProcessor.TickType.SOFTIRQ.getIndex(); + STEALIndex = CentralProcessor.TickType.STEAL.getIndex(); + SYSTEMIndex = CentralProcessor.TickType.SYSTEM.getIndex(); + USERIndex = CentralProcessor.TickType.USER.getIndex(); + IOWAITIndex = CentralProcessor.TickType.IOWAIT.getIndex(); + + } + + /** + * 构造,等待时间为用于计算在一定时长内的CPU负载情况,如传入1000表示最近1秒的负载情况 + * + * @param processor {@link CentralProcessor} + * @param waitingTime 设置等待时间,单位毫秒 + */ + public CpuTicks(CentralProcessor processor, long waitingTime) { + // CPU信息 + final long[] prevTicks = processor.getSystemCpuLoadTicks(); + + // 这里必须要设置延迟 + Util.sleep(waitingTime); + final long[] ticks = processor.getSystemCpuLoadTicks(); + + this.idle = tick(prevTicks, ticks, IDLEIndex); + this.nice = tick(prevTicks, ticks, NICEIndex); + this.irq = tick(prevTicks, ticks, IRQIndex); + this.softIrq = tick(prevTicks, ticks, SOFTIRQIndex); + this.steal = tick(prevTicks, ticks, STEALIndex); + this.cSys = tick(prevTicks, ticks, SYSTEMIndex); + this.user = tick(prevTicks, ticks, USERIndex); + this.ioWait = tick(prevTicks, ticks, IOWAITIndex); + } + + /** + * 获取CPU总的使用率 + * + * @return CPU总使用率 + */ + public long totalCpu() { + return Math.max(user + nice + cSys + idle + ioWait + irq + softIrq + steal, 0); + } + + /** + * 获取一段时间内的CPU负载标记差 + * + * @param prevTicks 开始的ticks + * @param ticks 结束的ticks + * @param tickType tick类型 + * @return 标记差 + * @since 5.7.12 + */ + private static long tick(long[] prevTicks, long[] ticks, int index) { + return ticks[index] - prevTicks[index]; + } + + +} diff --git a/agent/src/main/java/io/wdd/agent/status/hardware/memory/MemoryInfo.java b/agent/src/main/java/io/wdd/agent/status/hardware/memory/MemoryInfo.java new file mode 100644 index 0000000..f3fe425 --- /dev/null +++ b/agent/src/main/java/io/wdd/agent/status/hardware/memory/MemoryInfo.java @@ -0,0 +1,47 @@ +package io.wdd.agent.status.hardware.memory; + +import io.wdd.agent.status.hardware.config.FormatUtils; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; +import lombok.experimental.SuperBuilder; +import oshi.hardware.GlobalMemory; +import oshi.hardware.VirtualMemory; + + +@NoArgsConstructor +@AllArgsConstructor +@Data +@SuperBuilder(toBuilder = true) +public class MemoryInfo { + + + String total; + + String usage; + + String available; + + String memoryType; + + String swapTotal; + + String swapAvailable; + + String swapUsage; + + public MemoryInfo build(GlobalMemory memory) { + + VirtualMemory virtualMemory = memory.getVirtualMemory(); + return MemoryInfo.builder() + .memoryType(memory.getPhysicalMemory().get(0).getMemoryType()) + .total(FormatUtils.formatData(memory.getTotal())) + .available(FormatUtils.formatRate(memory.getAvailable())) + .usage(FormatUtils.formatData(memory.getTotal() - memory.getAvailable())) + .swapTotal(FormatUtils.formatData(virtualMemory.getSwapTotal())) + .swapUsage(FormatUtils.formatData(virtualMemory.getSwapUsed())) + .swapAvailable(FormatUtils.formatData(virtualMemory.getSwapTotal() - virtualMemory.getSwapUsed())) + .build(); + } + +} diff --git a/agent/src/main/java/io/wdd/agent/status/redisReporter/AgentStatus.java b/agent/src/main/java/io/wdd/agent/status/redisReporter/AgentStatus.java new file mode 100644 index 0000000..6e1edaf --- /dev/null +++ b/agent/src/main/java/io/wdd/agent/status/redisReporter/AgentStatus.java @@ -0,0 +1,29 @@ +package io.wdd.agent.status.redisReporter; + + +import io.wdd.agent.status.hardware.cpu.CpuInfo; +import io.wdd.agent.status.hardware.memory.MemoryInfo; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; +import lombok.experimental.SuperBuilder; +import oshi.hardware.HWDiskStore; + +import java.util.List; + +@Data +@AllArgsConstructor +@NoArgsConstructor +@SuperBuilder(toBuilder = true) +public class AgentStatus { + + CpuInfo cpuInfo; + + + MemoryInfo memoryInfo; + + + List diskStoreInfo; + + +} diff --git a/server/src/main/resources/mapper/DomainInfoMapper.xml b/server/src/main/resources/mapper/AgentStatusCollector.xml similarity index 100% rename from server/src/main/resources/mapper/DomainInfoMapper.xml rename to server/src/main/resources/mapper/AgentStatusCollector.xml diff --git a/source/src/main/java/io/wdd/source/shell/lib/wdd-lib-sys.sh b/source/src/main/java/io/wdd/source/shell/lib/wdd-lib-sys.sh index 7adab2d..027247e 100644 --- a/source/src/main/java/io/wdd/source/shell/lib/wdd-lib-sys.sh +++ b/source/src/main/java/io/wdd/source/shell/lib/wdd-lib-sys.sh @@ -135,7 +135,7 @@ FunctionEnd() { tmp () { -gcloud compute instances create octopus-agent-2c-4g-1 --project=compact-lacing-371804 --zone=asia-northeast1-b --machine-type=n2d-custom-2-4096 --network-interface=network-tier=PREMIUM,subnet=default --metadata=startup-script=wget\ https://raw.githubusercontent.com/zeaslity/ProjectOctopus/main/source/src/main/java/io/wdd/source/shell/agent-bootup.sh\ \&\&\ chmod\ \+x\ agent-bootup.sh\ \&\&\ /bin/bash\ agent-bootup.sh --can-ip-forward --maintenance-policy=MIGRATE --provisioning-model=STANDARD --service-account=172889627951-compute@developer.gserviceaccount.com --scopes=https://www.googleapis.com/auth/devstorage.read_only,https://www.googleapis.com/auth/logging.write,https://www.googleapis.com/auth/monitoring.write,https://www.googleapis.com/auth/servicecontrol,https://www.googleapis.com/auth/service.management.readonly,https://www.googleapis.com/auth/trace.append --create-disk=auto-delete=yes,boot=yes,device-name=octopus-agent-2c-4g,image=projects/ubuntu-os-cloud/global/images/ubuntu-2004-focal-v20221213,mode=rw,size=20,type=projects/compact-lacing-371804/zones/us-west4-b/diskTypes/pd-ssd --no-shielded-secure-boot --shielded-vtpm --shielded-integrity-monitoring --reservation-affinity=any +gcloud compute instances create octopus-agent-2c-4g-1 --project=compact-lacing-371804 --zone=asia-northeast1-b --machine-type=n2d-custom-2-4096 --network-interface=network-tier=PREMIUM,subnet=default --metadata=startup-script=wget\ https://raw.githubusercontent.com/zeaslity/ProjectOctopus/main/source/src/main/java/io/wdd/source/shell/agent-bootup.sh\ \&\&\ chmod\ \+x\ agent-bootup.sh\ \&\&\ /bin/bash\ agent-bootup.sh --can-ip-forward --maintenance-policy=MIGRATE --provisioning-model=STANDARD --service-account=172889627951-compute@developer.gserviceaccount.com --scopes=https://www.googleapis.com/auth/devstorage.read_only,https://www.googleapis.com/auth/logging.write,https://www.googleapis.com/auth/monitoring.write,https://www.googleapis.com/auth/servicecontrol,https://www.googleapis.com/auth/service.management.readonly,https://www.googleapis.com/auth/trace.append --create-disk=auto-delete=yes,boot=yes,device-name=octopus-agent-2c-4g,image=projects/ubuntu-os-cloud/global/images/ubuntu-2004-focal-v20221213,mode=rw,size=20,type=projects/compact-lacing-371804/zones/us-west4-b/diskTypes/pd1-ssd --no-shielded-secure-boot --shielded-vtpm --shielded-integrity-monitoring --reservation-affinity=any gcloud compute instances create tokyo-amd64-03 --project=compact-lacing-371804 --zone=asia-northeast1-b --machine-type=n2d-custom-2-4096 --network-interface=network-tier=PREMIUM,subnet=default --can-ip-forward --maintenance-policy=MIGRATE --provisioning-model=STANDARD --service-account=172889627951-compute@developer.gserviceaccount.com --scopes=https://www.googleapis.com/auth/devstorage.read_only,https://www.googleapis.com/auth/logging.write,https://www.googleapis.com/auth/monitoring.write,https://www.googleapis.com/auth/servicecontrol,https://www.googleapis.com/auth/service.management.readonly,https://www.googleapis.com/auth/trace.append --create-disk=auto-delete=yes,boot=yes,device-name=octopus-agent-2c-4g,image=projects/ubuntu-os-cloud/global/images/ubuntu-2004-focal-v20221213,mode=rw,size=20,type=projects/compact-lacing-371804/zones/us-west4-b/diskTypes/pd-ssd --no-shielded-secure-boot --shielded-vtpm --shielded-integrity-monitoring --reservation-affinity=any