|
|
|
@@ -4,6 +4,7 @@ import com.fasterxml.jackson.databind.JsonNode;
|
|
|
|
import com.fasterxml.jackson.databind.node.ArrayNode;
|
|
|
|
import com.fasterxml.jackson.databind.node.ArrayNode;
|
|
|
|
import com.imyeyu.api.modules.system.bean.DockerStatusStore;
|
|
|
|
import com.imyeyu.api.modules.system.bean.DockerStatusStore;
|
|
|
|
import com.imyeyu.api.modules.system.util.DockerEngineClient;
|
|
|
|
import com.imyeyu.api.modules.system.util.DockerEngineClient;
|
|
|
|
|
|
|
|
import com.imyeyu.java.TimiJava;
|
|
|
|
import com.imyeyu.utils.Time;
|
|
|
|
import com.imyeyu.utils.Time;
|
|
|
|
import jakarta.validation.constraints.NotNull;
|
|
|
|
import jakarta.validation.constraints.NotNull;
|
|
|
|
import lombok.RequiredArgsConstructor;
|
|
|
|
import lombok.RequiredArgsConstructor;
|
|
|
|
@@ -15,12 +16,13 @@ import org.springframework.scheduling.support.PeriodicTrigger;
|
|
|
|
import org.springframework.stereotype.Service;
|
|
|
|
import org.springframework.stereotype.Service;
|
|
|
|
|
|
|
|
|
|
|
|
import java.util.HashSet;
|
|
|
|
import java.util.HashSet;
|
|
|
|
|
|
|
|
import java.util.LinkedHashMap;
|
|
|
|
import java.util.Map;
|
|
|
|
import java.util.Map;
|
|
|
|
import java.util.Set;
|
|
|
|
import java.util.Set;
|
|
|
|
import java.util.concurrent.TimeUnit;
|
|
|
|
import java.util.concurrent.TimeUnit;
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
/**
|
|
|
|
* Docker 鐘舵€侀噰闆嗕换鍔?
|
|
|
|
* Docker 容器状态采集任务
|
|
|
|
*
|
|
|
|
*
|
|
|
|
* @author Codex
|
|
|
|
* @author Codex
|
|
|
|
* @since 2026-04-06
|
|
|
|
* @since 2026-04-06
|
|
|
|
@@ -56,19 +58,27 @@ public class DockerStatusTask implements SchedulingConfigurer {
|
|
|
|
try {
|
|
|
|
try {
|
|
|
|
ArrayNode containers = (ArrayNode) dockerEngineClient.getJson("/containers/json", DockerEngineClient.query("all", "true"));
|
|
|
|
ArrayNode containers = (ArrayNode) dockerEngineClient.getJson("/containers/json", DockerEngineClient.query("all", "true"));
|
|
|
|
long now = Time.now();
|
|
|
|
long now = Time.now();
|
|
|
|
synchronized (dockerStatusStore) {
|
|
|
|
Map<String, DockerStatusStore.Container> collectedContainers = new LinkedHashMap<>();
|
|
|
|
Set<String> activeIds = new HashSet<>();
|
|
|
|
for (JsonNode summary : containers) {
|
|
|
|
for (JsonNode summary : containers) {
|
|
|
|
try {
|
|
|
|
try {
|
|
|
|
String containerId = getAsString(summary, "Id");
|
|
|
|
String containerId = getAsString(summary, "Id");
|
|
|
|
DockerStatusStore.Container container = new DockerStatusStore.Container();
|
|
|
|
activeIds.add(containerId);
|
|
|
|
if (TimiJava.isEmpty(container)) {
|
|
|
|
DockerStatusStore.Container container = dockerStatusStore.getContainers().computeIfAbsent(containerId, key -> new DockerStatusStore.Container());
|
|
|
|
continue;
|
|
|
|
updateContainerSummary(container, summary);
|
|
|
|
|
|
|
|
updateContainerInspect(containerId, container);
|
|
|
|
|
|
|
|
updateContainerStats(containerId, container, now);
|
|
|
|
|
|
|
|
} catch (Exception e) {
|
|
|
|
|
|
|
|
log.error("collect docker container item error", e);
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
updateContainerSummary(container, summary);
|
|
|
|
|
|
|
|
updateContainerInspect(containerId, container);
|
|
|
|
|
|
|
|
updateContainerStats(containerId, container, now);
|
|
|
|
|
|
|
|
collectedContainers.put(container.getId(), container);
|
|
|
|
|
|
|
|
} catch (Exception e) {
|
|
|
|
|
|
|
|
log.error("collect docker container item error", e);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (dockerStatusStore) {
|
|
|
|
|
|
|
|
Set<String> activeIds = new HashSet<>(collectedContainers.keySet());
|
|
|
|
|
|
|
|
for (Map.Entry<String, DockerStatusStore.Container> item : collectedContainers.entrySet()) {
|
|
|
|
|
|
|
|
DockerStatusStore.Container container = dockerStatusStore.getContainers().computeIfAbsent(item.getKey(), key -> new DockerStatusStore.Container());
|
|
|
|
|
|
|
|
applyCollectedContainer(container, item.getValue());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
dockerStatusStore.getContainers().entrySet().removeIf(item -> !activeIds.contains(item.getKey()));
|
|
|
|
dockerStatusStore.getContainers().entrySet().removeIf(item -> !activeIds.contains(item.getKey()));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
@@ -77,6 +87,39 @@ public class DockerStatusTask implements SchedulingConfigurer {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private void applyCollectedContainer(DockerStatusStore.Container target, DockerStatusStore.Container source) {
|
|
|
|
|
|
|
|
target.setId(source.getId());
|
|
|
|
|
|
|
|
target.setName(source.getName());
|
|
|
|
|
|
|
|
target.setImage(source.getImage());
|
|
|
|
|
|
|
|
target.setImageId(source.getImageId());
|
|
|
|
|
|
|
|
target.setCreatedAt(source.getCreatedAt());
|
|
|
|
|
|
|
|
target.setState(source.getState());
|
|
|
|
|
|
|
|
target.setStatus(source.getStatus());
|
|
|
|
|
|
|
|
target.setHealthStatus(source.getHealthStatus());
|
|
|
|
|
|
|
|
target.setStartedAt(source.getStartedAt());
|
|
|
|
|
|
|
|
target.setFinishedAt(source.getFinishedAt());
|
|
|
|
|
|
|
|
target.setExitCode(source.getExitCode());
|
|
|
|
|
|
|
|
target.setRestartCount(source.getRestartCount());
|
|
|
|
|
|
|
|
target.setOomKilled(source.isOomKilled());
|
|
|
|
|
|
|
|
target.setCpuPercent(source.getCpuPercent());
|
|
|
|
|
|
|
|
target.setMemoryUsageBytes(source.getMemoryUsageBytes());
|
|
|
|
|
|
|
|
target.setMemoryLimitBytes(source.getMemoryLimitBytes());
|
|
|
|
|
|
|
|
target.setMemoryPercent(source.getMemoryPercent());
|
|
|
|
|
|
|
|
target.setNetworkRxBytes(source.getNetworkRxBytes());
|
|
|
|
|
|
|
|
target.setNetworkTxBytes(source.getNetworkTxBytes());
|
|
|
|
|
|
|
|
target.setBlockReadBytes(source.getBlockReadBytes());
|
|
|
|
|
|
|
|
target.setBlockWriteBytes(source.getBlockWriteBytes());
|
|
|
|
|
|
|
|
target.setPids(source.getPids());
|
|
|
|
|
|
|
|
target.setUpdatedAt(source.getUpdatedAt());
|
|
|
|
|
|
|
|
DockerStatusStore.Point point = source.getHistory().peekLast();
|
|
|
|
|
|
|
|
if (point != null) {
|
|
|
|
|
|
|
|
target.getHistory().addLast(point);
|
|
|
|
|
|
|
|
while (historyLimit < target.getHistory().size()) {
|
|
|
|
|
|
|
|
target.getHistory().pollFirst();
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private void updateContainerSummary(DockerStatusStore.Container container, JsonNode summary) {
|
|
|
|
private void updateContainerSummary(DockerStatusStore.Container container, JsonNode summary) {
|
|
|
|
container.setId(getAsString(summary, "Id"));
|
|
|
|
container.setId(getAsString(summary, "Id"));
|
|
|
|
container.setName(trimContainerName(readFirstArrayText(summary, "Names")));
|
|
|
|
container.setName(trimContainerName(readFirstArrayText(summary, "Names")));
|
|
|
|
@@ -108,8 +151,8 @@ public class DockerStatusTask implements SchedulingConfigurer {
|
|
|
|
if (memoryUsageBytes != null && memoryLimitBytes != null && 0 < memoryLimitBytes) {
|
|
|
|
if (memoryUsageBytes != null && memoryLimitBytes != null && 0 < memoryLimitBytes) {
|
|
|
|
memoryPercent = memoryUsageBytes * 100D / memoryLimitBytes;
|
|
|
|
memoryPercent = memoryUsageBytes * 100D / memoryLimitBytes;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
Long networkRxBytes = 0L;
|
|
|
|
long networkRxBytes = 0L;
|
|
|
|
Long networkTxBytes = 0L;
|
|
|
|
long networkTxBytes = 0L;
|
|
|
|
JsonNode networks = getAsObject(stats, "networks");
|
|
|
|
JsonNode networks = getAsObject(stats, "networks");
|
|
|
|
if (networks != null) {
|
|
|
|
if (networks != null) {
|
|
|
|
for (Map.Entry<String, JsonNode> item : (Iterable<Map.Entry<String, JsonNode>>) networks::fields) {
|
|
|
|
for (Map.Entry<String, JsonNode> item : (Iterable<Map.Entry<String, JsonNode>>) networks::fields) {
|
|
|
|
@@ -118,8 +161,8 @@ public class DockerStatusTask implements SchedulingConfigurer {
|
|
|
|
networkTxBytes += getAsLong(network, "tx_bytes", 0L);
|
|
|
|
networkTxBytes += getAsLong(network, "tx_bytes", 0L);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
Long blockReadBytes = 0L;
|
|
|
|
long blockReadBytes = 0L;
|
|
|
|
Long blockWriteBytes = 0L;
|
|
|
|
long blockWriteBytes = 0L;
|
|
|
|
JsonNode blkioStats = getAsObject(stats, "blkio_stats");
|
|
|
|
JsonNode blkioStats = getAsObject(stats, "blkio_stats");
|
|
|
|
ArrayNode ioServiceBytes = blkioStats == null ? null : getAsArray(blkioStats, "io_service_bytes_recursive");
|
|
|
|
ArrayNode ioServiceBytes = blkioStats == null ? null : getAsArray(blkioStats, "io_service_bytes_recursive");
|
|
|
|
if (ioServiceBytes != null) {
|
|
|
|
if (ioServiceBytes != null) {
|
|
|
|
@@ -134,7 +177,6 @@ public class DockerStatusTask implements SchedulingConfigurer {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
Integer pids = getNestedInteger(stats, "pids_stats", "current");
|
|
|
|
Integer pids = getNestedInteger(stats, "pids_stats", "current");
|
|
|
|
|
|
|
|
|
|
|
|
container.setCpuPercent(cpuPercent);
|
|
|
|
container.setCpuPercent(cpuPercent);
|
|
|
|
container.setMemoryUsageBytes(memoryUsageBytes);
|
|
|
|
container.setMemoryUsageBytes(memoryUsageBytes);
|
|
|
|
container.setMemoryLimitBytes(memoryLimitBytes);
|
|
|
|
container.setMemoryLimitBytes(memoryLimitBytes);
|
|
|
|
|