debug(checkmk): log raw monitoring response, remove query param, try multiple container keys

This commit is contained in:
Brückner
2026-06-04 15:22:00 +02:00
parent 7731a1a9af
commit 15c4e3f6ac

View File

@ -741,50 +741,38 @@ async function startServer() {
} }
// Step 2: fetch live monitoring state for all hosts in one call. // Step 2: fetch live monitoring state for all hosts in one call.
// Uses query param to force the collection to return results (some CheckMK versions
// return an empty list without an explicit filter even with full permissions).
let hostnameToState: Map<string, number>; let hostnameToState: Map<string, number>;
try { try {
const monQuery = encodeURIComponent(JSON.stringify({ op: '!=', left: 'name', right: '' }));
const monRes = await fetch( const monRes = await fetch(
`${CHECKMK_API_URL}/domain-types/host/collections/all?query=${monQuery}`, `${CHECKMK_API_URL}/domain-types/host/collections/all`,
{ headers } { headers }
); );
if (!monRes.ok) throw new Error(checkmkHttpHint(monRes.status)); if (!monRes.ok) throw new Error(checkmkHttpHint(monRes.status));
const monData = await monRes.json(); const monData = await monRes.json();
// Log raw response so we can see the actual structure (first 500 chars).
db.prepare('INSERT INTO logs (id, timestamp, type, message) VALUES (?, ?, ?, ?)')
.run(uid('log'), now, 'system',
`CheckMK monitoring raw response: ${JSON.stringify(monData).substring(0, 500)}`);
hostnameToState = new Map<string, number>(); hostnameToState = new Map<string, number>();
for (const host of monData?.value ?? []) { // Try multiple possible container keys used by different CheckMK versions.
const name: string | undefined = host?.id; const candidates: any[] = Array.isArray(monData?.value)
? monData.value
: Array.isArray(monData?.members)
? monData.members.map((m: any) => m?.value ?? m)
: [];
for (const host of candidates) {
const name: string | undefined = host?.id ?? host?.extensions?.name;
const state: number | undefined = host?.extensions?.state; const state: number | undefined = host?.extensions?.state;
if (name !== undefined && state !== undefined) hostnameToState.set(name, state); if (name !== undefined && state !== undefined) hostnameToState.set(name, state);
} }
if (hostnameToState.size === 0 && ipToHostname.size > 0) { if (hostnameToState.size === 0 && ipToHostname.size > 0) {
// Monitoring collection empty despite config hosts existing.
// Likely cause: automation user lacks "Use monitoring" permission in CheckMK.
// Falling back: probe one host via /objects/host_config/{name} and log its raw extensions
// so we can identify which field carries the reachability state.
db.prepare('INSERT INTO logs (id, timestamp, type, message) VALUES (?, ?, ?, ?)') db.prepare('INSERT INTO logs (id, timestamp, type, message) VALUES (?, ?, ?, ?)')
.run(uid('log'), now, 'system', .run(uid('log'), now, 'system',
'CheckMK: monitoring collection returned 0 hosts — automation user has no monitoring view access. ' + `CheckMK: parsed 0 monitoring hosts from response (candidates array length: ${candidates.length}). ` +
'Fix in CheckMK: Setup → Users → edit automation user → Roles → assign "Administrator" or a role with ' + 'Check the raw response entry above to identify the correct JSON path.');
'"General Permissions → Use monitoring" and "See all hosts and services" enabled. ' +
'Alternatively: add the automation user to all relevant Contact Groups.');
const firstHostname = [...ipToHostname.values()][0];
try {
const probeRes = await fetch(
`${CHECKMK_API_URL}/objects/host_config/${encodeURIComponent(firstHostname)}`,
{ headers }
);
if (probeRes.ok) {
const probeData = await probeRes.json();
const extJson = JSON.stringify(probeData?.extensions ?? {}).substring(0, 400);
db.prepare('INSERT INTO logs (id, timestamp, type, message) VALUES (?, ?, ?, ?)')
.run(uid('log'), now, 'system',
`CheckMK probe extensions for "${firstHostname}": ${extJson}`);
}
} catch { /* probe is best-effort */ }
} }
} catch (err: any) { } catch (err: any) {
const msg = `CheckMK sync failed — could not fetch monitoring states: ${err?.message ?? err}`; const msg = `CheckMK sync failed — could not fetch monitoring states: ${err?.message ?? err}`;