mirror of https://github.com/mamba-org/mamba.git
inline ops, fixes, rebase fixes, type_id
This commit is contained in:
parent
11641d374e
commit
349de7a205
|
@ -8,11 +8,13 @@
|
||||||
#define MAMBA_CORE_LOGGING_HPP
|
#define MAMBA_CORE_LOGGING_HPP
|
||||||
|
|
||||||
#include <concepts>
|
#include <concepts>
|
||||||
|
#include <functional>
|
||||||
#include <optional>
|
#include <optional>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
#include <typeindex>
|
||||||
|
|
||||||
namespace mamba
|
namespace mamba
|
||||||
{
|
{
|
||||||
|
@ -78,8 +80,9 @@ namespace mamba
|
||||||
// implementation
|
// implementation
|
||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
concept LogHandler = std::equality_comparable<T> //
|
concept LogHandler = std::movable<T> // at a minimum it must be movable
|
||||||
&& requires(
|
and std::equality_comparable<T> // and comparable TODO: is this really necessary?
|
||||||
|
and requires(
|
||||||
T& handler,
|
T& handler,
|
||||||
const T& const_handler //
|
const T& const_handler //
|
||||||
,
|
,
|
||||||
|
@ -94,14 +97,14 @@ namespace mamba
|
||||||
handler.set_log_level(params.logging_level); //
|
handler.set_log_level(params.logging_level); //
|
||||||
handler.set_params(std::as_const(params)); //
|
handler.set_params(std::as_const(params)); //
|
||||||
handler.log(log_record); //
|
handler.log(log_record); //
|
||||||
handler.log_stacktrace(); // log stacktrace in all sources
|
handler.log_stacktrace(); // log stacktrace in all sources
|
||||||
handler.log_stacktrace(source); // log stacktrace only in
|
handler.log_stacktrace(source); // log stacktrace only in
|
||||||
// specific source
|
// specific source
|
||||||
handler.log_stacktrace_no_guards(); // log stacktrace in all
|
handler.log_stacktrace_no_guards(); // log stacktrace in all
|
||||||
// sources
|
// sources
|
||||||
handler.log_stacktrace_no_guards(source); // log stacktrace
|
handler.log_stacktrace_no_guards(source); // log stacktrace
|
||||||
// only in specific
|
// only in specific
|
||||||
// source
|
// source
|
||||||
handler.flush(); // flush all
|
handler.flush(); // flush all
|
||||||
handler.flush(std::optional<log_source>{}); // flush only a
|
handler.flush(std::optional<log_source>{}); // flush only a
|
||||||
// specific source
|
// specific source
|
||||||
|
@ -155,14 +158,15 @@ namespace mamba
|
||||||
return has_value();
|
return has_value();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// @returns An identifier for the stored object's type, or `std::nullopt` if there is no
|
||||||
|
/// stored object.
|
||||||
|
std::optional<std::type_index> type_id() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
struct Interface
|
struct Interface
|
||||||
{
|
{
|
||||||
virtual ~Interface() = 0;
|
virtual ~Interface() = 0;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -174,7 +178,7 @@ namespace mamba
|
||||||
-> AnyLogHandler;
|
-> AnyLogHandler;
|
||||||
|
|
||||||
// not thread-safe
|
// not thread-safe
|
||||||
auto get_log_handler() -> const AnyLogHandler&;
|
auto get_log_handler() -> AnyLogHandler&;
|
||||||
|
|
||||||
// thread-safe
|
// thread-safe
|
||||||
auto set_log_level(log_level new_level) -> log_level;
|
auto set_log_level(log_level new_level) -> log_level;
|
||||||
|
@ -188,16 +192,16 @@ namespace mamba
|
||||||
// thread-safe
|
// thread-safe
|
||||||
auto set_logging_params(LoggingParams new_params);
|
auto set_logging_params(LoggingParams new_params);
|
||||||
|
|
||||||
// as thread-safe as handler's implementation
|
// as thread-safe as handler's implementation if set
|
||||||
auto log(LogRecord record) noexcept -> void;
|
auto log(LogRecord record) noexcept -> void;
|
||||||
|
|
||||||
// as thread-safe as handler's implementation
|
// as thread-safe as handler's implementation if set
|
||||||
auto log_stacktrace(std::optional<log_source> source = {}) noexcept -> void;
|
auto log_stacktrace(std::optional<log_source> source = {}) noexcept -> void;
|
||||||
|
|
||||||
// as thread-safe as handler's implementation
|
// as thread-safe as handler's implementation if set
|
||||||
auto flush_logs(std::optional<log_source> source = {}) noexcept -> void;
|
auto flush_logs(std::optional<log_source> source = {}) noexcept -> void;
|
||||||
|
|
||||||
// as thread-safe as handler's implementation
|
// as thread-safe as handler's implementation if set
|
||||||
auto log_stacktrace_no_guards(std::optional<log_source> source = {}) noexcept -> void;
|
auto log_stacktrace_no_guards(std::optional<log_source> source = {}) noexcept -> void;
|
||||||
|
|
||||||
///////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////
|
||||||
|
@ -227,6 +231,48 @@ namespace mamba
|
||||||
static void emit(const std::string& msg, const log_level& level);
|
static void emit(const std::string& msg, const log_level& level);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////
|
||||||
|
//////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
// NOTE: the following definitions are inline to help with performance.
|
||||||
|
|
||||||
|
// TODO: find a better name?
|
||||||
|
template <typename Func, typename... Args>
|
||||||
|
requires std::invocable<Func, AnyLogHandler&, Args...>
|
||||||
|
auto call_log_handler_if_existing(Func&& func, Args&&... args) -> void
|
||||||
|
{
|
||||||
|
// TODO: consider enabling for user to specify that no check is needed (one less branch)
|
||||||
|
if (auto& log_handler = get_log_handler())
|
||||||
|
{
|
||||||
|
std::invoke(std::forward<Func>(func), log_handler, std::forward<Args>(args)...);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// as thread-safe as handler's implementation
|
||||||
|
inline auto log(LogRecord record) noexcept -> void
|
||||||
|
{
|
||||||
|
call_log_handler_if_existing(&AnyLogHandler::log, std::move(record));
|
||||||
|
}
|
||||||
|
|
||||||
|
// as thread-safe as handler's implementation
|
||||||
|
inline auto log_stacktrace(std::optional<log_source> source) noexcept -> void
|
||||||
|
{
|
||||||
|
call_log_handler_if_existing(&AnyLogHandler::log_stacktrace, std::move(source));
|
||||||
|
}
|
||||||
|
|
||||||
|
// as thread-safe as handler's implementation
|
||||||
|
inline auto flush_logs(std::optional<log_source> source) noexcept -> void
|
||||||
|
{
|
||||||
|
call_log_handler_if_existing(&AnyLogHandler::flush, std::move(source));
|
||||||
|
}
|
||||||
|
|
||||||
|
// as thread-safe as handler's implementation
|
||||||
|
inline auto log_stacktrace_no_guards(std::optional<log_source> source) noexcept -> void
|
||||||
|
{
|
||||||
|
call_log_handler_if_existing(&AnyLogHandler::log_stacktrace_no_guards, std::move(source));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -38,12 +38,13 @@ namespace mamba::logging
|
||||||
// require it with the documentation which should guide the implementers anyway.
|
// require it with the documentation which should guide the implementers anyway.
|
||||||
AnyLogHandler current_log_handler;
|
AnyLogHandler current_log_handler;
|
||||||
|
|
||||||
|
|
||||||
// FIXME: maybe generalize and move in synchronized_value.hpp
|
// FIXME: maybe generalize and move in synchronized_value.hpp
|
||||||
template<std::default_initializable T, typename U, typename... OtherArgs>
|
template <std::default_initializable T, typename U, typename... OtherArgs>
|
||||||
requires std::assignable_from<T&, U>
|
requires std::assignable_from<T&, U>
|
||||||
auto
|
auto synchronize_with_value(
|
||||||
synchronize_with_value(util::synchronized_value<T, OtherArgs...>& sv, const std::optional<U>& new_value)
|
util::synchronized_value<T, OtherArgs...>& sv,
|
||||||
|
const std::optional<U>& new_value
|
||||||
|
)
|
||||||
{
|
{
|
||||||
auto synched_value = sv.synchronize();
|
auto synched_value = sv.synchronize();
|
||||||
if (new_value)
|
if (new_value)
|
||||||
|
@ -54,7 +55,6 @@ namespace mamba::logging
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
auto set_log_handler(AnyLogHandler new_handler, std::optional<LoggingParams> maybe_params)
|
auto set_log_handler(AnyLogHandler new_handler, std::optional<LoggingParams> maybe_params)
|
||||||
-> AnyLogHandler
|
-> AnyLogHandler
|
||||||
{
|
{
|
||||||
|
@ -63,7 +63,6 @@ namespace mamba::logging
|
||||||
current_log_handler.stop_log_handling();
|
current_log_handler.stop_log_handling();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
auto previous_handler = std::exchange(current_log_handler, std::move(new_handler));
|
auto previous_handler = std::exchange(current_log_handler, std::move(new_handler));
|
||||||
|
|
||||||
auto params = synchronize_with_value(logging_params, maybe_params);
|
auto params = synchronize_with_value(logging_params, maybe_params);
|
||||||
|
@ -72,9 +71,11 @@ namespace mamba::logging
|
||||||
{
|
{
|
||||||
current_log_handler.start_log_handling(*params, all_log_sources());
|
current_log_handler.start_log_handling(*params, all_log_sources());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return previous_handler;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto get_log_handler() -> const AnyLogHandler&
|
auto get_log_handler() -> AnyLogHandler&
|
||||||
{
|
{
|
||||||
return current_log_handler;
|
return current_log_handler;
|
||||||
}
|
}
|
||||||
|
@ -84,7 +85,10 @@ namespace mamba::logging
|
||||||
auto synched_params = logging_params.synchronize();
|
auto synched_params = logging_params.synchronize();
|
||||||
const auto previous_level = synched_params->logging_level;
|
const auto previous_level = synched_params->logging_level;
|
||||||
synched_params->logging_level = new_level;
|
synched_params->logging_level = new_level;
|
||||||
current_log_handler.set_log_level(synched_params->logging_level);
|
if (current_log_handler)
|
||||||
|
{
|
||||||
|
current_log_handler.set_log_level(synched_params->logging_level);
|
||||||
|
}
|
||||||
return previous_level;
|
return previous_level;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -100,28 +104,14 @@ namespace mamba::logging
|
||||||
|
|
||||||
auto set_logging_params(LoggingParams new_params)
|
auto set_logging_params(LoggingParams new_params)
|
||||||
{
|
{
|
||||||
logging_params = std::move(new_params);
|
auto synched_params = logging_params.synchronize();
|
||||||
|
*synched_params = std::move(new_params);
|
||||||
|
if (current_log_handler)
|
||||||
|
{
|
||||||
|
current_log_handler.set_params(*synched_params);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
auto log(LogRecord record) noexcept -> void
|
|
||||||
{
|
|
||||||
current_log_handler.log(std::move(record));
|
|
||||||
}
|
|
||||||
|
|
||||||
auto log_stacktrace(std::optional<log_source> source) noexcept -> void
|
|
||||||
{
|
|
||||||
current_log_handler.log_stacktrace(std::move(source));
|
|
||||||
}
|
|
||||||
|
|
||||||
auto flush_logs(std::optional<log_source> source) noexcept -> void
|
|
||||||
{
|
|
||||||
current_log_handler.flush(std::move(source));
|
|
||||||
}
|
|
||||||
|
|
||||||
auto log_stacktrace_no_guards(std::optional<log_source> source) noexcept -> void
|
|
||||||
{
|
|
||||||
current_log_handler.log_stacktrace_no_guards(std::move(source));
|
|
||||||
}
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////
|
||||||
// AnyLogHandler
|
// AnyLogHandler
|
||||||
|
@ -133,12 +123,10 @@ namespace mamba::logging
|
||||||
///////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////
|
||||||
// MessageLogger
|
// MessageLogger
|
||||||
|
|
||||||
struct MessageLoggerData
|
static std::atomic<bool> message_logger_use_buffer;
|
||||||
{
|
|
||||||
static std::mutex m_mutex;
|
using MessageLoggerBuffer = std::vector<std::pair<std::string, log_level>>;
|
||||||
static bool use_buffer;
|
static util::synchronized_value<MessageLoggerBuffer> message_logger_buffer;
|
||||||
static std::vector<std::pair<std::string, log_level>> m_buffer;
|
|
||||||
};
|
|
||||||
|
|
||||||
MessageLogger::MessageLogger(log_level level)
|
MessageLogger::MessageLogger(log_level level)
|
||||||
: m_level(level)
|
: m_level(level)
|
||||||
|
@ -147,14 +135,13 @@ namespace mamba::logging
|
||||||
|
|
||||||
MessageLogger::~MessageLogger()
|
MessageLogger::~MessageLogger()
|
||||||
{
|
{
|
||||||
if (!MessageLoggerData::use_buffer && Console::is_available())
|
if (!message_logger_use_buffer && Console::is_available())
|
||||||
{
|
{
|
||||||
emit(m_stream.str(), m_level);
|
emit(m_stream.str(), m_level);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
const std::lock_guard<std::mutex> lock(MessageLoggerData::m_mutex);
|
message_logger_buffer->push_back({ m_stream.str(), m_level });
|
||||||
MessageLoggerData::m_buffer.push_back({ m_stream.str(), m_level });
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -178,22 +165,18 @@ namespace mamba::logging
|
||||||
|
|
||||||
void MessageLogger::activate_buffer()
|
void MessageLogger::activate_buffer()
|
||||||
{
|
{
|
||||||
MessageLoggerData::use_buffer = true;
|
message_logger_use_buffer = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MessageLogger::deactivate_buffer()
|
void MessageLogger::deactivate_buffer()
|
||||||
{
|
{
|
||||||
MessageLoggerData::use_buffer = false;
|
message_logger_use_buffer = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MessageLogger::print_buffer(std::ostream& /*ostream*/)
|
void MessageLogger::print_buffer(std::ostream& /*ostream*/)
|
||||||
{
|
{
|
||||||
decltype(MessageLoggerData::m_buffer) tmp;
|
MessageLoggerBuffer tmp;
|
||||||
|
message_logger_buffer->swap(tmp);
|
||||||
{
|
|
||||||
const std::lock_guard<std::mutex> lock(MessageLoggerData::m_mutex);
|
|
||||||
MessageLoggerData::m_buffer.swap(tmp);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (const auto& [msg, level] : tmp)
|
for (const auto& [msg, level] : tmp)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue