Luigit
repositories / dotfiles

dotfiles

bugabingas dorkfiles

owned by admin

quickshell/nuguland/system-problems.js

Raw
// Pure journal query construction and parsing for system problem history.
// No I/O. Dual-mode: QML import and CommonJS require.

var COREDUMP_MESSAGE_ID = "fc2e22bc6ee647b6b90729ab34a250b1";
var WARNING_ICON = "";
var MAX_ISSUES = 100;
var MAX_DETAIL = 320;

function journalCommand() {
    return [
        "journalctl",
        "--boot=0",
        "--since=-24h",
        "--lines=100",
        "--output=json",
        "--no-pager",
        "--truncate-newline",
        "--output-fields=MESSAGE,MESSAGE_ID,_TRANSPORT,_COMM,_EXE,_PID,_UID,_SYSTEMD_UNIT,_SYSTEMD_USER_UNIT,COREDUMP_PID,COREDUMP_UID,COREDUMP_COMM,COREDUMP_EXE,COREDUMP_SIGNAL,COREDUMP_SIGNAL_NAME,COREDUMP_UNIT,COREDUMP_USER_UNIT",
        "--grep=^(?:[^\\r\\n]*dumped core\\.?|(?:Out of memory|Memory cgroup out of memory): Killed process [1-9][0-9]* \\([^()\\r\\n]+\\)(?: |$)|Killed /[^\\r\\n]*)",
        "MESSAGE_ID=" + COREDUMP_MESSAGE_ID,
        "+",
        "_TRANSPORT=kernel",
        "+",
        "_COMM=systemd-oomd",
        "_SYSTEMD_UNIT=systemd-oomd.service"
    ];
}

function stringField(entry, name) {
    return typeof entry[name] === "string" ? entry[name] : "";
}

function clean(value, limit) {
    var text = String(value == null ? "" : value)
        .replace(/[\x00-\x1f\x7f-\x9f]+/g, " ")
        .replace(/\s+/g, " ")
        .replace(/^\s+|\s+$/g, "");
    return text.length > limit ? text.slice(0, limit) : text;
}

function numericMetadata(value) {
    var text = clean(value, 20);
    return /^[0-9]{1,20}$/.test(text) ? text : "";
}

function signalMetadata(name, number) {
    if (/^SIG[A-Z0-9]{1,21}$/.test(name)) return name;
    return numericMetadata(number);
}

function commonMetadata(entry) {
    var cursor = stringField(entry, "__CURSOR");
    var bootId = stringField(entry, "_BOOT_ID");
    var micros = stringField(entry, "__REALTIME_TIMESTAMP");
    if (!/^[\x21-\x7e]{1,512}$/.test(cursor) || !/^[0-9a-fA-F]{32}$/.test(bootId) || !/^[0-9]{1,20}$/.test(micros)) {
        return null;
    }

    var millis = Math.floor(Number(micros) / 1000);
    var date = new Date(millis);
    if (!isFinite(millis) || isNaN(date.getTime())) return null;

    var timestamp;
    try {
        timestamp = date.toISOString();
    } catch (error) {
        return null;
    }
    return { cursor: cursor, bootId: bootId.toLowerCase(), timestamp: timestamp };
}

function classify(entry) {
    // Journal-owned unit attribution cannot be supplied by a client, unlike
    // MESSAGE_ID or a process name chosen to resemble a system daemon.
    if (stringField(entry, "MESSAGE_ID") === COREDUMP_MESSAGE_ID &&
        /^systemd-coredump@[^/\r\n]{1,160}\.service$/.test(stringField(entry, "_SYSTEMD_UNIT"))) {
        return { source: "crash", match: null };
    }

    var message = stringField(entry, "MESSAGE");
    if (stringField(entry, "_TRANSPORT") === "kernel") {
        var kernel = message.match(/^(?:Out of memory|Memory cgroup out of memory): Killed process ([1-9][0-9]*) \(([^()\r\n]{1,128})\)(?:\s|$)/);
        if (kernel) return { source: "kernel-oom", match: kernel };
    }

    if (stringField(entry, "_COMM") === "systemd-oomd" && stringField(entry, "_SYSTEMD_UNIT") === "systemd-oomd.service") {
        var oomd = message.match(/^Killed (\/[\s\S]{1,512}?)(?: due to[\s\S]*)?\.?$/);
        if (oomd) return { source: "oomd", match: oomd };
    }
    return null;
}

