Skip to content

Commit

Permalink
ENV LEVELS
Browse files Browse the repository at this point in the history
  • Loading branch information
pwojcikdev committed Jan 17, 2024
1 parent 82fb0b1 commit e51975f
Show file tree
Hide file tree
Showing 6 changed files with 97 additions and 18 deletions.
82 changes: 74 additions & 8 deletions nano/lib/logging.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -269,22 +269,32 @@ spdlog::level::level_enum nano::to_spdlog_level (nano::log::level level)

nano::log_config nano::log_config::cli_default ()
{
log_config config;
log_config config{};
config.default_level = nano::log::level::critical;
config.console.to_cerr = true; // Use cerr to avoid interference with CLI output that goes to stdout
config.file.enable = false;
return config;
}

nano::log_config nano::log_config::daemon_default ()
{
log_config config;
log_config config{};
config.default_level = nano::log::level::info;
return config;
}

nano::log_config nano::log_config::tests_default ()
{
log_config config;
config.default_level = nano::log::level::critical;
log_config config{};
config.default_level = nano::log::level::off;
return config;
}

nano::log_config nano::log_config::sample_config ()
{
log_config config{};
config.default_level = nano::log::level::info;
config.levels = default_levels (nano::log::level::info); // Populate with default levels
return config;
}

Expand Down Expand Up @@ -349,7 +359,7 @@ void nano::log_config::deserialize (nano::tomlconfig & toml)
if (toml.has_key ("default_level"))
{
auto default_level_l = toml.get<std::string> ("default_level");
default_level = nano::log::to_level (default_level_l);
default_level = nano::log::parse_level (default_level_l);
}

if (toml.has_key ("console"))
Expand All @@ -376,7 +386,7 @@ void nano::log_config::deserialize (nano::tomlconfig & toml)
try
{
auto & [name_str, level_str] = level;
auto logger_level = nano::log::to_level (level_str);
auto logger_level = nano::log::parse_level (level_str);
auto logger_id = parse_logger_id (name_str);

levels[logger_id] = logger_level;
Expand All @@ -399,14 +409,14 @@ nano::log_config::logger_id_t nano::log_config::parse_logger_id (const std::stri
auto pos = logger_name.find ("::");
if (pos == std::string::npos)
{
return { nano::log::to_type (logger_name), nano::log::detail::all };
return { nano::log::parse_type (logger_name), nano::log::detail::all };
}
else
{
auto logger_type = logger_name.substr (0, pos);
auto logger_detail = logger_name.substr (pos + 1);

return { nano::log::to_type (logger_type), nano::log::to_detail (logger_detail) };
return { nano::log::parse_type (logger_type), nano::log::parse_detail (logger_detail) };
}
}

Expand All @@ -430,6 +440,62 @@ nano::log_config nano::load_log_config (nano::log_config fallback, const std::fi
try
{
auto config = nano::load_config_file<nano::log_config> (fallback, config_filename, data_path, config_overrides);

// Parse default log level from environment variable, e.g. "NANO_LOG=debug"
auto env_level = nano::get_env ("NANO_LOG");
if (env_level)
{
try
{
config.default_level = nano::log::parse_level (*env_level);

std::cerr << "Using default log level from NANO_LOG environment variable: " << *env_level << std::endl;
}
catch (std::invalid_argument const & ex)
{
std::cerr << "Invalid log level from NANO_LOG environment variable: " << ex.what () << std::endl;
}
}

// Parse per logger levels from environment variable, e.g. "NANO_LOG_LEVELS=ledger=debug,node=trace"
auto env_levels = nano::get_env ("NANO_LOG_LEVELS");
if (env_levels)
{
std::map<nano::log_config::logger_id_t, nano::log::level> levels;
for (auto const & env_level_str : nano::util::split (*env_levels, ','))
{
try
{
// Split 'logger_name=level' into a pair of 'logger_name' and 'level'
auto arr = nano::util::split (env_level_str, '=');
if (arr.size () != 2)
{
throw std::invalid_argument ("Invalid entry: " + env_level_str);
}

auto name_str = arr[0];
auto level_str = arr[1];

auto logger_id = nano::log_config::parse_logger_id (name_str);
auto logger_level = nano::log::parse_level (level_str);

levels[logger_id] = logger_level;

std::cerr << "Using logger log level from NANO_LOG_LEVELS environment variable: " << name_str << "=" << level_str << std::endl;
}
catch (std::invalid_argument const & ex)
{
std::cerr << "Invalid log level from NANO_LOG_LEVELS environment variable: " << ex.what () << std::endl;
}
}

// Merge with existing levels
for (auto const & [logger_id, level] : levels)
{
config.levels[logger_id] = level;
}
}

return config;
}
catch (std::runtime_error const & ex)
Expand Down
7 changes: 4 additions & 3 deletions nano/lib/logging.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ class log_config final
nano::log::level flush_level{ nano::log::level::error };

using logger_id_t = std::pair<nano::log::type, nano::log::detail>;
std::map<logger_id_t, nano::log::level> levels{ default_levels (default_level) };
std::map<logger_id_t, nano::log::level> levels;

struct console_config
{
Expand All @@ -50,10 +50,11 @@ class log_config final
static log_config cli_default ();
static log_config daemon_default ();
static log_config tests_default ();
static log_config sample_config (); // For auto-generated sample config files

private:
logger_id_t parse_logger_id (std::string const &);
static logger_id_t parse_logger_id (std::string const &);

private:
/// Returns placeholder log levels for all loggers
static std::map<logger_id_t, nano::log::level> default_levels (nano::log::level);
};
Expand Down
6 changes: 3 additions & 3 deletions nano/lib/logging_enums.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ const std::vector<nano::log::type> & nano::log::all_types ()
return all;
}

nano::log::level nano::log::to_level (std::string_view name)
nano::log::level nano::log::parse_level (std::string_view name)
{
auto value = magic_enum::enum_cast<nano::log::level> (name);
if (value.has_value ())
Expand All @@ -64,7 +64,7 @@ nano::log::level nano::log::to_level (std::string_view name)
}
}

