Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

spdlog::initialize_logger undesired effect on patterns #2648

Closed
afshinpir opened this issue Feb 22, 2023 · 5 comments
Closed

spdlog::initialize_logger undesired effect on patterns #2648

afshinpir opened this issue Feb 22, 2023 · 5 comments

Comments

@afshinpir
Copy link
Contributor

Hi all

I have a small code with 1 logger and 2 sinkers with different pattern on sinkers:

auto create_logger() {
    spdlog::cfg::load_env_levels();

    std::vector<spdlog::sink_ptr> sinks;

    auto console1_sink = std::make_shared<spdlog::sinks::stdout_color_sink_mt>();
    console1_sink->set_level(spdlog::level::info);
    console1_sink->set_pattern("[%n] %v");
    sinks.push_back(console1_sink);

    auto console2_sink = std::make_shared<spdlog::sinks::stderr_color_sink_mt>();
    console2_sink->set_level(spdlog::level::trace);
    sinks.push_back(console2_sink);

    auto logger = std::make_shared<spdlog::logger>(GGL_PROVIDER_LOG_NAME, std::begin(sinks), std::end(sinks));
    spdlog::initialize_logger(logger);
    return logger;
}

now if you log anything with logger like this:

logger->info("test");

You will see default pattern on output of both sinkers. Why? Because spdlog::initialize_logger applies pattern on loggers(which is default) and these patterns will be applied to sinkers overriding their patterns. I used spdlog::initialize_logger only in order to apply SPDLOG_LEVEL values from command line, but this undesired behavior is very bad. I think I have a workaround by setting patterns after spdlog::initialize_logger(logger), but I don't think this is a desired approach.

@tt4g
Copy link
Contributor

tt4g commented Feb 23, 2023

The description of spdlog::initialize_logger() clearly states that it changes the formatter. Its behavior cannot be easily changed.

// Initialize and register a logger,
// formatter and flush level will be set according the global settings.
//
// Useful for initializing manually created loggers with the global settings.
//
// Example:
// auto mylogger = std::make_shared<spdlog::logger>("mylogger", ...);
// spdlog::initialize_logger(mylogger);
SPDLOG_API void initialize_logger(std::shared_ptr<logger> logger);

If you are calling spdlog::initialize_logger() to apply the log levels loaded by spdlog::cfg::load_env_levels(), the formatter can only be changed after spdlog::initialize_logger().

@afshinpir
Copy link
Contributor Author

afshinpir commented Feb 23, 2023

@tt4g Since you normally create spdlog::logger after creating sinkers and setting up their configuration, I think this behavior is somehow not great.
I think it is better to have another method that only applies levels to loggers directly based on SPDLOG_LEVEL environment variable too.

@tt4g
Copy link
Contributor

tt4g commented Feb 23, 2023

If you think there is demand, please open a PR to add an API that allows only log levels to be set.
The following code sets the log level loaded with spdlog::cfg::load_env_levels() in spdlog::initialize_logger().

// set new level according to previously configured level or default level
auto it = log_levels_.find(new_logger->name());
auto new_level = it != log_levels_.end() ? it->second : global_log_level_;
new_logger->set_level(new_level);

@afshinpir
Copy link
Contributor Author

Already created a PR #2649 . I hope I have not made any mistakes there.

@afshinpir
Copy link
Contributor Author

My PR already merged. Now everyone can use apply_logger_env_levels to apply SPDLOG_LEVEL to their manually created loggers without changing sinkers' pattern.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants