Skip to content

Commit

Permalink
Error handler
Browse files Browse the repository at this point in the history
  • Loading branch information
gabime committed Jan 4, 2025
1 parent 9df63ce commit 3153f22
Show file tree
Hide file tree
Showing 10 changed files with 105 additions and 127 deletions.
4 changes: 2 additions & 2 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,7 @@ set(SPDLOG_HEADERS
"include/spdlog/details/mpmc_blocking_q.h"
"include/spdlog/details/null_mutex.h"
"include/spdlog/details/os.h"
"include/spdlog/details/error_handler.h"
"include/spdlog/details/default_err_handler.h"
"include/spdlog/bin_to_hex.h"
"include/spdlog/sinks/android_sink.h"
"include/spdlog/sinks/base_sink.h"
Expand Down Expand Up @@ -192,7 +192,7 @@ set(SPDLOG_SRCS
"src/details/os_filesystem.cpp"
"src/details/log_msg.cpp"
"src/details/async_log_msg.cpp"
"src/details/error_handler.cpp"
"src/details/default_err_handler.cpp"
"src/sinks/base_sink.cpp"
"src/sinks/basic_file_sink.cpp"
"src/sinks/rotating_file_sink.cpp"
Expand Down
19 changes: 19 additions & 0 deletions include/spdlog/details/default_err_handler.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
// Copyright(c) 2015-present, Gabi Melman & spdlog contributors.
// Distributed under the MIT License (http://opensource.org/licenses/MIT)

#pragma once

#include <string>
#include "spdlog/common.h"

// by default, prints the error to stderr, thread safe
namespace spdlog {
namespace details {
class default_err_handler {
mutable std::mutex mutex_;
public:
void handle(const std::string& origin, const source_loc& loc, const std::string &err_msg) const;
};


}} // namespace spdlog::details
33 changes: 0 additions & 33 deletions include/spdlog/details/error_handler.h

This file was deleted.

27 changes: 16 additions & 11 deletions include/spdlog/logger.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,11 @@

#pragma once

// Thread safe logger (except for set_error_handler())
// Thread safe logger, Except for the following methods which are not thread-safe:
// set_pattern()
// set_formatter()
// set_error_handler()
// sinks() non const version
// Has name, log level, vector of std::shared sink pointers and formatter
// Upon each log write the logger:
// 1. Checks if its log level is enough to log the message and if yes:
Expand All @@ -19,8 +23,8 @@
#include <vector>

#include "common.h"
#include "details/default_err_handler.h"
#include "details/log_msg.h"
#include "details/error_handler.h"
#include "sinks/sink.h"

namespace spdlog {
Expand All @@ -29,15 +33,13 @@ class SPDLOG_API logger {
public:
// Empty logger
explicit logger(std::string name)
: name_(name),
err_handler_(std::move(name)) {}
: name_(name) {}

// Logger with range on sinks
template <typename It>
logger(std::string name, It begin, It end)
: name_(name),
sinks_(begin, end),
err_handler_(std::move(name)) {}
sinks_(begin, end) {}

// Logger with single sink
logger(std::string name, sink_ptr single_sink)
Expand Down Expand Up @@ -165,7 +167,8 @@ class SPDLOG_API logger {
std::vector<sink_ptr> sinks_;
atomic_level_t level_{level::info};
atomic_level_t flush_level_{level::off};
details::error_handler err_handler_;
err_handler custom_err_handler_;
details::default_err_handler default_err_handler_;

// common implementation for after templated public api has been resolved to format string and
// args
Expand All @@ -178,10 +181,10 @@ class SPDLOG_API logger {
sink_it_(details::log_msg(loc, name_, lvl, string_view_t(buf.data(), buf.size())));
}
catch (const std::exception &ex) { \
err_handler_.handle(loc, ex.what()); \
handle_error_(loc, ex.what()); \
} \
catch (...) { \
err_handler_.handle(loc, "Unknown exception"); \
handle_error_(loc, "Unknown exception"); \
}
}

Expand All @@ -194,10 +197,10 @@ class SPDLOG_API logger {
sink->log(msg);
}
catch (const std::exception &ex) { \
err_handler_.handle(msg.source, ex.what()); \
handle_error_(msg.source, ex.what()); \
} \
catch (...) { \
err_handler_.handle(msg.source, "Unknown exception"); \
handle_error_(msg.source, "Unknown exception"); \
}
}
}
Expand All @@ -208,6 +211,8 @@ class SPDLOG_API logger {
}
void flush_();
[[nodiscard]] bool should_flush_(const details::log_msg &msg) const;

void handle_error_(const source_loc& loc, const std::string &err_msg) const;
};

} // namespace spdlog
4 changes: 2 additions & 2 deletions include/spdlog/sinks/async_sink.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
#include <vector>

#include "../details/async_log_msg.h"
#include "../details/error_handler.h"
#include "../details/default_err_handler.h"
#include "sink.h"

// async_sink is a sink that sends log messages to a dist_sink in a separate thread using a queue.
Expand Down Expand Up @@ -78,7 +78,7 @@ class SPDLOG_API async_sink final : public sink {
config config_;
std::unique_ptr<queue_t> q_;
std::thread worker_thread_;
details::error_handler err_handler_;
details::default_err_handler err_handler_;
};

} // namespace sinks
Expand Down
27 changes: 27 additions & 0 deletions src/details/default_err_handler.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
// Copyright(c) 2015-present, Gabi Melman & spdlog contributors.
// Distributed under the MIT License (http://opensource.org/licenses/MIT)

