Skip to content

Commit

Permalink
use spdlog as logger backend
Browse files Browse the repository at this point in the history
split verbosity and log level
use backtrace to replay logs on critical error
use backtrace to replay logs emitted before setting the log level, with the appropriate level
make libmamba compile time log level a cmake option
break circular dependencies
remove hard-coded config loading sequence
  • Loading branch information
adriendelsalle committed Nov 5, 2021
1 parent 0f3901f commit 95e65b8
Show file tree
Hide file tree
Showing 25 changed files with 398 additions and 248 deletions.
9 changes: 9 additions & 0 deletions libmamba/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,15 @@ option(BUILD_TESTS "Build libmamba C++ tests" OFF)
option(BUILD_SHARED "Build shared libmamba library" OFF)
option(BUILD_STATIC "Build static libmamba library" OFF)
option(BUILD_STATIC_DEPS "Build static libmamba library with static linkage to its dependencies" OFF)
set(BUILD_LOG_LEVEL "TRACE" CACHE STRING "Logger active level at compile time")

if (NOT ${BUILD_LOG_LEVEL} MATCHES "^(TRACE|DEBUG|INFO|WARN|ERROR|CRITICAL|OFF)$")
message(FATAL_ERROR "Invalid log level: ${BUILD_LOG_LEVEL}, should be one of { TRACE, DEBUG, INFO, WARN, ERROR, CRITICAL, OFF }")
endif ()

if (BUILD_STATIC_DEPS)
add_definitions("-DSPDLOG_ACTIVE_LEVEL=SPDLOG_LEVEL_${BUILD_LOG_LEVEL}")
endif ()

if (BUILD_STATIC_DEPS)
add_definitions(-DLIBMAMBA_STATIC_DEPS)
Expand Down
1 change: 1 addition & 0 deletions libmamba/environment-dev.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,4 @@ dependencies:
- yaml-cpp
- termcolor-cpp
- cli11
- spdlog
143 changes: 130 additions & 13 deletions libmamba/include/mamba/api/configuration.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@

#include <yaml-cpp/yaml.h>

#include "spdlog/spdlog.h"

#include <functional>


Expand All @@ -28,7 +30,6 @@
#define CONFIG_DEBUGGING \
if (Configuration::instance().at("print_config_only").value<bool>()) \
{ \
Configuration::instance().at("quiet").set_value(true); \
int dump_opts \
= MAMBA_SHOW_CONFIG_VALUES | MAMBA_SHOW_CONFIG_SRCS | MAMBA_SHOW_ALL_CONFIGS; \
std::cout << Configuration::instance().dump(dump_opts) << std::endl; \
Expand Down Expand Up @@ -163,6 +164,35 @@ namespace YAML
return true;
}
};

template <>
struct convert<spdlog::level::level_enum>
{
static Node encode(const spdlog::level::level_enum& rhs)
{
using namespace spdlog::level;

return Node(to_string_view(rhs).data());
}

static bool decode(const Node& node, spdlog::level::level_enum& rhs)
{
using namespace spdlog::level;

auto name = node.as<std::string>();
auto it = std::find(std::begin(level_string_views), std::end(level_string_views), name);
if (it != std::end(level_string_views))
{
rhs = static_cast<level_enum>(it - std::begin(level_string_views));
return true;
}

LOG_ERROR
<< "Invalid log level, should be in {'critical', 'error', 'warning', 'info', 'debug', 'trace', 'off'} but is '"
<< name << "'";
return false;
}
};
}


Expand Down Expand Up @@ -348,6 +378,27 @@ namespace mamba
std::string m_value = "";
};

template <>
struct cli_config<spdlog::level::level_enum>
{
using value_type = spdlog::level::level_enum;
using storage_type = std::string;

cli_config(const storage_type& value)
: m_value(value){};

bool defined()
{
return !m_value.empty();
};
value_type value()
{
return YAML::Node(m_value).as<spdlog::level::level_enum>();
};

storage_type m_value = "";
};

bool has_config_name(const std::string& file);

bool is_config_file(const fs::path& path);
Expand Down Expand Up @@ -501,11 +552,66 @@ namespace mamba
enum class RCConfigLevel
{
kSystemDir = 0,
kRootPrefix = 1,
kHomeDir = 2,
kHomeDir = 1,
kRootPrefix = 2,
kTargetPrefix = 3
};
} // mamba

namespace YAML
{
template <>
struct convert<mamba::RCConfigLevel>
{
static Node encode(const mamba::RCConfigLevel& rhs)
{
using namespace spdlog::level;

switch (rhs)
{
case mamba::RCConfigLevel::kHomeDir:
return Node("HomeDir");
break;
case mamba::RCConfigLevel::kRootPrefix:
return Node("RootPrefix");
break;
case mamba::RCConfigLevel::kSystemDir:
return Node("SystemDir");
break;
case mamba::RCConfigLevel::kTargetPrefix:
return Node("TargetPrefix");
break;
default:
break;
}
return Node();
}

static bool decode(const Node& node, mamba::RCConfigLevel& rhs)
{
if (!node.IsScalar())
return false;

auto str = node.as<std::string>();

if (str == "HomeDir")
rhs = mamba::RCConfigLevel::kHomeDir;
else if (str == "RootPrefix")
rhs = mamba::RCConfigLevel::kRootPrefix;
else if (str == "SystemDir")
rhs = mamba::RCConfigLevel::kSystemDir;
else if (str == "TargetPrefix")
rhs = mamba::RCConfigLevel::kTargetPrefix;
else
return false;

return true;
}
};
} // YAML

