From 9c0dcd7dd147a1302d1b14c4d07ca246ac72c5b6 Mon Sep 17 00:00:00 2001 From: Vladimir Davydov <vdavydov@tarantool.org> Date: Mon, 23 Oct 2023 17:00:23 +0300 Subject: [PATCH] log: make log.cfg{modules=...} work as box.cfg{log_modules=...} Configuring log modules work differently with log.cfg and box.cfg: box.cfg{log_modules=...} overwrites the current config completely while log.cfg{modules=...} overwrites the currently config only for the specified modules. Let's fix this inconsistency by making log.cfg behave exactly as box.cfg. Closes #7962 NO_DOC=bug fix (cherry picked from commit c13e59a555966c1c8a0948041233afa270957fd3) --- .../unreleased/gh-7962-log-cfg-modules-fix.md | 6 ++ src/box/lua/load_cfg.lua | 34 +++++----- src/lua/log.lua | 3 +- .../gh_3211_per_module_log_level_test.lua | 63 +++++++------------ 4 files changed, 43 insertions(+), 63 deletions(-) create mode 100644 changelogs/unreleased/gh-7962-log-cfg-modules-fix.md diff --git a/changelogs/unreleased/gh-7962-log-cfg-modules-fix.md b/changelogs/unreleased/gh-7962-log-cfg-modules-fix.md new file mode 100644 index 0000000000..b6988ea969 --- /dev/null +++ b/changelogs/unreleased/gh-7962-log-cfg-modules-fix.md @@ -0,0 +1,6 @@ +## bugfix/core + +* Fixed the behavior of `log.cfg{modules = ...}`. Now, instead of merging the + new log modules configuration with the old one, it completely overwrites the + current configuration, which is consistent with `box.cfg{log_modules = ...}` + (gh-7962). diff --git a/src/box/lua/load_cfg.lua b/src/box/lua/load_cfg.lua index 5199ca18c6..1813fb3936 100644 --- a/src/box/lua/load_cfg.lua +++ b/src/box/lua/load_cfg.lua @@ -771,11 +771,10 @@ local function check_cfg_option_type(template, name, value) end end -local function prepare_cfg(cfg, default_cfg, template_cfg, modify_cfg) +local function prepare_cfg(cfg, old_cfg, default_cfg, template_cfg, modify_cfg) if cfg == nil then - return {} - end - if type(cfg) ~= 'table' then + cfg = {} + elseif type(cfg) ~= 'table' then error("Error: cfg should be a table") end local new_cfg = {} @@ -793,6 +792,15 @@ local function prepare_cfg(cfg, default_cfg, template_cfg, modify_cfg) end new_cfg[k] = v end + -- Use the old config for omitted options. + for k, v in pairs(old_cfg) do + -- Don't override options set to box.NULL (which equals nil but + -- evaluates to true) because setting an option to box.NULL must + -- be equivalent to resetting it to the default value. + if cfg[k] == nil and not cfg[k] then + new_cfg[k] = v + end + end return new_cfg end @@ -809,16 +817,6 @@ local function apply_env_cfg(cfg, env_cfg, skip_cfg) end end -local function merge_cfg(cfg, cur_cfg) - for k,v in pairs(cur_cfg) do - if cfg[k] == nil then - cfg[k] = v - elseif type(v) == 'table' then - merge_cfg(cfg[k], v) - end - end -end - -- Return true if two configurations are equivalent. local function compare_cfg(cfg1, cfg2) if type(cfg1) ~= type(cfg2) then @@ -907,8 +905,8 @@ end local function reload_cfg(oldcfg, cfg) cfg = upgrade_cfg(cfg, translate_cfg) - local newcfg = prepare_cfg(cfg, default_cfg, template_cfg, modify_cfg) - + local newcfg = prepare_cfg(cfg, {}, default_cfg, template_cfg, + modify_cfg) local module_keys = {} -- iterate over original table because prepare_cfg() may store NILs for key in pairs(cfg) do @@ -1004,8 +1002,7 @@ local function load_cfg(cfg) -- Set options passed through environment variables. apply_env_cfg(cfg, box.internal.cfg.env, pre_load_cfg_is_set) - cfg = prepare_cfg(cfg, default_cfg, template_cfg, modify_cfg) - merge_cfg(cfg, pre_load_cfg); + cfg = prepare_cfg(cfg, pre_load_cfg, default_cfg, template_cfg, modify_cfg) -- Save new box.cfg box.cfg = cfg @@ -1227,7 +1224,6 @@ end box.internal.prepare_cfg = prepare_cfg box.internal.apply_env_cfg = apply_env_cfg -box.internal.merge_cfg = merge_cfg box.internal.check_cfg_option_type = check_cfg_option_type box.internal.update_cfg = update_cfg box.internal.env_cfg = env_cfg diff --git a/src/lua/log.lua b/src/lua/log.lua index 1f8ce74ea2..13e36082df 100644 --- a/src/lua/log.lua +++ b/src/lua/log.lua @@ -445,8 +445,7 @@ local function log_configure(self, cfg, box_api) local env_cfg = box.internal.env_cfg(box2log_keys) box.internal.apply_env_cfg(cfg, box_to_log_cfg(env_cfg)) end - cfg = box.internal.prepare_cfg(cfg, default_cfg, option_types) - box.internal.merge_cfg(cfg, log_cfg); + cfg = box.internal.prepare_cfg(cfg, log_cfg, default_cfg, option_types) end log_check_cfg(cfg) diff --git a/test/box-luatest/gh_3211_per_module_log_level_test.lua b/test/box-luatest/gh_3211_per_module_log_level_test.lua index 8fc2e48177..391eb0cc1c 100644 --- a/test/box-luatest/gh_3211_per_module_log_level_test.lua +++ b/test/box-luatest/gh_3211_per_module_log_level_test.lua @@ -80,14 +80,6 @@ g2.test_per_module_log_level = function(cg) local log = require('log') local log_cfg = _G.log_cfg - local function assert_log_and_box_cfg_equals() - t.assert_equals(log.cfg.level, box.cfg.log_level) - t.assert_equals(log.cfg.modules.mod1, box.cfg.log_modules.mod1) - t.assert_equals(log.cfg.modules.mod2, box.cfg.log_modules.mod2) - t.assert_equals(log.cfg.modules.mod3, box.cfg.log_modules.mod3) - t.assert_equals(log.cfg.modules.mod4, box.cfg.log_modules.mod4) - end - t.assert_error_msg_contains( "modules': should be of type table", log_cfg, {modules = 'hello'}) @@ -99,6 +91,14 @@ g2.test_per_module_log_level = function(cg) "Incorrect value for option 'log_modules.mod2': " .. "expected crit,warn,info,debug,syserror,verbose,fatal,error", log_cfg, {modules = {mod2 = 'hello'}}) + t.assert_error_msg_content_equals( + "Incorrect value for option 'log_modules.mod3': " .. + "expected crit,warn,info,debug,syserror,verbose,fatal,error", + log_cfg, {modules = {mod3 = ''}}) + t.assert_error_msg_content_equals( + "Incorrect value for option 'log_modules.mod4': " .. + "should be one of types number, string", + log_cfg, {modules = {mod4 = box.NULL}}) t.assert_error_msg_content_equals( "Incorrect value for option 'module name': should be of type string", log_cfg, {modules = {[123] = 'debug'}}) @@ -112,40 +112,23 @@ g2.test_per_module_log_level = function(cg) -- per-module levels. log_cfg{level = 'warn'} t.assert_equals(log.cfg.level, 'warn') - t.assert_equals(log.cfg.modules.mod1, 'debug') - t.assert_equals(log.cfg.modules.mod2, 2) - t.assert_equals(log.cfg.modules.mod3, 'error') - assert_log_and_box_cfg_equals() - --[[ TODO(gh-7962) - -- Check that log.cfg{modules = {...}} with the new modules appends them - -- to the existing ones. - log_cfg{modules = {mod4 = 4}} - t.assert_equals(log.cfg.modules.mod1, 'debug') - t.assert_equals(log.cfg.modules.mod2, 2) - t.assert_equals(log.cfg.modules.mod3, 'error') - t.assert_equals(log.cfg.modules.mod4, 4) - assert_log_and_box_cfg_equals() - -- Check that log.cfg{modules = {...}} sets levels for the specified - -- modules, and doesn't affect other modules. - log_cfg{modules = {mod1 = 0, mod3 = 'info'}} - t.assert_equals(log.cfg.modules.mod1, 0) - t.assert_equals(log.cfg.modules.mod2, 2) - t.assert_equals(log.cfg.modules.mod3, 'info') - t.assert_equals(log.cfg.modules.mod4, 4) - assert_log_and_box_cfg_equals() - -- Check that box.NULL and the empty string remove the corresponding - -- module from the config. - log_cfg{modules = {mod2 = box.NULL, mod4 = ''}} - t.assert_equals(log.cfg.modules.mod1, 0) - t.assert_equals(log.cfg.modules.mod2, nil) - t.assert_equals(log.cfg.modules.mod3, 'info') - t.assert_equals(log.cfg.modules.mod4, nil) - assert_log_and_box_cfg_equals() + t.assert_equals(box.cfg.log_level, log.cfg.level) + t.assert_equals(log.cfg.modules, { + mod1 = 'debug', mod2 = 2, mod3 = 'error' + }) + t.assert_equals(box.cfg.log_modules, log.cfg.modules) + -- Check that log.cfg{modules = {...}} overwrites old modules. + log_cfg{modules = {mod3 = 'info', mod4 = 4}} + t.assert_equals(log.cfg.modules, {mod3 = 'info', mod4 = 4}) + t.assert_equals(box.cfg.log_modules, log.cfg.modules) + t.assert_equals(log.cfg.level, 'warn') + t.assert_equals(box.cfg.log_level, log.cfg.level) -- Check that log.cfg{modules = box.NULL} removes all modules. log_cfg{modules = box.NULL} t.assert_equals(log.cfg.modules, nil) t.assert_equals(box.cfg.log_modules, nil) - --]] + t.assert_equals(log.cfg.level, 'warn') + t.assert_equals(box.cfg.log_level, log.cfg.level) -- Check that log levels actually affect what is printed to the log. log_cfg{level = 'info', modules = {module2 = 4, module3 = 'debug'}} @@ -226,8 +209,4 @@ g2.test_tarantool_module = function(cg) end) find_in_log(cg, 'Lua verbose message 3', false) find_in_log(cg, 'C debug message 3', true) - - -- TODO(gh-7962) - -- Check that box.NULL unsets custom Tarantool C log level. - -- _G.log_cfg{modules = {tarantool = box.NULL}} end -- GitLab