Skip to content

Commit

Permalink
Bugfix
Browse files Browse the repository at this point in the history
  • Loading branch information
robomics committed Nov 7, 2024
1 parent 66efea2 commit cec303a
Showing 1 changed file with 60 additions and 24 deletions.
84 changes: 60 additions & 24 deletions src/hictk/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
#include <deque>
#include <memory>
#include <mutex>
#include <string_view>
#include <tuple>
#include <utility>
#include <variant>
Expand All @@ -28,8 +29,8 @@ using namespace hictk::tools;

template <std::size_t CAPACITY>
class GlobalLogger {
// [2021-08-12 17:49:34.581] [info]: my log msg
static constexpr auto *_msg_pattern{"[%Y-%m-%d %T.%e] %^[%l]%$: %v"};
// [2021-08-12 17:49:34.581] [info]: my log msg
static constexpr std::string_view _msg_pattern{"[%Y-%m-%d %T.%e] %^[%l]%$: %v"};
using HictkLogMsg = std::pair<spdlog::level::level_enum, std::string>;
std::deque<HictkLogMsg> _msg_buffer{};

Expand All @@ -39,7 +40,7 @@ class GlobalLogger {

[[nodiscard]] static std::shared_ptr<spdlog::sinks::stderr_color_sink_mt> init_stderr_sink() {
auto stderr_sink = std::make_shared<spdlog::sinks::stderr_color_sink_mt>();
stderr_sink->set_pattern(_msg_pattern);
stderr_sink->set_pattern(std::string{_msg_pattern});
stderr_sink->set_level(spdlog::level::debug);

return stderr_sink;
Expand All @@ -49,7 +50,7 @@ class GlobalLogger {
if constexpr (CAPACITY != 0 && SPDLOG_ACTIVE_LEVEL <= SPDLOG_LEVEL_WARN) {
auto callback_sink = std::make_shared<spdlog::sinks::callback_sink_mt>(
[this](const spdlog::details::log_msg &msg) noexcept { enqueue_msg(msg); });
callback_sink->set_pattern(_msg_pattern);
callback_sink->set_pattern(std::string{_msg_pattern});
callback_sink->set_level(spdlog::level::warn);

return callback_sink;
Expand All @@ -68,15 +69,15 @@ class GlobalLogger {
}

Check warning on line 69 in src/hictk/main.cpp

View check run for this annotation

Codecov / codecov/patch

src/hictk/main.cpp#L63-L69

Added lines #L63 - L69 were not covered by tests

void enqueue_msg(const spdlog::details::log_msg &msg) noexcept {
if (msg.level < spdlog::level::warn) [[likely]] {
if (msg.level < spdlog::level::warn) {
return;
}

Check warning on line 74 in src/hictk/main.cpp

View check run for this annotation

Codecov / codecov/patch

src/hictk/main.cpp#L73-L74

Added lines #L73 - L74 were not covered by tests

++_num_msg_enqueued;

try {
[[maybe_unused]] const std::scoped_lock lck(_mtx);
if (_msg_buffer.size() == CAPACITY) [[unlikely]] {
if (_msg_buffer.size() == CAPACITY) {
_msg_buffer.pop_front();
}

Check warning on line 82 in src/hictk/main.cpp

View check run for this annotation

Codecov / codecov/patch

src/hictk/main.cpp#L81-L82

Added lines #L81 - L82 were not covered by tests
_msg_buffer.emplace_back(msg.level, std::string{msg.payload.begin(), msg.payload.end()});
Expand Down Expand Up @@ -108,6 +109,14 @@ class GlobalLogger {
_msg_buffer.clear();
}

static void reset_logger() noexcept {
try {
spdlog::set_default_logger(
std::make_shared<spdlog::logger>("main_logger", init_stderr_sink()));
} catch (...) { // NOLINT
}

Check warning on line 117 in src/hictk/main.cpp

View check run for this annotation

Codecov / codecov/patch

src/hictk/main.cpp#L117

Added line #L117 was not covered by tests
}

public:
GlobalLogger() noexcept {
try {
Expand All @@ -122,13 +131,34 @@ class GlobalLogger {
}

GlobalLogger(const GlobalLogger &other) = delete;
GlobalLogger(GlobalLogger &&other) noexcept = default;
GlobalLogger(GlobalLogger &&other) noexcept
: _msg_buffer(std::move(other._msg_buffer)),
_num_msg_enqueued(other._num_msg_enqueued.load()),
_ok(other._ok.load()) {
other._num_msg_enqueued = 0;
other._ok = false;
}

GlobalLogger &operator=(const GlobalLogger &other) = delete;
GlobalLogger &operator=(GlobalLogger &&other) noexcept = default;
GlobalLogger &operator=(GlobalLogger &&other) noexcept {
if (this == &other) {
return *this;
}

[[maybe_unused]] const auto lck = std::scoped_lock(other._mtx);
_msg_buffer = std::move(other._msg_buffer);
_num_msg_enqueued = other._num_msg_enqueued.load();
_ok = other._ok.load();

other._num_msg_enqueued = 0;
other._ok = false;

return *this;
}

~GlobalLogger() noexcept {
if (!_ok) {
reset_logger();
return;
}

Check warning on line 163 in src/hictk/main.cpp

View check run for this annotation

Codecov / codecov/patch

src/hictk/main.cpp#L161-L163

Added lines #L161 - L163 were not covered by tests

Expand All @@ -139,6 +169,7 @@ class GlobalLogger {
} catch (...) {
print_noexcept(FMT_STRING("FAILURE! Failed to replay hictk warnings: unknown error"));
}

Check warning on line 171 in src/hictk/main.cpp

View check run for this annotation

Codecov / codecov/patch

src/hictk/main.cpp#L168-L171

Added lines #L168 - L171 were not covered by tests
reset_logger();
}

static void set_level(int lvl) {
Expand Down Expand Up @@ -166,23 +197,25 @@ class GlobalLogger {
}
};

// NOLINTNEXTLINE(*-err58-cpp, *-avoid-non-const-global-variables)
// NOLINTNEXTLINE(*-err58-cpp, *-avoid-non-const-global-variables, *-avoid-magic-numbers)
static auto global_logger = std::make_unique<GlobalLogger<256>>();

static auto acquire_global_logger() noexcept { return std::move(global_logger); }

static std::tuple<int, Cli::subcommand, Config> parse_cli_and_setup_logger(Cli &cli) {
template <typename Logger>
static std::tuple<int, Cli::subcommand, Config> parse_cli_and_setup_logger(Cli &cli,
Logger &logger) {
try {
auto config = cli.parse_arguments();
const auto subcmd = cli.get_subcommand();
std::visit(
[&](const auto &config_) {
using T = hictk::remove_cvref_t<decltype(config_)>;
if constexpr (!std::is_same_v<T, std::monostate>) {
if (global_logger && global_logger->ok()) {
global_logger->set_level(config_.verbosity); // NOLINT
if (logger.ok()) {
logger.set_level(config_.verbosity); // NOLINT
if (subcmd != Cli::subcommand::help && subcmd != Cli::subcommand::dump) {
global_logger->print_welcome_msg();
logger.print_welcome_msg();
}
}
}
Expand Down Expand Up @@ -217,7 +250,7 @@ int main(int argc, char **argv) noexcept {

auto local_logger = acquire_global_logger();
cli = std::make_unique<Cli>(argc, argv);
const auto [ec, subcmd, config] = parse_cli_and_setup_logger(*cli);
const auto [ec, subcmd, config] = parse_cli_and_setup_logger(*cli, *local_logger);
if (ec != 0 || subcmd == Cli::subcommand::help) {
local_logger->clear();
return ec;
Expand Down Expand Up @@ -265,23 +298,26 @@ int main(int argc, char **argv) noexcept {
assert(cli);
return cli->exit(e); // This takes care of formatting and printing error messages (if any)
} catch (const std::bad_alloc &err) {
fmt::print(stderr, FMT_STRING("FAILURE! Unable to allocate enough memory: {}\n"), err.what());
SPDLOG_CRITICAL(FMT_STRING("FAILURE! Unable to allocate enough memory: {}"), err.what());

Check warning on line 301 in src/hictk/main.cpp

View check run for this annotation

Codecov / codecov/patch

src/hictk/main.cpp#L300-L301

Added lines #L300 - L301 were not covered by tests
return 1;
} catch (const spdlog::spdlog_ex &e) {
fmt::print(stderr,
FMT_STRING("FAILURE! hictk encountered the following error while logging: {}\n"),
e.what());
return 1;

Check warning on line 307 in src/hictk/main.cpp

View check run for this annotation

Codecov / codecov/patch

src/hictk/main.cpp#L303-L307

Added lines #L303 - L307 were not covered by tests
} catch (const std::exception &e) {
if (cli) {
fmt::print(stderr, FMT_STRING("FAILURE! hictk {} encountered the following error: {}\n"),
cli->get_printable_subcommand(), e.what());
SPDLOG_CRITICAL(FMT_STRING("FAILURE! hictk {} encountered the following error: {}"),
cli->get_printable_subcommand(), e.what());
} else {
fmt::print(stderr, FMT_STRING("FAILURE! hictk encountered the following error: {}\n"),
e.what());
SPDLOG_CRITICAL(FMT_STRING("FAILURE! hictk encountered the following error: {}"), e.what());

Check warning on line 313 in src/hictk/main.cpp

View check run for this annotation

Codecov / codecov/patch

src/hictk/main.cpp#L313

Added line #L313 was not covered by tests
}
return 1;
} catch (...) {
fmt::print(stderr,
FMT_STRING("FAILURE! hictk {} encountered the following error: Caught an "
"unhandled exception! "
"If you see this message, please file an issue on GitHub.\n"),
cli->get_printable_subcommand());
SPDLOG_CRITICAL(FMT_STRING("FAILURE! hictk {} encountered the following error: Caught an "
"unhandled exception! "
"If you see this message, please file an issue on GitHub."),
cli->get_printable_subcommand());

Check warning on line 320 in src/hictk/main.cpp

View check run for this annotation

Codecov / codecov/patch

src/hictk/main.cpp#L317-L320

Added lines #L317 - L320 were not covered by tests
return 1;
}
return 0;
Expand Down

0 comments on commit cec303a

Please sign in to comment.