[feature] Refactor configureLogger

This commit is contained in:
Sergey Konovalov
2025-10-01 02:28:27 +03:00
parent 6fd91f61d7
commit db6e6fd1e8
12 changed files with 63 additions and 32 deletions

View File

@ -35,7 +35,7 @@ function LoggerConfig() {
// Configuration paths
const CONFIG_PATHS = {
logLevel: 'log.level'
logLevel: 'log.options.categories.default.level'
};
// Reset state and errors to global config

View File

@ -33,6 +33,7 @@
'use strict';
const Ajv = require('ajv');
const addFormats = require('ajv-formats');
const logger = require('../../../../../Common/sources/logger');
const tenantManager = require('../../../../../Common/sources/tenantManager');
const supersetSchema = require('../../../../../Common/config/schemas/config.schema.json');
const {deriveSchemaForScope, X_SCOPE_KEYWORD} = require('./config.schema.utils');
@ -101,6 +102,13 @@ function validateScoped(ctx, updateData) {
function getScopedConfig(ctx) {
const cfg = ctx.getFullCfg();
const configCopy = JSON.parse(JSON.stringify(cfg));
// Add log config. getLoggerConfig return merged config
if (!configCopy.log) {
configCopy.log = {};
}
configCopy.log.options = logger.getLoggerConfig();
const filter = isAdminScope(ctx) ? filterAdmin : filterTenant;
filter(configCopy);
return configCopy;

View File

@ -38,6 +38,7 @@ const operationContext = require('../../../Common/sources/operationContext');
const tenantManager = require('../../../Common/sources/tenantManager');
const license = require('../../../Common/sources/license');
const utils = require('../../../Common/sources/utils');
const runtimeConfigManager = require('../../../Common/sources/runtimeConfigManager');
const express = require('express');
const http = require('http');
@ -108,5 +109,9 @@ server.listen(port, () => {
operationContext.global.logger.warn('AdminPanel server listening on port %d', port);
});
//Initialize watch here to avoid circular import with operationContext
runtimeConfigManager.initRuntimeConfigWatcher(operationContext.global).catch(err => {
operationContext.global.logger.warn('initRuntimeConfigWatcher error: %s', err.stack);
});
//after all required modules in all files
moduleReloader.finalizeConfigWithRuntime();

View File

@ -21,7 +21,6 @@
},
"log": {
"filePath": "",
"level": "WARN",
"options": {
"replaceConsole": true
}

View File

@ -9,6 +9,6 @@
}
},
"categories": {
"default": {"appenders": ["default"]}
"default": {"appenders": ["default"], "level": "ALL"}
}
}

View File

@ -9,6 +9,6 @@
}
},
"categories": {
"default": {"appenders": ["default"]}
"default": {"appenders": ["default"], "level": "WARN"}
}
}

View File

@ -220,10 +220,28 @@
"additionalProperties": true,
"x-scope": "admin",
"properties": {
"level": {
"type": "string",
"enum": ["ALL", "TRACE", "DEBUG", "INFO", "WARN", "ERROR", "FATAL", "OFF"],
"description": "Logging level for the application"
"options": {
"type": "object",
"additionalProperties": true,
"properties": {
"categories": {
"type": "object",
"additionalProperties": true,
"properties": {
"default": {
"type": "object",
"additionalProperties": true,
"properties": {
"level": {
"type": "string",
"enum": ["ALL", "TRACE", "DEBUG", "INFO", "WARN", "ERROR", "FATAL", "OFF"],
"description": "Logging level for the application"
}
}
}
}
}
}
}
}
}

View File