namespace mamba
{
template <class T>
class Configurable
{
Expand Down Expand Up @@ -562,6 +668,8 @@ namespace mamba

bool configured() const;

bool env_var_active() const;

bool has_single_op_lifetime() const;

self_type& set_rc_value(const T& value, const std::string& source);
Expand Down Expand Up @@ -784,6 +892,12 @@ namespace mamba
return rc_configured() || env_var_configured() || cli_configured() || api_configured();
};

template <class T>
bool Configurable<T>::env_var_active() const
{
return !Context::instance().no_env || (name() == "no_env");
};

template <class T>
bool Configurable<T>::has_single_op_lifetime() const
{
Expand Down Expand Up @@ -898,14 +1012,12 @@ namespace mamba
auto Configurable<T>::set_env_var_names(const std::vector<std::string>& names) -> self_type&
{
if (names.empty())
{
m_env_var_names = { "MAMBA_" + to_upper(m_name) };
}
else
{
m_env_var_names = names;
}
m_needed_configs.insert("no_env");

if (name() != "no_env")
m_needed_configs.insert("no_env");

return *this;
}
Expand Down Expand Up @@ -1421,7 +1533,7 @@ namespace mamba
}
catch (const std::bad_cast& e)
{
LOG_FATAL << "Bad cast of Configurable '" << name() << "'";
LOG_CRITICAL << "Bad cast of Configurable '" << name() << "'";
throw e;
}
};
Expand Down Expand Up @@ -1800,6 +1912,11 @@ namespace mamba
bool hook_disabled = options & MAMBA_CONF_DISABLE_HOOK;
bool force_compute = options & MAMBA_CONF_FORCE_COMPUTE;

if (force_compute)
LOG_TRACE << "Update configurable '" << name() << "'";
else
LOG_TRACE << "Compute configurable '" << name() << "'";

if (!force_compute && (Configuration::instance().is_loading() && (m_compute_counter > 0)))
throw std::runtime_error("Multiple computation of '" + m_name
+ "' detected during loading sequence.");
Expand All @@ -1820,7 +1937,7 @@ namespace mamba
m_values.insert({ "CLI", p_cli_config->value() });
}

if (env_var_configured() && !ctx.no_env && (level >= ConfigurationLevel::kEnvVar))
if (env_var_configured() && env_var_active() && (level >= ConfigurationLevel::kEnvVar))
{
for (const auto& env_var : m_env_var_names)
{
Expand All @@ -1834,9 +1951,9 @@ namespace mamba
}
catch (const YAML::Exception& e)
{
LOG_ERROR << "Bad conversion of configurable '" << name()
<< "' from environment variable '" << env_var << "' with value '"
<< env_var_value << "'";
LOG_CRITICAL << "Bad conversion of configurable '" << name()
<< "' from environment variable '" << env_var
<< "' with value '" << env_var_value << "'";
throw e;
}
}
Expand Down
16 changes: 11 additions & 5 deletions libmamba/include/mamba/core/context.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,14 @@
#ifndef MAMBA_CORE_CONTEXT_HPP
#define MAMBA_CORE_CONTEXT_HPP

#include "mamba/core/mamba_fs.hpp"

#include "spdlog/spdlog.h"

#include <map>
#include <string>
#include <vector>

#include "mamba/core/mamba_fs.hpp"

#define ROOT_ENV_NAME "base"

namespace mamba
Expand Down Expand Up @@ -86,6 +88,7 @@ namespace mamba
kStrict
};

class Logger;

std::string env_name(const fs::path& prefix);
fs::path locate_prefix_by_name(const std::string& name);
Expand Down Expand Up @@ -118,7 +121,6 @@ namespace mamba
#endif
};


bool use_index_cache = false;
std::size_t local_repodata_ttl = 1; // take from header
bool offline = false;
Expand All @@ -129,6 +131,12 @@ namespace mamba

long max_parallel_downloads = 5;
int verbosity = 0;
void set_verbosity(int lvl);

spdlog::level::level_enum log_level = spdlog::level::level_enum::info;
std::string log_pattern = "%^%-8!l%$ %v";
std::size_t log_backtrace = 20;
std::shared_ptr<Logger> logger;

bool dev = false;
bool on_ci = false;
Expand Down Expand Up @@ -180,8 +188,6 @@ namespace mamba
// Conda compat
bool add_pip_as_python_dependency = true;

void set_verbosity(int lvl);

std::string host_platform = MAMBA_PLATFORM;
std::string platform = MAMBA_PLATFORM;
std::vector<std::string> platforms();
Expand Down
Loading

0 comments on commit 95e65b8

Please sign in to comment.