nano::log::type nano::log::to_type (std::string_view name)
nano::log::type nano::log::parse_type (std::string_view name)
{
auto value = magic_enum::enum_cast<nano::log::type> (name);
if (value.has_value ())
Expand All @@ -77,7 +77,7 @@ nano::log::type nano::log::to_type (std::string_view name)
}
}

nano::log::detail nano::log::to_detail (std::string_view name)
nano::log::detail nano::log::parse_detail (std::string_view name)
{
auto value = magic_enum::enum_cast<nano::log::detail> (name);
if (value.has_value ())
Expand Down
6 changes: 3 additions & 3 deletions nano/lib/logging_enums.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -128,13 +128,13 @@ std::string_view to_string (nano::log::detail);
std::string_view to_string (nano::log::level);

/// @throw std::invalid_argument if the input string does not match a log::level
nano::log::level to_level (std::string_view);
nano::log::level parse_level (std::string_view);

/// @throw std::invalid_argument if the input string does not match a log::type
nano::log::type to_type (std::string_view);
nano::log::type parse_type (std::string_view);

/// @throw std::invalid_argument if the input string does not match a log::detail
nano::log::detail to_detail (std::string_view);
nano::log::detail parse_detail (std::string_view);

std::vector<nano::log::level> const & all_levels ();
std::vector<nano::log::type> const & all_types ();
Expand Down
12 changes: 12 additions & 0 deletions nano/lib/utility.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -245,6 +245,18 @@ std::string join (Container const & container, std::string_view delimiter, Func
return join (container.begin (), container.end (), delimiter, transform);
}

inline std::vector<std::string> split (const std::string & str, char delimiter)
{
std::stringstream ss{ str };
std::vector<std::string> result;
std::string item;
while (std::getline (ss, item, delimiter))
{
result.push_back (item);
}
return result;
}

template <class T>
std::string to_str (T const & val)
{
Expand Down
2 changes: 1 addition & 1 deletion nano/node/cli.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -674,7 +674,7 @@ std::error_code nano::handle_node_options (boost::program_options::variables_map
else if (type == "log")
{
valid_type = true;
nano::log_config config{ nano::log_config::daemon_default () };
nano::log_config config = nano::log_config::sample_config ();
config.serialize_toml (toml);
}
else if (type == "tls")
Expand Down

0 comments on commit e51975f

Please sign in to comment.