mirror of
https://github.com/Termix-SSH/Termix.git
synced 2026-10-29 14:45:24 +00:00
106 lines
2.8 KiB
TypeScript
106 lines
2.8 KiB
TypeScript
import type { Client } from "ssh2";
|
|
import {
|
|
execCommand,
|
|
execPowerShell,
|
|
type HostPlatform,
|
|
} from "../../../../src/backend/hosts/metrics-shared/common-utils.js";
|
|
|
|
function formatUptime(uptimeSeconds: number): string {
|
|
const days = Math.floor(uptimeSeconds / 86400);
|
|
const hours = Math.floor((uptimeSeconds % 86400) / 3600);
|
|
const minutes = Math.floor((uptimeSeconds % 3600) / 60);
|
|
return `${days}d ${hours}h ${minutes}m`;
|
|
}
|
|
|
|
async function collectDarwinUptimeMetrics(client: Client): Promise<{
|
|
seconds: number | null;
|
|
formatted: string | null;
|
|
}> {
|
|
let uptimeSeconds: number | null = null;
|
|
let uptimeFormatted: string | null = null;
|
|
|
|
try {
|
|
const bootTimeOut = await execCommand(client, "sysctl -n kern.boottime");
|
|
// "{ sec = 1700000000, usec = 123456 } Thu Nov 16 ..."
|
|
const match = bootTimeOut.stdout.match(/sec\s*=\s*(\d+)/);
|
|
if (match) {
|
|
const bootSeconds = Number(match[1]);
|
|
if (Number.isFinite(bootSeconds)) {
|
|
uptimeSeconds = Math.max(0, Date.now() / 1000 - bootSeconds);
|
|
uptimeFormatted = formatUptime(uptimeSeconds);
|
|
}
|
|
}
|
|
} catch {
|
|
// expected
|
|
}
|
|
|
|
return {
|
|
seconds: uptimeSeconds,
|
|
formatted: uptimeFormatted,
|
|
};
|
|
}
|
|
|
|
async function collectWindowsUptimeMetrics(client: Client): Promise<{
|
|
seconds: number | null;
|
|
formatted: string | null;
|
|
}> {
|
|
let uptimeSeconds: number | null = null;
|
|
let uptimeFormatted: string | null = null;
|
|
|
|
try {
|
|
const { stdout } = await execPowerShell(
|
|
client,
|
|
"$os=Get-CimInstance Win32_OperatingSystem; [PSCustomObject]@{seconds=((Get-Date) - $os.LastBootUpTime).TotalSeconds} | ConvertTo-Json -Compress",
|
|
);
|
|
const parsed = JSON.parse(stdout.trim());
|
|
const seconds = Number(parsed?.seconds);
|
|
if (Number.isFinite(seconds)) {
|
|
uptimeSeconds = Math.max(0, seconds);
|
|
uptimeFormatted = formatUptime(uptimeSeconds);
|
|
}
|
|
} catch {
|
|
// expected
|
|
}
|
|
|
|
return {
|
|
seconds: uptimeSeconds,
|
|
formatted: uptimeFormatted,
|
|
};
|
|
}
|
|
|
|
export async function collectUptimeMetrics(
|
|
client: Client,
|
|
platform?: HostPlatform,
|
|
): Promise<{
|
|
seconds: number | null;
|
|
formatted: string | null;
|
|
}> {
|
|
if (platform === "darwin") {
|
|
return collectDarwinUptimeMetrics(client);
|
|
}
|
|
if (platform === "windows") {
|
|
return collectWindowsUptimeMetrics(client);
|
|
}
|
|
|
|
let uptimeSeconds: number | null = null;
|
|
let uptimeFormatted: string | null = null;
|
|
|
|
try {
|
|
const uptimeOut = await execCommand(client, "cat /proc/uptime");
|
|
const uptimeParts = uptimeOut.stdout.trim().split(/\s+/);
|
|
if (uptimeParts.length >= 1) {
|
|
uptimeSeconds = Number(uptimeParts[0]);
|
|
if (Number.isFinite(uptimeSeconds)) {
|
|
uptimeFormatted = formatUptime(uptimeSeconds);
|
|
}
|
|
}
|
|
} catch {
|
|
// expected
|
|
}
|
|
|
|
return {
|
|
seconds: uptimeSeconds,
|
|
formatted: uptimeFormatted,
|
|
};
|
|
}
|