// SPDX-FileCopyrightText: 2023 XWiki CryptPad Team and contributors // // SPDX-License-Identifier: AGPL-3.0-or-later var Store = require("./storage/file"); var Util = require("./common-util"); var Logger = module.exports; /* Every line in the log should contain: * timestamp * public key of initiator * the action * the event's tag */ var messageTemplate = function (type, time, tag, info) { return JSON.stringify([type.toUpperCase(), time, tag, info]); }; var noop = function () {}; var write = function (ctx, content, cb) { if (typeof(cb) !== "function") { cb = noop; } if (!ctx.store) { cb = Util.mkAsync(cb); return void cb(); } ctx.store.log(ctx.channelName, content, cb); }; // various degrees of logging const logLevels = Logger.levels = ['silly', 'verbose', 'debug', 'feedback', 'info', 'warn', 'error']; var handlers = {}; ['silly', 'debug', 'verbose', 'feedback', 'info'].forEach(function (level) { handlers[level] = function (ctx, content) { console.log(content); }; }); ['warn', 'error'].forEach(function (level) { handlers[level] = function (ctx, content) { console.error(content); }; }); var createLogType = function (ctx, type) { if (logLevels.indexOf(type) < logLevels.indexOf(ctx.logLevel)) { return noop; } return function (tag, info, cb) { if (ctx.shutdown) { throw new Error("Logger has been shut down!"); } var time = new Date().toISOString(); var content; try { content = messageTemplate(type, time, tag, info); } catch (e) { return; } if (ctx.logToStdout && typeof(handlers[type]) === 'function') { handlers[type](ctx, content); } write(ctx, content, cb); }; }; var createMethods = function (ctx) { var log = {}; logLevels.forEach(function (type) { log[type] = createLogType(ctx, type); }); return log; }; Logger.create = function (config, cb) { if (typeof(config.logLevel) !== 'string') { config.logLevel = 'info'; } var date = new Date(); var launchTime = ('' + date.getUTCFullYear()).slice(-2) + date.toISOString(); var ctx = { channelName: launchTime, logFeedback: Boolean(config.logFeedback), logLevel: config.logLevel, logToStdout: config.logToStdout, }; if (!config.logPath) { console.log("No logPath configured. Logging to file disabled"); var logger = createMethods(ctx); logger.shutdown = noop; return void cb(Object.freeze(logger)); } Store.create({ filePath: config.logPath, archivePath: config.archivePath, }, function (err, store) { if (err) { throw err; } ctx.store = store; var logger = createMethods(ctx); logger.shutdown = function () { delete ctx.store; ctx.shutdown = true; store.shutdown(); }; cb(Object.freeze(logger)); }); };