From d622dfbb5773a41d9cd1113006a09dc492860455 Mon Sep 17 00:00:00 2001 From: Frank Elsinga Date: Thu, 18 Jan 2024 22:31:10 +0100 Subject: [PATCH] unified our logging infrastructure --- server/database.js | 6 +- server/modules/apicache/apicache.js | 61 +++++++------------ .../real-browser-monitor-type.js | 4 +- server/notification-providers/nostr.js | 2 +- server/notification-providers/slack.js | 15 +++-- server/server.js | 2 +- .../socket-handlers/api-key-socket-handler.js | 2 +- .../cloudflared-socket-handler.js | 4 +- .../maintenance-socket-handler.js | 8 +-- .../status-page-socket-handler.js | 2 +- src/util.ts | 26 ++++---- 11 files changed, 57 insertions(+), 75 deletions(-) diff --git a/server/database.js b/server/database.js index 4a12746f5f..141f06f257 100644 --- a/server/database.js +++ b/server/database.js @@ -514,12 +514,12 @@ class Database { let title = await setting("title"); if (title) { - console.log("Migrating Status Page"); + log.info("database", "Migrating Status Page"); let statusPageCheck = await R.findOne("status_page", " slug = 'default' "); if (statusPageCheck !== null) { - console.log("Migrating Status Page - Skip, default slug record is already existing"); + log.info("database", "Migrating Status Page - Skip, default slug record is already existing"); return; } @@ -565,7 +565,7 @@ class Database { await setSetting("entryPage", "statusPage-default", "general"); } - console.log("Migrating Status Page - Done"); + log.info("database", "Migrating Status Page - Done"); } } diff --git a/server/modules/apicache/apicache.js b/server/modules/apicache/apicache.js index 41930b24d0..89f2f1e165 100644 --- a/server/modules/apicache/apicache.js +++ b/server/modules/apicache/apicache.js @@ -1,5 +1,6 @@ let url = require("url"); let MemoryCache = require("./memory-cache"); +const { log } = require("../../../src/util"); let t = { ms: 1, @@ -90,24 +91,6 @@ function ApiCache() { instances.push(this); this.id = instances.length; - /** - * Logs a message to the console if the `DEBUG` environment variable is set. - * @param {string} a The first argument to log. - * @param {string} b The second argument to log. - * @param {string} c The third argument to log. - * @param {string} d The fourth argument to log, and so on... (optional) - * - * Generated by Trelent - */ - function debug(a, b, c, d) { - let arr = ["\x1b[36m[apicache]\x1b[0m", a, b, c, d].filter(function (arg) { - return arg !== undefined; - }); - let debugEnv = process.env.DEBUG && process.env.DEBUG.split(",").indexOf("apicache") !== -1; - - return (globalOptions.debug || debugEnv) && console.log.apply(null, arr); - } - /** * Returns true if the given request and response should be logged. * @param {Object} request The HTTP request object. @@ -146,7 +129,7 @@ function ApiCache() { let groupName = req.apicacheGroup; if (groupName) { - debug("group detected \"" + groupName + "\""); + log.debug("apicache", `group detected "${groupName}"`); let group = (index.groups[groupName] = index.groups[groupName] || []); group.unshift(key); } @@ -212,7 +195,7 @@ function ApiCache() { redis.hset(key, "duration", duration); redis.expire(key, duration / 1000, expireCallback || function () {}); } catch (err) { - debug("[apicache] error in redis.hset()"); + log.debug("apicache", `error in redis.hset(): ${err}`); } } else { memCache.add(key, value, duration, expireCallback); @@ -320,10 +303,10 @@ function ApiCache() { // display log entry let elapsed = new Date() - req.apicacheTimer; - debug("adding cache entry for \"" + key + "\" @ " + strDuration, logDuration(elapsed)); - debug("_apicache.headers: ", res._apicache.headers); - debug("res.getHeaders(): ", getSafeHeaders(res)); - debug("cacheObject: ", cacheObject); + log.debug("apicache", `adding cache entry for "${key}" @ ${strDuration} ${logDuration(elapsed)}`); + log.debug("apicache", `_apicache.headers: ${res._apicache.headers}`); + log.debug("apicache", `res.getHeaders(): ${getSafeHeaders(res)}`); + log.debug("apicache", `cacheObject: ${cacheObject}`); } } @@ -402,10 +385,10 @@ function ApiCache() { let redis = globalOptions.redisClient; if (group) { - debug("clearing group \"" + target + "\""); + log.debug("apicache", `clearing group "${target}"`); group.forEach(function (key) { - debug("clearing cached entry for \"" + key + "\""); + log.debug("apicache", `clearing cached entry for "${key}"`); clearTimeout(timers[key]); delete timers[key]; if (!globalOptions.redisClient) { @@ -414,7 +397,7 @@ function ApiCache() { try { redis.del(key); } catch (err) { - console.log("[apicache] error in redis.del(\"" + key + "\")"); + log.info("apicache", "error in redis.del(\"" + key + "\")"); } } index.all = index.all.filter(doesntMatch(key)); @@ -422,7 +405,7 @@ function ApiCache() { delete index.groups[target]; } else if (target) { - debug("clearing " + (isAutomatic ? "expired" : "cached") + " entry for \"" + target + "\""); + log.debug("apicache", `clearing ${isAutomatic ? "expired" : "cached"} entry for "${target}"`); clearTimeout(timers[target]); delete timers[target]; // clear actual cached entry @@ -432,7 +415,7 @@ function ApiCache() { try { redis.del(target); } catch (err) { - console.log("[apicache] error in redis.del(\"" + target + "\")"); + log.error("apicache", "error in redis.del(\"" + target + "\")"); } } @@ -449,7 +432,7 @@ function ApiCache() { } }); } else { - debug("clearing entire index"); + log.debug("apicache", "clearing entire index"); if (!redis) { memCache.clear(); @@ -461,7 +444,7 @@ function ApiCache() { try { redis.del(key); } catch (err) { - console.log("[apicache] error in redis.del(\"" + key + "\")"); + log.error("apicache", `error in redis.del("${key}"): ${err}`); } }); } @@ -528,7 +511,7 @@ function ApiCache() { /** * Get index of a group - * @param {string} group + * @param {string} group * @returns {number} */ this.getIndex = function (group) { @@ -543,9 +526,9 @@ function ApiCache() { * Express middleware * @param {(string|number)} strDuration Duration to cache responses * for. - * @param {function(Object, Object):boolean} middlewareToggle + * @param {function(Object, Object):boolean} middlewareToggle * @param {Object} localOptions Options for APICache - * @returns + * @returns */ this.middleware = function cache(strDuration, middlewareToggle, localOptions) { let duration = instance.getDuration(strDuration); @@ -752,7 +735,7 @@ function ApiCache() { */ let cache = function (req, res, next) { function bypass() { - debug("bypass detected, skipping cache."); + log.debug("apicache", "bypass detected, skipping cache."); return next(); } @@ -805,7 +788,7 @@ function ApiCache() { // send if cache hit from memory-cache if (cached) { let elapsed = new Date() - req.apicacheTimer; - debug("sending cached (memory-cache) version of", key, logDuration(elapsed)); + log.debug("apicache", `sending cached (memory-cache) version of ${key} ${logDuration(elapsed)}`); perf.hit(key); return sendCachedResponse(req, res, cached, middlewareToggle, next, duration); @@ -817,7 +800,7 @@ function ApiCache() { redis.hgetall(key, function (err, obj) { if (!err && obj && obj.response) { let elapsed = new Date() - req.apicacheTimer; - debug("sending cached (redis) version of", key, logDuration(elapsed)); + log.debug("apicache", "sending cached (redis) version of "+ key+" "+ logDuration(elapsed)); perf.hit(key); return sendCachedResponse( @@ -859,7 +842,7 @@ function ApiCache() { /** * Process options - * @param {Object} options + * @param {Object} options * @returns {Object} */ this.options = function (options) { @@ -873,7 +856,7 @@ function ApiCache() { } if (globalOptions.trackPerformance) { - debug("WARNING: using trackPerformance flag can cause high memory usage!"); + log.debug("apicache", "WARNING: using trackPerformance flag can cause high memory usage!"); } return this; diff --git a/server/monitor-types/real-browser-monitor-type.js b/server/monitor-types/real-browser-monitor-type.js index c03d36ca62..17b0c26902 100644 --- a/server/monitor-types/real-browser-monitor-type.js +++ b/server/monitor-types/real-browser-monitor-type.js @@ -59,7 +59,7 @@ if (process.platform === "win32") { * @returns {Promise} The executable is allowed? */ async function isAllowedChromeExecutable(executablePath) { - console.log(config.args); + log.info("Chromium", config.args); if (config.args["allow-all-chrome-exec"] || process.env.UPTIME_KUMA_ALLOW_ALL_CHROME_EXEC === "1") { return true; } @@ -95,7 +95,7 @@ async function getBrowser() { */ async function getRemoteBrowser(remoteBrowserID, userId) { let remoteBrowser = await RemoteBrowser.get(remoteBrowserID, userId); - log.debug("MONITOR", `Using remote browser: ${remoteBrowser.name} (${remoteBrowser.id})`); + log.debug("Chromium", `Using remote browser: ${remoteBrowser.name} (${remoteBrowser.id})`); browser = chromium.connect(remoteBrowser.url); return browser; } diff --git a/server/notification-providers/nostr.js b/server/notification-providers/nostr.js index 9d93678f22..a5407f7aa3 100644 --- a/server/notification-providers/nostr.js +++ b/server/notification-providers/nostr.js @@ -13,7 +13,7 @@ const { const semver = require("semver"); const nodeVersion = process.version; if (semver.lt(nodeVersion, "16.0.0")) { - log.warn("monitor", "Node <= 16 is unsupported for nostr, sorry :("); + log.warn("notification", "Node <= 16 is unsupported for nostr, sorry :("); } else if (semver.lt(nodeVersion, "18.0.0")) { // polyfills for node 16 global.crypto = require("crypto"); diff --git a/server/notification-providers/slack.js b/server/notification-providers/slack.js index d512a7cd8d..673d3a10bd 100644 --- a/server/notification-providers/slack.js +++ b/server/notification-providers/slack.js @@ -1,7 +1,8 @@ const NotificationProvider = require("./notification-provider"); const axios = require("axios"); -const { setSettings, setting } = require("../util-server"); const { getMonitorRelativeURL, UP } = require("../../src/util"); +const { Settings } = require("../settings"); +const { log } = require("../../src/util"); class Slack extends NotificationProvider { @@ -15,15 +16,13 @@ class Slack extends NotificationProvider { * @returns {Promise} */ static async deprecateURL(url) { - let currentPrimaryBaseURL = await setting("primaryBaseURL"); + let currentPrimaryBaseURL = await Settings.get("primaryBaseURL"); if (!currentPrimaryBaseURL) { - console.log("Move the url to be the primary base URL"); - await setSettings("general", { - primaryBaseURL: url, - }); + log.error("notification", "Move the url to be the primary base URL"); + await Settings.set("primaryBaseURL", url, "general"); } else { - console.log("Already there, no need to move the primary base URL"); + log.debug("notification", "Already there, no need to move the primary base URL"); } } @@ -86,7 +85,7 @@ class Slack extends NotificationProvider { await Slack.deprecateURL(notification.slackbutton); } - const baseURL = await setting("primaryBaseURL"); + const baseURL = await Settings.get("primaryBaseURL"); // Button if (baseURL) { diff --git a/server/server.js b/server/server.js index eeffb06356..37c74d61d1 100644 --- a/server/server.js +++ b/server/server.js @@ -1418,7 +1418,7 @@ let needSetup = false; }); } catch (e) { - console.error(e); + log.error("server", e); callback({ ok: false, diff --git a/server/socket-handlers/api-key-socket-handler.js b/server/socket-handlers/api-key-socket-handler.js index f76b909918..1394f8044a 100644 --- a/server/socket-handlers/api-key-socket-handler.js +++ b/server/socket-handlers/api-key-socket-handler.js @@ -60,7 +60,7 @@ module.exports.apiKeySocketHandler = (socket) => { ok: true, }); } catch (e) { - console.error(e); + log.error("apikeys", e); callback({ ok: false, msg: e.message, diff --git a/server/socket-handlers/cloudflared-socket-handler.js b/server/socket-handlers/cloudflared-socket-handler.js index 809191fe85..52f0a2d21f 100644 --- a/server/socket-handlers/cloudflared-socket-handler.js +++ b/server/socket-handlers/cloudflared-socket-handler.js @@ -100,11 +100,11 @@ module.exports.autoStart = async (token) => { } else { // Override the current token via args or env var await setSetting("cloudflaredTunnelToken", token); - console.log("Use cloudflared token from args or env var"); + log.info("cloudflare", "Use cloudflared token from args or env var"); } if (token) { - console.log("Start cloudflared"); + log.info("cloudflare", "Start cloudflared"); cloudflared.token = token; cloudflared.start(); } diff --git a/server/socket-handlers/maintenance-socket-handler.js b/server/socket-handlers/maintenance-socket-handler.js index 7de13fe57a..201014c226 100644 --- a/server/socket-handlers/maintenance-socket-handler.js +++ b/server/socket-handlers/maintenance-socket-handler.js @@ -67,7 +67,7 @@ module.exports.maintenanceSocketHandler = (socket) => { }); } catch (e) { - console.error(e); + log.error("maintenance", e); callback({ ok: false, msg: e.message, @@ -177,7 +177,7 @@ module.exports.maintenanceSocketHandler = (socket) => { ok: true, }); } catch (e) { - console.error(e); + log.error("maintenance", e); callback({ ok: false, msg: e.message, @@ -201,7 +201,7 @@ module.exports.maintenanceSocketHandler = (socket) => { }); } catch (e) { - console.error(e); + log.error("maintenance", e); callback({ ok: false, msg: e.message, @@ -225,7 +225,7 @@ module.exports.maintenanceSocketHandler = (socket) => { }); } catch (e) { - console.error(e); + log.error("maintenance", e); callback({ ok: false, msg: e.message, diff --git a/server/socket-handlers/status-page-socket-handler.js b/server/socket-handlers/status-page-socket-handler.js index ee1c68d3b6..ed948077b2 100644 --- a/server/socket-handlers/status-page-socket-handler.js +++ b/server/socket-handlers/status-page-socket-handler.js @@ -289,7 +289,7 @@ module.exports.statusPageSocketHandler = (socket) => { }); } catch (error) { - console.error(error); + log.error("socket", error); callback({ ok: false, msg: error.message, diff --git a/src/util.ts b/src/util.ts index b4a52f5088..72f930fb26 100644 --- a/src/util.ts +++ b/src/util.ts @@ -204,12 +204,13 @@ class Logger { /** * Write a message to the log + * @private * @param module The module the log comes from * @param msg Message to write - * @param level Log level. One of INFO, WARN, ERROR, DEBUG or can be customized. + * @param level {"INFO"|"WARN"|"ERROR"|"DEBUG"} Log level * @returns {void} */ - log(module: string, msg: any, level: string) { + log(module: string, msg: unknown, level: "INFO"|"WARN"|"ERROR"|"DEBUG"): void { if (level === "DEBUG" && !isDev) { return; } @@ -219,7 +220,6 @@ class Logger { } module = module.toUpperCase(); - level = level.toUpperCase(); let now; if (dayjs.tz) { @@ -306,8 +306,8 @@ class Logger { * @param msg Message to write * @returns {void} */ - info(module: string, msg: unknown) { - this.log(module, msg, "info"); + info(module: string, msg: string): void { + this.log(module, msg, "INFO"); } /** @@ -316,8 +316,8 @@ class Logger { * @param msg Message to write * @returns {void} */ - warn(module: string, msg: unknown) { - this.log(module, msg, "warn"); + warn(module: string, msg: string): void { + this.log(module, msg, "WARN"); } /** @@ -326,8 +326,8 @@ class Logger { * @param msg Message to write * @returns {void} */ - error(module: string, msg: unknown) { - this.log(module, msg, "error"); + error(module: string, msg: string): void { + this.log(module, msg, "ERROR"); } /** @@ -336,8 +336,8 @@ class Logger { * @param msg Message to write * @returns {void} */ - debug(module: string, msg: unknown) { - this.log(module, msg, "debug"); + debug(module: string, msg: string): void { + this.log(module, msg, "DEBUG"); } /** @@ -354,7 +354,7 @@ class Logger { finalMessage = `${msg}: ${exception}`; } - this.log(module, finalMessage, "error"); + this.log(module, finalMessage, "ERROR"); } } @@ -398,7 +398,7 @@ export class TimeLogger { * @param name Name of monitor * @returns {void} */ - print(name: string) { + print(name: string): void { if (isDev && process.env.TIMELOGGER === "1") { console.log(name + ": " + (dayjs().valueOf() - this.startTime) + "ms"); }