Updated load_env_levels() and load_argv_levels() to return level map

pull/2143/head
gabime 4 years ago
parent 11a98a8cb4
commit c1223a6f04

@ -123,7 +123,7 @@ int main(int argc, char *argv[])
auto file_sink = std::make_shared<spdlog::sinks::basic_file_sink_mt>(filename, true);
auto logger = std::make_shared<async_logger>("async_logger", std::move(file_sink), std::move(tp), async_overflow_policy::block);
bench_mt(howmany, std::move(logger), threads);
// verify_file(filename, howmany);
//verify_file(filename, howmany);
}
spdlog::info("");

@ -115,9 +115,18 @@ void daily_example()
#include "spdlog/cfg/env.h"
void load_levels_example()
{
// Set the log level to "info" and mylogger to "trace":
// Set the default logger level to "info" and mylogger to "trace":
// SPDLOG_LEVEL=info,mylogger=trace && ./example
spdlog::cfg::load_env_levels();
auto levels = spdlog::cfg::load_env_levels();
auto it = levels.find(spdlog::default_logger()->name());
if(it != levels.end())
spdlog::default_logger()->set_level(it->second);
auto my_logger = spdlog::basic_logger_mt("my_logger", "logs/my-logger.txt");
it = levels.find(my_logger->name());
if(it != levels.end())
my_logger ->set_level(it->second);
// or from command line:
// ./example SPDLOG_LEVEL=info,mylogger=trace
// #include "spdlog/cfg/argv.h" // for loading levels from argv

@ -20,7 +20,7 @@ namespace spdlog {
namespace cfg {
// search for SPDLOG_LEVEL= in the args and use it to init the levels
inline void load_argv_levels(int argc, const char **argv)
inline level_map load_argv_levels(int argc, const char **argv)
{
const std::string spdlog_level_prefix = "SPDLOG_LEVEL=";
for (int i = 1; i < argc; i++)
@ -29,14 +29,17 @@ inline void load_argv_levels(int argc, const char **argv)
if (arg.find(spdlog_level_prefix) == 0)
{
auto levels_string = arg.substr(spdlog_level_prefix.size());
helpers::load_levels(levels_string);
return helpers::load_levels(levels_string);
}
}
// the "SPDLOG_LEVEL=" prefix was not found in any of the argv items
return std::unordered_map<std::string, level::level_enum>{};
}
inline void load_argv_levels(int argc, char **argv)
inline level_map load_argv_levels(int argc, char **argv)
{
load_argv_levels(argc, const_cast<const char **>(argv));
return load_argv_levels(argc, const_cast<const char **>(argv));
}
} // namespace cfg

@ -24,13 +24,11 @@
namespace spdlog {
namespace cfg {
inline void load_env_levels()
inline std::unordered_map<std::string, level::level_enum> load_env_levels()
{
auto env_val = details::os::getenv("SPDLOG_LEVEL");
if (!env_val.empty())
{
helpers::load_levels(env_val);
}
return helpers::load_levels(env_val);
}
} // namespace cfg

@ -78,17 +78,15 @@ inline std::unordered_map<std::string, std::string> extract_key_vals_(const std:
return rv;
}
SPDLOG_INLINE void load_levels(const std::string &input)
SPDLOG_INLINE std::unordered_map<std::string, level::level_enum> load_levels(const std::string &input)
{
std::unordered_map<std::string, level::level_enum> levels;
if (input.empty() || input.size() > 512)
{
return;
return levels;
}
auto key_vals = extract_key_vals_(input);
std::unordered_map<std::string, level::level_enum> levels;
level::level_enum global_level = level::info;
bool global_level_found = false;
for (auto &name_level : key_vals)
{
@ -100,19 +98,9 @@ SPDLOG_INLINE void load_levels(const std::string &input)
{
continue;
}
if (logger_name.empty()) // no logger name indicate global level
{
global_level_found = true;
global_level = level;
}
else
{
levels[logger_name] = level;
}
levels[logger_name] = level;
}
// TODO what to do here with registry?
//details::registry::instance().set_levels(std::move(levels), global_level_found ? &global_level : nullptr);
return levels;
}
} // namespace helpers

@ -8,6 +8,9 @@
namespace spdlog {
namespace cfg {
using level_map = std::unordered_map<std::string, level::level_enum>;
namespace helpers {
//
// Init levels from given string
@ -18,7 +21,7 @@ namespace helpers {
// turn off all logging except for logger1: "off,logger1=debug"
// turn off all logging except for logger1 and logger2: "off,logger1=debug,logger2=info"
//
SPDLOG_API void load_levels(const std::string &txt);
SPDLOG_API level_map load_levels(const std::string &txt);
} // namespace helpers
} // namespace cfg

@ -29,7 +29,7 @@ set(SPDLOG_UTESTS_SOURCES
test_fmt_helper.cpp
test_stdout_api.cpp
test_create_dir.cpp
# test_cfg.cpp TODO
test_cfg.cpp
test_time_point.cpp
test_stopwatch.cpp)

@ -11,173 +11,139 @@ using spdlog::sinks::test_sink_st;
TEST_CASE("env", "[cfg]")
{
spdlog::drop("l1");
auto l1 = spdlog::create<test_sink_st>("l1");
#ifdef CATCH_PLATFORM_WINDOWS
_putenv_s("SPDLOG_LEVEL", "l1=warn");
_putenv_s("SPDLOG_LEVEL", "warn");
#else
setenv("SPDLOG_LEVEL", "l1=warn", 1);
setenv("SPDLOG_LEVEL", "warn", 1);
#endif
load_env_levels();
REQUIRE(l1->level() == spdlog::level::warn);
spdlog::set_default_logger(spdlog::create<test_sink_st>("cfg-default"));
REQUIRE(spdlog::default_logger()->level() == spdlog::level::info);
auto levels = load_env_levels();
auto it = levels.find(spdlog::default_logger()->name());
REQUIRE(levels == spdlog::cfg::level_map {{"", spdlog::level::warn}});
}
TEST_CASE("argv1", "[cfg]")
{
spdlog::drop("l1");
const char *argv[] = {"ignore", "SPDLOG_LEVEL=l1=warn"};
load_argv_levels(2, argv);
auto l1 = spdlog::create<spdlog::sinks::test_sink_st>("l1");
REQUIRE(l1->level() == spdlog::level::warn);
REQUIRE(spdlog::default_logger()->level() == spdlog::level::info);
auto levels= load_argv_levels(sizeof(argv)/sizeof (const char*), argv);
REQUIRE(levels == spdlog::cfg::level_map {{"l1", spdlog::level::warn}});
}
TEST_CASE("argv2", "[cfg]")
{
spdlog::drop("l1");
const char *argv[] = {"ignore", "SPDLOG_LEVEL=l1=warn,trace"};
load_argv_levels(2, argv);
auto l1 = spdlog::create<test_sink_st>("l1");
REQUIRE(l1->level() == spdlog::level::warn);
REQUIRE(spdlog::default_logger()->level() == spdlog::level::trace);
auto levels = load_argv_levels(sizeof(argv)/sizeof (const char*), argv);
REQUIRE(levels == spdlog::cfg::level_map {
{"l1", spdlog::level::warn},
{"", spdlog::level::trace}
});
}
TEST_CASE("argv3", "[cfg]")
{
spdlog::set_level(spdlog::level::trace);
spdlog::drop("l1");
const char *argv[] = {"ignore", "SPDLOG_LEVEL=junk_name=warn"};
load_argv_levels(2, argv);
auto l1 = spdlog::create<test_sink_st>("l1");
REQUIRE(l1->level() == spdlog::level::trace);
REQUIRE(spdlog::default_logger()->level() == spdlog::level::trace);
auto levels= load_argv_levels(sizeof(argv)/sizeof (const char*), argv);
REQUIRE(levels == spdlog::cfg::level_map {{"junk_name", spdlog::level::warn}});
}
TEST_CASE("argv4", "[cfg]")
{
spdlog::set_level(spdlog::level::info);
spdlog::drop("l1");
const char *argv[] = {"ignore", "SPDLOG_LEVEL=junk"};
load_argv_levels(2, argv);
auto l1 = spdlog::create<test_sink_st>("l1");
REQUIRE(l1->level() == spdlog::level::info);
auto levels= load_argv_levels(sizeof(argv)/sizeof (const char*), argv);
REQUIRE(levels.empty());
}
TEST_CASE("argv5", "[cfg]")
{
spdlog::set_level(spdlog::level::info);
spdlog::drop("l1");
const char *argv[] = {"ignore", "ignore", "SPDLOG_LEVEL=l1=warn,trace"};
load_argv_levels(3, argv);
auto l1 = spdlog::create<test_sink_st>("l1");
REQUIRE(l1->level() == spdlog::level::warn);
REQUIRE(spdlog::default_logger()->level() == spdlog::level::trace);
spdlog::set_level(spdlog::level::info);
auto levels= load_argv_levels(sizeof(argv)/sizeof (const char*), argv);
REQUIRE(levels == spdlog::cfg::level_map {
{"l1", spdlog::level::warn},
{"", spdlog::level::trace}
});
}
TEST_CASE("argv6", "[cfg]")
{
spdlog::set_level(spdlog::level::err);
const char *argv[] = {""};
load_argv_levels(1, argv);
REQUIRE(spdlog::default_logger()->level() == spdlog::level::err);
spdlog::set_level(spdlog::level::info);
const char *argv[] = {"SPDLOG_LEVEL=info"};
auto levels= load_argv_levels(sizeof(argv)/sizeof (const char*), argv);
REQUIRE(levels.empty());
}
TEST_CASE("argv7", "[cfg]")
{
spdlog::set_level(spdlog::level::err);
const char *argv[] = {""};
load_argv_levels(0, argv);
REQUIRE(spdlog::default_logger()->level() == spdlog::level::err);
spdlog::set_level(spdlog::level::info);
}
TEST_CASE("level-not-set-test1", "[cfg]")
{
spdlog::drop("l1");
const char *argv[] = {"ignore", ""};
load_argv_levels(2, argv);
auto l1 = spdlog::create<spdlog::sinks::test_sink_st>("l1");
l1->set_level(spdlog::level::trace);
REQUIRE(l1->level() == spdlog::level::trace);
REQUIRE(spdlog::default_logger()->level() == spdlog::level::info);
auto levels= load_argv_levels(sizeof(argv)/sizeof (const char*), argv);
REQUIRE(levels.empty());
}
TEST_CASE("level-not-set-test2", "[cfg]")
TEST_CASE("argv8", "[cfg]")
{
spdlog::drop("l1");
spdlog::drop("l2");
const char *argv[] = {"ignore", "SPDLOG_LEVEL=l1=trace"};
auto l1 = spdlog::create<spdlog::sinks::test_sink_st>("l1");
l1->set_level(spdlog::level::warn);
auto l2 = spdlog::create<spdlog::sinks::test_sink_st>("l2");
l2->set_level(spdlog::level::warn);
const char *argv[] = {"ignore"};
auto levels= load_argv_levels(sizeof(argv)/sizeof (const char*), argv);
REQUIRE(levels.empty());
}
load_argv_levels(2, argv);
REQUIRE(l1->level() == spdlog::level::trace);
REQUIRE(l2->level() == spdlog::level::warn);
REQUIRE(spdlog::default_logger()->level() == spdlog::level::info);
TEST_CASE("argv9", "[cfg]")
{
const char *argv[] = {"ignore", "arg1"};
auto levels= load_argv_levels(sizeof(argv)/sizeof (const char*), argv);
REQUIRE(levels.empty());
}
TEST_CASE("level-not-set-test3", "[cfg]")
TEST_CASE("argv10", "[cfg]")
{
spdlog::drop("l1");
spdlog::drop("l2");
const char *argv[] = {"ignore", "SPDLOG_LEVEL=l1=trace"};
load_argv_levels(2, argv);
auto l1 = spdlog::create<spdlog::sinks::test_sink_st>("l1");
auto l2 = spdlog::create<spdlog::sinks::test_sink_st>("l2");
REQUIRE(l1->level() == spdlog::level::trace);
REQUIRE(l2->level() == spdlog::level::info);
REQUIRE(spdlog::default_logger()->level() == spdlog::level::info);
const char *argv[] = {"ignore", "junk", "SPDLOG_LEVEL=info"};
auto levels= load_argv_levels(sizeof(argv)/sizeof (const char*), argv);
REQUIRE(levels == spdlog::cfg::level_map {{"", spdlog::level::info}});
}
TEST_CASE("level-not-set-test4", "[cfg]")
TEST_CASE("argv11", "[cfg]")
{
spdlog::drop("l1");
spdlog::drop("l2");
const char *argv[] = {"ignore", "SPDLOG_LEVEL=l1=trace,warn"};
load_argv_levels(2, argv);
auto l1 = spdlog::create<spdlog::sinks::test_sink_st>("l1");
auto l2 = spdlog::create<spdlog::sinks::test_sink_st>("l2");
REQUIRE(l1->level() == spdlog::level::trace);
REQUIRE(l2->level() == spdlog::level::warn);
REQUIRE(spdlog::default_logger()->level() == spdlog::level::warn);
const char *argv[] = {};
auto levels= load_argv_levels(0, argv);
REQUIRE(levels.empty());
}
TEST_CASE("level-not-set-test5", "[cfg]")
TEST_CASE("argv12", "[cfg]")
{
spdlog::drop("l1");
spdlog::drop("l2");
const char *argv[] = {"ignore", "SPDLOG_LEVEL=l1=junk,warn"};
load_argv_levels(2, argv);
const char *argv[] = {"ignore", "junk", "SPDLOG_LEVEL=info,l1=debug,l2=warn,l3=off"};
auto levels= load_argv_levels(sizeof(argv)/sizeof (const char*), argv);
REQUIRE(levels == spdlog::cfg::level_map {
{"", spdlog::level::info},
{"l1", spdlog::level::debug},
{"l2", spdlog::level::warn},
{"l3", spdlog::level::off}
});
}
auto l1 = spdlog::create<spdlog::sinks::test_sink_st>("l1");
auto l2 = spdlog::create<spdlog::sinks::test_sink_st>("l2");
TEST_CASE("argv13", "[cfg]")
{
//test that only first SPDLOG_LEVEL is handled
const char *argv[] = {"ignore", "junk", "SPDLOG_LEVEL=info,l1=debug,l2=warn,l3=off", "SPDLOG_LEVEL=off"};
auto levels= load_argv_levels(sizeof(argv)/sizeof (const char*), argv);
REQUIRE(levels == spdlog::cfg::level_map {
{"", spdlog::level::info},
{"l1", spdlog::level::debug},
{"l2", spdlog::level::warn},
{"l3", spdlog::level::off}
});
}
REQUIRE(l1->level() == spdlog::level::warn);
REQUIRE(l2->level() == spdlog::level::warn);
REQUIRE(spdlog::default_logger()->level() == spdlog::level::warn);
TEST_CASE("argv14", "[cfg]")
{
//test that only first SPDLOG_LEVEL is handled
const char *argv[] = {"ignore", "SPDLOG_LEVEL="};
auto levels= load_argv_levels(sizeof(argv)/sizeof (const char*), argv);
REQUIRE(levels.empty());
}
TEST_CASE("restore-to-default", "[cfg]")
TEST_CASE("argv15", "[cfg]")
{
spdlog::drop("l1");
spdlog::drop("l2");
const char *argv[] = {"ignore", "SPDLOG_LEVEL=info"};
load_argv_levels(2, argv);
REQUIRE(spdlog::default_logger()->level() == spdlog::level::info);
//test that only first SPDLOG_LEVEL is handled
const char *argv[] = {"ignore", "SPDLOG_LEVEL=info,l1=junk,l2=debug"};
auto levels= load_argv_levels(sizeof(argv)/sizeof (const char*), argv);
REQUIRE(levels == spdlog::cfg::level_map {
{"", spdlog::level::info},
{"l2", spdlog::level::debug},
});
}

Loading…
Cancel
Save