Files
Auto-Mirror-Switcher/background-diagnostics.js

123 lines
4.0 KiB
JavaScript

(function (root) {
'use strict';
var DEBUG_LOG_KEY = 'debugLogs';
var DEBUG_LOG_LIMIT = 1200;
var debugLogsCache = [];
var earlyDebugLogs = [];
var debugLogsLoaded = false;
var debugSaveTimer = null;
function trimText(value, limit) {
value = String(value == null ? '' : value);
limit = Math.max(20, Number(limit || 500));
return value.length > limit ? value.slice(0, limit) + '…' : value;
}
function makePlainLogValue(value, depth) {
depth = Number(depth || 0);
if (value == null) return value;
if (typeof value === 'string') return trimText(value, 900);
if (typeof value === 'number' || typeof value === 'boolean') return value;
if (value instanceof Error) return { name: value.name, message: value.message, stack: trimText(value.stack, 1200) };
if (value instanceof URL) return value.href;
if (depth > 3) return '[max-depth]';
if (Array.isArray(value)) {
return value.slice(0, 40).map(function (item) {
return makePlainLogValue(item, depth + 1);
});
}
if (typeof value === 'object') {
var result = {};
Object.keys(value).slice(0, 60).forEach(function (key) {
result[key] = makePlainLogValue(value[key], depth + 1);
});
return result;
}
return trimText(String(value), 300);
}
function trimDebugLogs(logs) {
logs = Array.isArray(logs) ? logs : [];
return logs.length > DEBUG_LOG_LIMIT ? logs.slice(logs.length - DEBUG_LOG_LIMIT) : logs;
}
function scheduleDebugSave() {
if (!debugLogsLoaded || debugSaveTimer) return;
debugSaveTimer = root.setTimeout(function () {
debugSaveTimer = null;
try {
var payload = {};
payload[DEBUG_LOG_KEY] = trimDebugLogs(debugLogsCache);
chrome.storage.local.set(payload);
} catch (e) {
// Diagnostics must never break redirect logic.
}
}, 80);
}
function initializeDebugLogs() {
var defaults = {};
defaults[DEBUG_LOG_KEY] = [];
try {
chrome.storage.local.get(defaults, function (items) {
var stored = Array.isArray(items[DEBUG_LOG_KEY]) ? items[DEBUG_LOG_KEY] : [];
debugLogsCache = trimDebugLogs(stored.concat(earlyDebugLogs));
earlyDebugLogs = [];
debugLogsLoaded = true;
scheduleDebugSave();
});
} catch (e) {
debugLogsLoaded = true;
}
}
function appendDebugLog(level, event, data) {
try {
var entry = {
time: new Date().toISOString(),
level: level || 'info',
event: String(event || 'log'),
data: makePlainLogValue(data || {})
};
if (!debugLogsLoaded) {
earlyDebugLogs.push(entry);
earlyDebugLogs = trimDebugLogs(earlyDebugLogs);
return;
}
debugLogsCache.push(entry);
debugLogsCache = trimDebugLogs(debugLogsCache);
scheduleDebugSave();
} catch (e) {
// Logging must never break redirect logic.
}
}
function log() {
var args = Array.prototype.slice.call(arguments);
console.log.apply(console, ['[Auto Mirror Switcher]'].concat(args));
appendDebugLog('info', args[0] || 'log', { args: args.slice(1) });
}
function warn() {
var args = Array.prototype.slice.call(arguments);
console.warn.apply(console, ['[Auto Mirror Switcher]'].concat(args));
appendDebugLog('warn', args[0] || 'warn', { args: args.slice(1) });
}
root.AutoMirrorDiagnostics = {
initializeDebugLogs: initializeDebugLogs,
appendDebugLog: appendDebugLog,
log: log,
warn: warn
};
})(typeof globalThis !== 'undefined' ? globalThis : this);