feat(telemetry): add canonical VPS host monitoring
This commit is contained in:
@@ -204,7 +204,10 @@ export function createLocalPreviewDeviceCore({ fixture = null } = {}) {
|
||||
},
|
||||
assets: projectValues(assets, projectRef),
|
||||
assetBindings: projectValues(assetBindings, projectRef),
|
||||
hosts: projectHosts.map((host) => withHealth("host", host, host.hostRef)),
|
||||
hosts: projectHosts.map((host) => ({
|
||||
...withHealth("host", host, host.hostRef),
|
||||
telemetry: host.telemetry ?? emptyPreviewHostTelemetry(),
|
||||
})),
|
||||
endpoints: projectValues(endpoints, projectRef),
|
||||
deployments: projectValues(deployments, projectRef),
|
||||
serviceInstances: projectServices.map((service) =>
|
||||
@@ -245,6 +248,10 @@ export function createLocalPreviewDeviceCore({ fixture = null } = {}) {
|
||||
routes,
|
||||
sessions,
|
||||
configurationStates,
|
||||
hosts,
|
||||
deployments,
|
||||
serviceInstances,
|
||||
healthObservations,
|
||||
});
|
||||
else if (fixture != null && fixture !== "") {
|
||||
throw serviceError("device_manager_preview_fixture_invalid", 400);
|
||||
@@ -890,6 +897,88 @@ function previewOntology(entityId) {
|
||||
return { entityId, catalogHash: "229c61c02a790906" };
|
||||
}
|
||||
|
||||
function emptyPreviewHostTelemetry() {
|
||||
return {
|
||||
state: "unobserved",
|
||||
freshness: "missing",
|
||||
observedAt: null,
|
||||
receivedAt: null,
|
||||
expiresAt: null,
|
||||
current: null,
|
||||
history: [],
|
||||
observation: null,
|
||||
};
|
||||
}
|
||||
|
||||
function previewHostTelemetry(hostRef, serviceInstanceRef, edgeRef) {
|
||||
const now = Date.now();
|
||||
const history = Array.from({ length: 60 }, (_, index) => {
|
||||
const observedAt = new Date(now - (59 - index) * 2_000).toISOString();
|
||||
const phase = index / 7;
|
||||
return {
|
||||
observedAt,
|
||||
cpuUsagePercent: 18 + Math.sin(phase) * 8 + (index % 5),
|
||||
memoryUsedPercent: 42 + Math.sin(phase / 2) * 3,
|
||||
network: [{
|
||||
interface: "eth0",
|
||||
bytesReceived: 8_000_000 + index * (32_000 + (index % 4) * 4_000),
|
||||
bytesSent: 3_000_000 + index * (14_000 + (index % 3) * 2_000),
|
||||
}],
|
||||
};
|
||||
});
|
||||
const observedAt = history.at(-1).observedAt;
|
||||
const current = {
|
||||
schemaVersion: "nodedc.infrastructure.host-telemetry.v1",
|
||||
profile: "linux-host-telegraf-v1",
|
||||
hostKey: "robot2b-b2-edge-vps",
|
||||
observedAt,
|
||||
source: {
|
||||
agent: "telegraf",
|
||||
agentVersion: "1.38.4",
|
||||
collectorRef: "service:nodedc-host-telemetry-agent",
|
||||
},
|
||||
hardware: {
|
||||
hostname: "koffyvngij",
|
||||
architecture: "x64",
|
||||
platform: "linux",
|
||||
kernelRelease: "6.8.0-79-generic",
|
||||
cpuModel: "AMD EPYC Processor (KVM)",
|
||||
logicalProcessors: 1,
|
||||
},
|
||||
cpu: { usagePercent: history.at(-1).cpuUsagePercent, load1: 0.31, load5: 0.24, load15: 0.18 },
|
||||
memory: { totalBytes: 1_007_681_536, availableBytes: 570_425_344, freeBytes: null, usedBytes: 437_256_192, usedPercent: history.at(-1).memoryUsedPercent },
|
||||
swap: { totalBytes: 0, availableBytes: null, freeBytes: 0, usedBytes: 0, usedPercent: 0 },
|
||||
system: { uptimeSeconds: 723_419, users: 1, processes: { total: 118, running: 2, sleeping: 115, blocked: 0, zombies: 1 } },
|
||||
disks: [{ device: "/dev/vda1", mount: "/", filesystem: "ext4", totalBytes: 21_474_836_480, freeBytes: 14_495_514_624, usedBytes: 6_979_321_856, usedPercent: 32.5 }],
|
||||
network: [{ interface: "eth0", bytesReceived: history.at(-1).network[0].bytesReceived, bytesSent: history.at(-1).network[0].bytesSent, packetsReceived: 91_482, packetsSent: 64_501, errorsReceived: 0, errorsSent: 0, droppedReceived: 0, droppedSent: 0 }],
|
||||
services: [
|
||||
{ name: "nodedc-device-edge-channel.service", loadState: "loaded", activeState: "active", subState: "running", memoryBytes: 71_303_168, restarts: 0, pid: 1482 },
|
||||
{ name: "nodedc-host-telemetry-agent.service", loadState: "loaded", activeState: "active", subState: "running", memoryBytes: 35_651_584, restarts: 0, pid: 1510 },
|
||||
{ name: "ssh.service", loadState: "loaded", activeState: "active", subState: "running", memoryBytes: 8_388_608, restarts: 0, pid: 712 },
|
||||
],
|
||||
};
|
||||
return {
|
||||
state: "online",
|
||||
freshness: "fresh",
|
||||
observedAt,
|
||||
receivedAt: new Date(now).toISOString(),
|
||||
expiresAt: new Date(now + 15_000).toISOString(),
|
||||
current,
|
||||
history,
|
||||
observation: {
|
||||
observationRef: "observation:preview-host-telemetry",
|
||||
entityId: "observation.observation",
|
||||
catalogHash: "229c61c02a790906",
|
||||
targetRef: hostRef,
|
||||
serviceInstanceRef,
|
||||
edgeRef,
|
||||
profileRef: "linux-host-telegraf-v1",
|
||||
source: { ...current.source, provenanceRef: `${edgeRef}:${current.source.collectorRef}` },
|
||||
observedProperties: ["host.cpu.utilization", "host.memory.utilization", "host.disk.utilization", "host.network.counters", "host.systemd.unit-state"],
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
function requirePlatformOwner(actor) {
|
||||
if (actor?.hubRole !== "owner") {
|
||||
throw serviceError("device_platform_catalog_access_denied", 403);
|
||||
@@ -905,6 +994,10 @@ function seedArusnaviB2Preview({
|
||||
routes,
|
||||
sessions,
|
||||
configurationStates,
|
||||
hosts,
|
||||
deployments,
|
||||
serviceInstances,
|
||||
healthObservations,
|
||||
}) {
|
||||
const timestamp = new Date().toISOString();
|
||||
const ownerScopeRef = "owner-scope:78da71d5-f48f-4de0-8e47-729f6d644151";
|
||||
@@ -913,6 +1006,9 @@ function seedArusnaviB2Preview({
|
||||
const edgeRef = "edge:73da0c42-a641-4559-b8f7-23509b60bfe9";
|
||||
const routeRef = "route:fef9b7a0-a462-4d68-9991-af026203368b";
|
||||
const sessionRef = "session:57ead610-47de-45f7-a42d-fbe4fa0aba38";
|
||||
const hostRef = "host:adf2a5b6-3c0b-4a39-998c-07dfb7818ad1";
|
||||
const deploymentRef = "deployment:49b296f8-4cc8-470f-9dc1-2e3a543fd224";
|
||||
const serviceInstanceRef = "service-instance:01f14736-f5c2-4867-9cbc-2d268996a871";
|
||||
const scope = {
|
||||
ownerScopeRef,
|
||||
scopeKind: "personal",
|
||||
@@ -963,6 +1059,52 @@ function seedArusnaviB2Preview({
|
||||
createdAt: timestamp,
|
||||
updatedAt: timestamp,
|
||||
});
|
||||
hosts.set(hostRef, {
|
||||
hostRef,
|
||||
projectRef,
|
||||
hostKey: "robot2b-b2-edge-vps",
|
||||
displayName: "Robot2B B2 Edge VPS",
|
||||
providerRef: "provider:beget",
|
||||
externalRef: "host:koffyvngij",
|
||||
managementCredentialConfigured: true,
|
||||
lifecycleState: "active",
|
||||
telemetry: previewHostTelemetry(hostRef, serviceInstanceRef, edgeRef),
|
||||
ontology: previewOntology("infrastructure.host"),
|
||||
});
|
||||
deployments.set(deploymentRef, {
|
||||
deploymentRef,
|
||||
projectRef,
|
||||
hostRef,
|
||||
deploymentKey: "device-edge-vps-command-transport",
|
||||
displayName: "Device Edge VPS runtime",
|
||||
artifactRef: "device-edge-vps-command-transport-20260812-013",
|
||||
artifactDigest: "sha256:c7486ec879681ddd706f229b628c8556ca8c9ccc4f152a85debb409c302759ef",
|
||||
lifecycleState: "active",
|
||||
ontology: previewOntology("infrastructure.deployment"),
|
||||
});
|
||||
serviceInstances.set(serviceInstanceRef, {
|
||||
serviceInstanceRef,
|
||||
projectRef,
|
||||
hostRef,
|
||||
deploymentRef,
|
||||
edgeRef,
|
||||
serviceKey: "device-edge",
|
||||
displayName: "Robot2B B2 Device Edge",
|
||||
serviceRole: "device.edge",
|
||||
lifecycleState: "active",
|
||||
ontology: previewOntology("infrastructure.service_instance"),
|
||||
});
|
||||
const healthObservationRef = "health-observation:b912a45a-2b97-4562-8f9e-824cc24e0710";
|
||||
healthObservations.set(healthObservationRef, {
|
||||
healthObservationRef,
|
||||
projectRef,
|
||||
subjectKind: "host",
|
||||
subjectRef: hostRef,
|
||||
observedState: "reachable",
|
||||
evidenceClass: "agent.telemetry",
|
||||
observedAt: timestamp,
|
||||
expiresAt: new Date(Date.now() + 60_000).toISOString(),
|
||||
});
|
||||
routes.set(routeRef, {
|
||||
routeRef,
|
||||
projectRef,
|
||||
|
||||
Reference in New Issue
Block a user