@ -34,14 +34,12 @@
const config = require('config');
const util = require('util');
const path = require('path');
const fs = require('fs');
const log4js = require('log4js');
const layouts = require('log4js/lib/layouts');
const logConfigPath = config.get('log.filePath');
let logLevel = config.get('log.level');
const fullLogConfigPath = path.resolve(__dirname, '..', logConfigPath);
const logOptions = config.get('log.options');
// https://stackoverflow.com/a/36643588
const dateToJSONWithTZ = function (d) {
@ -83,18 +81,15 @@ log4js.addLayout('patternWithTokens', cfg => {
return layouts.patternLayout(pattern, tokens);
});
exports.configureLogger = function (level = logLevel) {
const logConfig = JSON.parse(fs.readFileSync(fullLogConfigPath, 'utf8'));
Object.keys(logConfig.categories).forEach(categoryName => {
logConfig.categories[categoryName].level = level;
});
logLevel = level;
log4js.configure(logConfig);
};
exports.configureLogger();
exports.getLogLevel = function () {
return logLevel;
};
const cachedLogConfig = JSON.parse(fs.readFileSync(logConfigPath, 'utf8'));
let curLogConfig = cachedLogConfig;
function configureLogger(options) {
const mergedOptions = config.util.extendDeep({}, cachedLogConfig, options);
log4js.configure(mergedOptions);
curLogConfig = mergedOptions;
}
configureLogger(logOptions);
const logger = log4js.getLogger('nodeJS');
@ -129,3 +124,7 @@ exports.fatal = function () {
exports.shutdown = function (callback) {
return log4js.shutdown(callback);
};
exports.configureLogger = configureLogger;
exports.getLoggerConfig = function () {
return curLogConfig;
};

View File

@ -103,7 +103,6 @@ async function saveConfig(ctx, config) {
*/
function handleConfigFileChange(eventTypeOrCurrent, filenameOrPrevious) {
try {
const logLevel = logger.getLogLevel();
let shouldReload = false;
if (typeof eventTypeOrCurrent === 'object' && eventTypeOrCurrent.isFile) {
@ -117,9 +116,7 @@ function handleConfigFileChange(eventTypeOrCurrent, filenameOrPrevious) {
nodeCache.del(configFileName);
// Reload config and update logging level
getConfig(operationContext.global).then(config => {
if (config.log.level !== logLevel) {
logger.configureLogger(config.log.level);
}
logger.configureLogger(config?.log?.options);
});
}
} catch (err) {

View File

@ -99,7 +99,6 @@ const pubsubService = require('./pubsubRabbitMQ');
const wopiClient = require('./wopiClient');
const queueService = require('./../../Common/sources/taskqueueRabbitMQ');
const operationContext = require('./../../Common/sources/operationContext');
const runtimeConfigManager = require('./../../Common/sources/runtimeConfigManager');
const tenantManager = require('./../../Common/sources/tenantManager');
const {notificationTypes, ...notificationService} = require('../../Common/sources/notificationService');
const aiProxyHandler = require('./ai/aiProxyHandler');
@ -4348,10 +4347,6 @@ exports.install = function (server, app, callbackFunction) {
});
});
//Initialize watch here to avoid circular import with operationContext
runtimeConfigManager.initRuntimeConfigWatcher(operationContext.global).catch(err => {
operationContext.global.logger.warn('initRuntimeConfigWatcher error: %s', err.stack);
});
void aiProxyHandler.getPluginSettings(operationContext.global);
};
exports.setLicenseInfo = async function (globalCtx, data, original) {

View File

@ -60,6 +60,7 @@ const staticRouter = require('./routes/static');
const infoRouter = require('./routes/info');
const ms = require('ms');
const aiProxyHandler = require('./ai/aiProxyHandler');
const runtimeConfigManager = require('./../../Common/sources/runtimeConfigManager');
const cfgWopiEnable = config.get('wopi.enable');
const cfgWopiDummyEnable = config.get('wopi.dummy.enable');
@ -499,5 +500,9 @@ process.on('uncaughtException', err => {
});
});
//Initialize watch here to avoid circular import with operationContext
runtimeConfigManager.initRuntimeConfigWatcher(operationContext.global).catch(err => {
operationContext.global.logger.warn('initRuntimeConfigWatcher error: %s', err.stack);
});
//after all required modules in all files
moduleReloader.finalizeConfigWithRuntime();

View File

@ -37,6 +37,7 @@ const moduleReloader = require('./../../Common/sources/moduleReloader');
const config = moduleReloader.requireConfigWithRuntime();
const logger = require('./../../Common/sources/logger');
const operationContext = require('./../../Common/sources/operationContext');
const runtimeConfigManager = require('./../../Common/sources/runtimeConfigManager');
if (cluster.isMaster) {
const fs = require('fs');
@ -95,6 +96,10 @@ if (cluster.isMaster) {
} else {
const converter = require('./converter');
converter.run();
//Initialize watch here to avoid circular import with operationContext
runtimeConfigManager.initRuntimeConfigWatcher(operationContext.global).catch(err => {
operationContext.global.logger.warn('initRuntimeConfigWatcher error: %s', err.stack);
});
}
process.on('uncaughtException', err => {