function eventMetadata(entry, classification) {
    var metadata;
    if (classification.source === "crash") {
        metadata = {
            executable: clean(stringField(entry, "COREDUMP_EXE"), 240),
            comm: clean(stringField(entry, "COREDUMP_COMM"), 160),
            pid: numericMetadata(stringField(entry, "COREDUMP_PID")),
            signal: signalMetadata(stringField(entry, "COREDUMP_SIGNAL_NAME"), stringField(entry, "COREDUMP_SIGNAL")),
            unit: clean(stringField(entry, "COREDUMP_UNIT"), 160),
            userUnit: clean(stringField(entry, "COREDUMP_USER_UNIT"), 160),
            uid: numericMetadata(stringField(entry, "COREDUMP_UID"))
        };
    } else if (classification.source === "kernel-oom") {
        metadata = {
            executable: "",
            comm: clean(classification.match[2], 128),
            pid: numericMetadata(classification.match[1]),
            signal: "SIGKILL",
            unit: "",
            userUnit: "",
            uid: ""
        };
    } else {
        metadata = {
            executable: "",
            comm: "",
            pid: "",
            signal: "SIGKILL",
            unit: "",
            userUnit: "",
            uid: "",
            target: clean(classification.match[1] || classification.match[2], 200)
        };
    }
    return metadata;
}

// Only complete, lossless identity may join occurrences. Display cleanup or
// truncation must never make two different applications look like one.
function crashGroupId(entry) {
    var executable = stringField(entry, "COREDUMP_EXE");
    var uid = stringField(entry, "COREDUMP_UID");
    if (executable[0] !== "/" || executable !== clean(executable, 240) || !uid || uid !== numericMetadata(uid)) return "";
    return "crashes:" + JSON.stringify([uid, executable]);
}

// Derived presentation only: retain the journal records as the source of truth.
function groupIncidents(issues) {
    var groups = {};
    var result = [];
    issues.slice().sort(function (a, b) { return Date.parse(b.context.timestamp) - Date.parse(a.context.timestamp); }).forEach(function (issue) {
        var key = issue.context.source === "crash" ? issue.groupId : "";
        if (!key) {
            result.push(issue);
            return;
        }
        if (!Object.prototype.hasOwnProperty.call(groups, key)) {
            var group = Object.assign({}, issue, { id: key, events: [] });
            groups[key] = group;
            result.push(group);
        }
        groups[key].events.push(issue.context);
    });
    return result;
}

function issueLabel(source) {
    if (source === "crash") return "process crashed";
    if (source === "kernel-oom") return "process killed by kernel oom";
    return "process killed by systemd-oomd";
}

function issueDetail(timestamp, metadata) {
    var parts = [timestamp];
    var process = metadata.comm || metadata.executable || metadata.target;
    if (process) parts.push(process);
    if (metadata.pid) parts.push("pid " + metadata.pid);
    if (metadata.signal) parts.push(metadata.signal);
    if (metadata.userUnit || metadata.unit) parts.push(metadata.userUnit || metadata.unit);
    if (metadata.uid) parts.push("uid " + metadata.uid);
    return clean(parts.join(" · "), MAX_DETAIL);
}

function parseJournal(text) {
    var sourceText = String(text == null ? "" : text);
    if (!sourceText.trim()) return { ok: true, issues: [] };

    var lines = sourceText.split(/\r?\n/);
    var issues = [];
    var seen = {};
    var ok = true;

    for (var i = 0; i < lines.length; i++) {
        if (!lines[i].trim()) continue;
        var entry;
        try {
            entry = JSON.parse(lines[i]);
        } catch (error) {
            ok = false;
            continue;
        }
        if (!entry || typeof entry !== "object" || Object.prototype.toString.call(entry) === "[object Array]") {
            ok = false;
            continue;
        }

        var classification = classify(entry);
        if (!classification) continue;
        var common = commonMetadata(entry);
        if (!common) {
            ok = false;
            continue;
        }
        var seenKey = "$" + common.cursor;
        if (Object.prototype.hasOwnProperty.call(seen, seenKey)) continue;
        seen[seenKey] = true;

        if (issues.length < MAX_ISSUES) {
            var metadata = eventMetadata(entry, classification);
            issues.push({
                id: "journal:" + common.cursor,
                groupId: classification.source === "crash" ? crashGroupId(entry) : "",
                severity: "warning",
                icon: WARNING_ICON,
                label: issueLabel(classification.source),
                detail: issueDetail(common.timestamp, metadata),
                action: { kind: "journal-event", bootId: common.bootId, timestamp: common.timestamp, cursor: common.cursor },
                context: {
                    source: classification.source,
                    bootId: common.bootId,
                    timestamp: common.timestamp,
                    cursor: common.cursor,
                    metadata: metadata
                }
            });
        }
    }

    issues.sort(function (a, b) { return Date.parse(b.context.timestamp) - Date.parse(a.context.timestamp); });
    return { ok: ok, issues: issues };
}

if (typeof module !== "undefined" && module.exports) {
    module.exports = { journalCommand: journalCommand, parseJournal: parseJournal, groupIncidents: groupIncidents };
}