fix: correct Unraid CPU calculation, OIDC single-group sync, and Uptime-Kuma paused status
- **Unraid CPU calculation** (#6082): Use thread count instead of core count when normalizing CPU utilization. Each cpus[] entry is one thread, so dividing by physical cores (cores) over-reports on SMT systems. - **OIDC single-group sync** (#5716): Normalize the groups claim to always be an array. Some providers (e.g. Jumpcloud) send a single group as a plain string instead of an array, which caused the Array.isArray check to skip group synchronization entirely. - **Uptime-Kuma paused status** (#6002): Add the status field to the monitor schema and check it before falling back to heartbeat inference. When a monitor is paused, heartbeats stop arriving, so the latest heartbeat may still show 'up' from before pausing. The status page returns status=2 for paused monitors, which this change now respects.
This commit is contained in:
6 files changed
+277
-9
No files matched your search
@@ -37,9 +37,10 @@ export class UnraidIntegration extends Integration implements ISystemHealthMonit
|
||||
const systemInfo = await this.getSystemInformationAsync();
|
||||
|
||||
const cpuUtilization = systemInfo.metrics.cpu.cpus.reduce((acc, val) => acc + val.percentTotal, 0);
|
||||
const cpuCount = systemInfo.info.cpu.cores;
|
||||
const cpuCount = systemInfo.info.cpu.threads;
|
||||
|
||||
// We use "info" object instead of the stats since this is the exact amount the kernel sees, which is what Unraid displays.
|
||||
// We use the thread count (not physical cores) because each logical CPU entry in cpus[]
|
||||
// represents a thread. Dividing by cores would over-report utilization on SMT systems.
|
||||
const totalMemory = systemInfo.info.memory.layout.reduce((acc, layout) => layout.size + acc, 0);
|
||||
const usedMemory = totalMemory * (systemInfo.metrics.memory.percentTotal / 100);
|
||||
const uptime = dayjs(systemInfo.info.os.uptime);
|
||||
@@ -139,7 +140,7 @@ export class UnraidIntegration extends Integration implements ISystemHealthMonit
|
||||
},
|
||||
memory {
|
||||
layout {
|
||||
size
|
||||
size
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -62,9 +62,24 @@ export class UptimeKumaIntegration extends Integration {
|
||||
}
|
||||
|
||||
private mapMonitor(
|
||||
monitor: { id: number; name: string },
|
||||
monitor: { id: number; name: string; status?: number },
|
||||
heartbeat: { heartbeatList: Record<string, { status: number }[]>; uptimeList: Record<string, number> },
|
||||
): UptimeKumaMonitor {
|
||||
// If the status page reports a monitor status directly, prefer it over heartbeat inference.
|
||||
// Uptime-Kuma status page returns status=2 for paused monitors, and once paused,
|
||||
// heartbeats stop arriving so the latest heartbeat may still show "up" from before pausing.
|
||||
if (monitor.status !== undefined) {
|
||||
const statusFromPage = uptimeKumaHeartbeatCategoryMap[monitor.status];
|
||||
if (statusFromPage === "paused") {
|
||||
return {
|
||||
id: monitor.id,
|
||||
name: monitor.name,
|
||||
status: "paused",
|
||||
uptimePercent24h: null,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
const heartbeats = heartbeat.heartbeatList[String(monitor.id)] ?? [];
|
||||
const latestHeartbeat = heartbeats.at(-1);
|
||||
const uptimeKey = `${monitor.id}_24`;
|
||||
|
||||
@@ -19,6 +19,7 @@ export const uptimeKumaHeartbeatCategoryMap: Record<number, UptimeKumaMonitorCat
|
||||
export const uptimeKumaStatusPageMonitorSchema = z.object({
|
||||
id: z.number().int(),
|
||||
name: z.string(),
|
||||
status: z.number().int().optional(),
|
||||
});
|
||||
|
||||
export const uptimeKumaStatusPageGroupSchema = z.object({
|
||||
|
||||
Reference in new issue
Block a user