#include "iostream"
#include "spdlog/details/default_err_handler.h"
#include "spdlog/details/os.h"

namespace spdlog {
namespace details {

void default_err_handler::handle(const std::string &origin, const source_loc &loc, const std::string &err_msg) const {
std::lock_guard lk{mutex_};
const auto tm_time = os::localtime();
char date_buf[128];
std::strftime(date_buf, sizeof(date_buf), "%Y-%m-%d %H:%M:%S", &tm_time);
std::string msg;
if (loc.empty()) {
msg = fmt_lib::format("[*** LOGGING ERROR ***] [{}] [{}] {}\n", date_buf, origin, err_msg);
}
else {
msg = fmt_lib::format("[*** LOGGING ERROR ***] [{}({})] [{}] [{}] {}\n", loc.filename, loc.line, date_buf, origin, err_msg);
}
std::fputs(msg.c_str(), stderr);
}

} // namespace details
} // namespace spdlog
55 changes: 0 additions & 55 deletions src/details/error_handler.cpp

This file was deleted.

20 changes: 13 additions & 7 deletions src/logger.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
// Distributed under the MIT License (http://opensource.org/licenses/MIT)

#include "spdlog/logger.h"
#include <cstdio>

#include "spdlog/pattern_formatter.h"
#include "spdlog/sinks/sink.h"
Expand All @@ -15,14 +14,14 @@ logger::logger(const logger &other) noexcept
sinks_(other.sinks_),
level_(other.level_.load(std::memory_order_relaxed)),
flush_level_(other.flush_level_.load(std::memory_order_relaxed)),
err_handler_(other.err_handler_) {}
custom_err_handler_(other.custom_err_handler_) {}

logger::logger(logger &&other) noexcept
: name_(std::move(other.name_)),
sinks_(std::move(other.sinks_)),
level_(other.level_.load(std::memory_order_relaxed)),
flush_level_(other.flush_level_.load(std::memory_order_relaxed)),
err_handler_(std::move(other.err_handler_)) {}
custom_err_handler_(std::move(other.custom_err_handler_)) {}

void logger::set_level(level level) { level_.store(level); }

Expand Down Expand Up @@ -62,14 +61,13 @@ std::vector<sink_ptr> &logger::sinks() { return sinks_; }

// custom error handler
void logger::set_error_handler(err_handler handler) {
err_handler_.set_custom_handler(std::move(handler));
custom_err_handler_ = std::move(handler);
}

// create new logger with same sinks and configuration.
std::shared_ptr<logger> logger::clone(std::string logger_name) {
auto cloned = std::make_shared<logger>(*this);
cloned->name_ = std::move(logger_name);
cloned->err_handler_.set_name(cloned->name_);
return cloned;
}

Expand All @@ -80,10 +78,10 @@ void logger::flush_() {
sink->flush();
}
catch (const std::exception &ex) { \
err_handler_.handle(source_loc{}, ex.what()); \
handle_error_(source_loc{}, ex.what()); \
} \
catch (...) { \
err_handler_.handle(source_loc{}, "Unknown exception"); \
handle_error_(source_loc{}, "Unknown exception"); \
}
}
}
Expand All @@ -93,4 +91,12 @@ bool logger::should_flush_(const details::log_msg &msg) const {
return (msg.log_level >= flush_level) && (msg.log_level != level::off);
}

void logger::handle_error_(const source_loc &loc, const std::string &err_msg) const {
if (custom_err_handler_) {
custom_err_handler_(err_msg);
return;
}
default_err_handler_.handle(name_, loc, err_msg);
}

} // namespace spdlog
8 changes: 4 additions & 4 deletions src/sinks/async_sink.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ namespace spdlog {
namespace sinks {

async_sink::async_sink(config async_config)
: config_(std::move(async_config)), err_handler_("async_sink") {
: config_(std::move(async_config)) {
if (config_.queue_size == 0 || config_.queue_size > max_queue_size) {
throw spdlog_ex("async_sink: invalid queue size");
}
Expand Down Expand Up @@ -107,7 +107,7 @@ void async_sink::backend_log_(const details::log_msg &msg) {
try {
sink->log(msg);
} catch (const std::exception &ex) {
err_handler_.handle(msg.source, std::string("async log failed: ") + ex.what());
err_handler_.handle("async", msg.source, std::string("async log failed: ") + ex.what());
}
}
}
Expand All @@ -118,9 +118,9 @@ void async_sink::backend_flush_() {
try {
sink->flush();
} catch (const std::exception &ex) {
err_handler_.handle(source_loc{}, std::string("async flush failed: ") + ex.what());
err_handler_.handle("async", source_loc{}, std::string("async flush failed: ") + ex.what());
} catch (...) {
err_handler_.handle(source_loc{}, "Async flush failed with unknown exception");
err_handler_.handle("async", source_loc{}, "Async flush failed with unknown exception");
}
}
}
Expand Down
Loading

0 comments on commit 3153f22

Please sign in to comment.