Skip to content

Commit

Permalink
Add support for a callback
Browse files Browse the repository at this point in the history
  • Loading branch information
vyasr committed Dec 11, 2024
1 parent 2e005f9 commit da934ca
Show file tree
Hide file tree
Showing 2 changed files with 54 additions and 0 deletions.
10 changes: 10 additions & 0 deletions logger.hpp.in
Original file line number Diff line number Diff line change
Expand Up @@ -424,6 +424,16 @@ class null_sink_mt : public sink {
null_sink_mt();
};

typedef void (*log_callback_t)(int lvl, const char* msg);

/**
* @brief A sink that executes a callback whenever a message is logged.
*/
class callback_sink_mt : public sink {
public:
explicit callback_sink_mt(const log_callback_t &callback);
};

/**
* @brief Returns the default log filename for the global logger.
*
Expand Down
44 changes: 44 additions & 0 deletions logger_impl.hpp.in
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,13 @@
#include <spdlog/sinks/null_sink.h>
#include <spdlog/sinks/ostream_sink.h>
#include <spdlog/spdlog.h>
#include <spdlog/details/log_msg.h>
#include <spdlog/sinks/base_sink.h>
#pragma GCC diagnostic pop

#include <iostream>
#include <memory>
#include <mutex>
#include <sstream>
#include <string>

Expand Down Expand Up @@ -136,6 +140,43 @@ private:
spdlog::logger underlying; ///< The spdlog logger
};

// Default flush function
void default_flush() { std::cout << std::flush; }

/**
* @brief A sink that calls a callback function with log messages.
*
* We do not currently use spdlog's callback sink because it does not support
* flushing. We could contribute that function to the upstream callback_sink_mt
* to simplify this code.
*/
template <class Mutex>
class callback_sink : public spdlog::sinks::base_sink<Mutex> {
public:
explicit callback_sink(log_callback_t callback,
void (*flush)() = nullptr)
: _callback{callback}, _flush{flush ? flush : default_flush} {}

protected:
void sink_it_(const spdlog::details::log_msg& msg) override
{
spdlog::memory_buf_t formatted;
spdlog::sinks::base_sink<Mutex>::formatter_->format(msg, formatted);
std::string msg_string = fmt::to_string(formatted);

if (_callback) {
_callback(static_cast<int>(msg.level), msg_string.c_str());
} else {
std::cout << msg_string;
}
}

void flush_() override { _flush();}

log_callback_t _callback;
void (*_flush)();
};

} // namespace detail

// Sink vector functions
Expand Down Expand Up @@ -170,6 +211,9 @@ ostream_sink_mt::ostream_sink_mt(std::ostream& stream, bool force_flush)
null_sink_mt::null_sink_mt()
: sink{std::make_unique<detail::sink_impl>(std::make_shared<spdlog::sinks::null_sink_mt>())} {}

callback_sink_mt::callback_sink_mt(const log_callback_t &callback)
: sink{std::make_unique<detail::sink_impl>(std::make_shared<detail::callback_sink<std::mutex>>(callback))} {}

// Logger methods
logger::logger(std::string name, std::string filename)
: impl{std::make_unique<detail::logger_impl>(name)}, sinks_{*this} {
Expand Down

0 comments on commit da934ca

Please sign in to comment.