# HG changeset patch # User David Demelier # Date 1531859400 -7200 # Node ID 0dbe1842a7d89cd956426ea4ebd6108d476866e2 # Parent 99c52213e3bd014dec28ab24722f1536b61c7c0f Irccd: rework loggers, closes #793 @3h Logger now supports category/component metadata. diff -r 99c52213e3bd -r 0dbe1842a7d8 irccd/main.cpp --- a/irccd/main.cpp Tue Jul 17 20:31:00 2018 +0200 +++ b/irccd/main.cpp Tue Jul 17 22:30:00 2018 +0200 @@ -163,7 +163,7 @@ instance->get_log().set_verbose(true); } } catch (const std::exception& ex) { - instance->get_log().warning() << "irccd: " << ex.what() << std::endl; + instance->get_log().warning("irccd", "") << "abort: " << ex.what() << std::endl; usage(); } diff -r 99c52213e3bd -r 0dbe1842a7d8 libirccd-js/irccd/js/logger_jsapi.cpp --- a/libirccd-js/irccd/js/logger_jsapi.cpp Tue Jul 17 20:31:00 2018 +0200 +++ b/libirccd-js/irccd/js/logger_jsapi.cpp Tue Jul 17 22:30:00 2018 +0200 @@ -16,8 +16,9 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +#include #include -#include +#include #include "irccd_jsapi.hpp" #include "js_plugin.hpp" @@ -30,11 +31,25 @@ // {{{ print -duk_ret_t print(duk_context* ctx, std::ostream &out) +duk_ret_t print(duk_context* ctx, unsigned level) { + assert(level >= 0 && level <= 2); + try { - out << "plugin " << dukx_type_traits::self(ctx)->get_name() << ": "; - out << duk_require_string(ctx, 0) << std::endl; + auto& sink = dukx_type_traits::self(ctx).get_log(); + auto self = dukx_type_traits::self(ctx); + + switch (level) { + case 0: + sink.debug(static_cast(*self)) << duk_require_string(ctx, 0) << std::endl; + break; + case 1: + sink.info(static_cast(*self)) << duk_require_string(ctx, 0) << std::endl; + break; + default: + sink.warning(static_cast(*self)) << duk_require_string(ctx, 0) << std::endl; + break; + } } catch (const std::exception& ex) { dukx_throw(ctx, ex); } @@ -59,7 +74,7 @@ */ duk_ret_t Logger_info(duk_context* ctx) { - return print(ctx, dukx_type_traits::self(ctx).get_log().info()); + return print(ctx, 1); } // }}} @@ -79,7 +94,7 @@ */ duk_ret_t Logger_warning(duk_context* ctx) { - return print(ctx, dukx_type_traits::self(ctx).get_log().warning()); + return print(ctx, 2); } // }}} @@ -99,7 +114,7 @@ */ duk_ret_t Logger_debug(duk_context* ctx) { - return print(ctx, dukx_type_traits::self(ctx).get_log().debug()); + return print(ctx, 0); } // }}} diff -r 99c52213e3bd -r 0dbe1842a7d8 libirccd-js/irccd/js/timer_jsapi.cpp --- a/libirccd-js/irccd/js/timer_jsapi.cpp Tue Jul 17 20:31:00 2018 +0200 +++ b/libirccd-js/irccd/js/timer_jsapi.cpp Tue Jul 17 22:30:00 2018 +0200 @@ -20,6 +20,7 @@ #include #include +#include #include "irccd_jsapi.hpp" #include "js_plugin.hpp" @@ -75,12 +76,12 @@ void timer::handle() { - auto plugin = plugin_.lock(); + auto plg = plugin_.lock(); - if (!plugin) + if (!plg) return; - auto& ctx = plugin->get_context(); + auto& ctx = plg->get_context(); duk_get_global_string(ctx, table); duk_get_prop_string(ctx, -1, key().c_str()); @@ -89,8 +90,8 @@ if (duk_pcall(ctx, 0)) { auto& log = dukx_type_traits::self(ctx).get_log(); - log.warning() << "plugin: " << plugin->get_name() << " timer error:" << std::endl; - log.warning() << " " << dukx_stack(ctx, -1).what() << std::endl; + log.warning(static_cast(*plg)) << "timer error:" << std::endl; + log.warning(static_cast(*plg)) << " " << dukx_stack(ctx, -1).what() << std::endl; } else duk_pop(ctx); } @@ -201,8 +202,6 @@ duk_del_prop_string(ctx, -1, ptr->key().c_str()); duk_pop(ctx); - dukx_type_traits::self(ctx).get_log().debug("timer: destroyed"); - delete ptr; return 0; diff -r 99c52213e3bd -r 0dbe1842a7d8 libirccd-test/irccd/test/command_test.hpp --- a/libirccd-test/irccd/test/command_test.hpp Tue Jul 17 20:31:00 2018 +0200 +++ b/libirccd-test/irccd/test/command_test.hpp Tue Jul 17 22:30:00 2018 +0200 @@ -108,7 +108,7 @@ // Add the server and the command. add(); - daemon_->set_log(std::make_unique()); + daemon_->set_log(std::make_unique()); // Wait for controller to connect. boost::asio::deadline_timer timer(service_); diff -r 99c52213e3bd -r 0dbe1842a7d8 libirccd-test/irccd/test/js_test.hpp --- a/libirccd-test/irccd/test/js_test.hpp Tue Jul 17 20:31:00 2018 +0200 +++ b/libirccd-test/irccd/test/js_test.hpp Tue Jul 17 22:30:00 2018 +0200 @@ -82,7 +82,7 @@ : plugin_(new js_plugin(plugin_path)) , server_(new journal_server(service_, "test")) { - irccd_.set_log(std::make_unique()); + irccd_.set_log(std::make_unique()); // Irccd is mandatory at the moment. add(); diff -r 99c52213e3bd -r 0dbe1842a7d8 libirccd-test/irccd/test/plugin_test.cpp --- a/libirccd-test/irccd/test/plugin_test.cpp Tue Jul 17 20:31:00 2018 +0200 +++ b/libirccd-test/irccd/test/plugin_test.cpp Tue Jul 17 22:30:00 2018 +0200 @@ -46,7 +46,7 @@ server_->set_nickname("irccd"); plugin_ = std::make_unique(std::move(path)); - irccd_.set_log(std::make_unique()); + irccd_.set_log(std::make_unique()); irccd_.get_log().set_verbose(false); irccd_.plugins().add("test", plugin_); irccd_.servers().add(server_); diff -r 99c52213e3bd -r 0dbe1842a7d8 libirccd/irccd/daemon/irccd.cpp --- a/libirccd/irccd/daemon/irccd.cpp Tue Jul 17 20:31:00 2018 +0200 +++ b/libirccd/irccd/daemon/irccd.cpp Tue Jul 17 22:30:00 2018 +0200 @@ -35,49 +35,70 @@ namespace { -class log_filter : public logger_filter { +class format_filter : public logger::filter { private: std::string info_; std::string warning_; std::string debug_; - std::string convert(const std::string& tmpl, std::string input) const - { - if (tmpl.empty()) - return input; - - string_util::subst params; - - params.flags &= ~(string_util::subst_flags::irc_attrs); - params.flags |= string_util::subst_flags::shell_attrs; - params.keywords.emplace("message", std::move(input)); - - return string_util::format(tmpl, params); - } + auto convert(const std::string&, + std::string_view, + std::string_view, + std::string_view) const -> std::string; public: - inline log_filter(std::string info, std::string warning, std::string debug) noexcept - : info_(std::move(info)) - , warning_(std::move(warning)) - , debug_(std::move(debug)) - { - } + format_filter(std::string info, std::string warning, std::string debug) noexcept; + auto pre_debug(std::string_view, std::string_view, std::string_view) const -> std::string override; + auto pre_info(std::string_view, std::string_view, std::string_view) const -> std::string override; + auto pre_warning(std::string_view, std::string_view, std::string_view) const -> std::string override; +}; + +auto format_filter::convert(const std::string& tmpl, + std::string_view category, + std::string_view component, + std::string_view message) const -> std::string +{ + if (tmpl.empty()) + return pre(category, component, message); + + string_util::subst params; + + params.flags &= ~(string_util::subst_flags::irc_attrs); + params.flags |= string_util::subst_flags::shell_attrs; + params.keywords.emplace("category", std::string(category)); + params.keywords.emplace("component", std::string(component)); + params.keywords.emplace("message", std::string(message)); + + return string_util::format(tmpl, params); +} - std::string pre_debug(std::string input) const override - { - return convert(debug_, std::move(input)); - } +format_filter::format_filter(std::string info, std::string warning, std::string debug) noexcept + : info_(std::move(info)) + , warning_(std::move(warning)) + , debug_(std::move(debug)) +{ +} + +auto format_filter::pre_debug(std::string_view category, + std::string_view component, + std::string_view message) const -> std::string +{ + return convert(debug_, category, component, message); +} - std::string pre_info(std::string input) const override - { - return convert(info_, std::move(input)); - } +auto format_filter::pre_info(std::string_view category, + std::string_view component, + std::string_view message) const -> std::string +{ + return convert(info_, category, component, message); +} - std::string pre_warning(std::string input) const override - { - return convert(warning_, std::move(input)); - } -}; +auto format_filter::pre_warning(std::string_view category, + std::string_view component, + std::string_view message) const -> std::string +{ + return convert(warning_, category, component, message); +} } // !namespace @@ -102,18 +123,18 @@ errors = it->value(); try { - logger_ = std::make_unique(std::move(normal), std::move(errors)); + sink_ = std::make_unique(std::move(normal), std::move(errors)); } catch (const std::exception& ex) { - logger_->warning() << "logs: " << ex.what() << std::endl; + sink_->warning("logs", "") << ex.what() << std::endl; } } void irccd::load_logs_syslog() { #if defined(HAVE_SYSLOG) - logger_ = std::make_unique(); + sink_ = std::make_unique(); #else - logger_->warning() << "logs: syslog is not available on this platform" << std::endl; + sink_->warning() << "logs: syslog is not available on this platform" << std::endl; #endif // !HAVE_SYSLOG } @@ -124,7 +145,7 @@ if (sc.empty()) return; - logger_->set_verbose(string_util::is_identifier(sc.get("verbose").value())); + sink_->set_verbose(string_util::is_identifier(sc.get("verbose").value())); const auto type = sc.get("type").value(); @@ -135,7 +156,7 @@ else if (type == "syslog") load_logs_syslog(); else if (type != "console") - logger_->warning() << "logs: invalid log type '" << type << std::endl; + sink_->warning("logs", "") << "invalid log type '" << type << std::endl; } } @@ -146,7 +167,7 @@ if (sc.empty()) return; - logger_->set_filter(std::make_unique( + sink_->set_filter(std::make_unique( sc.get("info").value(), sc.get("warning").value(), sc.get("debug").value() @@ -156,7 +177,7 @@ irccd::irccd(boost::asio::io_service& service, std::string config) : config_(std::move(config)) , service_(service) - , logger_(std::make_unique()) + , sink_(std::make_unique()) , server_service_(std::make_unique(*this)) , tpt_service_(std::make_unique(*this)) , rule_service_(std::make_unique(*this)) @@ -166,11 +187,11 @@ irccd::~irccd() = default; -void irccd::set_log(std::unique_ptr logger) noexcept +void irccd::set_log(std::unique_ptr sink) noexcept { - assert(logger); + assert(sink); - logger_ = std::move(logger); + sink_ = std::move(sink); } void irccd::load() noexcept @@ -187,9 +208,9 @@ load_formats(); if (!loaded_) - logger_->info() << "irccd: loading configuration from " << config_.get_path() << std::endl; + sink_->info("irccd", "") << "loading configuration from " << config_.get_path() << std::endl; else - logger_->info() << "irccd: reloading configuration" << std::endl; + sink_->info("irccd", "") << "reloading configuration" << std::endl; if (!loaded_) tpt_service_->load(config_); diff -r 99c52213e3bd -r 0dbe1842a7d8 libirccd/irccd/daemon/irccd.hpp --- a/libirccd/irccd/daemon/irccd.hpp Tue Jul 17 20:31:00 2018 +0200 +++ b/libirccd/irccd/daemon/irccd.hpp Tue Jul 17 22:30:00 2018 +0200 @@ -38,7 +38,12 @@ */ namespace irccd { -class logger; +namespace logger { + +class sink; + +} // !logger + class plugin_service; class rule_service; class server_service; @@ -59,7 +64,7 @@ bool loaded_{false}; // Custom logger. - std::unique_ptr logger_; + std::unique_ptr sink_; // Services. std::shared_ptr server_service_; @@ -139,9 +144,9 @@ * * \return the logger */ - inline const logger& get_log() const noexcept + inline const logger::sink& get_log() const noexcept { - return *logger_; + return *sink_; } /** @@ -149,9 +154,9 @@ * * \return the logger */ - inline logger& get_log() noexcept + inline logger::sink& get_log() noexcept { - return *logger_; + return *sink_; } /** @@ -160,7 +165,7 @@ * \pre logger != nullptr * \param logger the new logger */ - void set_log(std::unique_ptr logger) noexcept; + void set_log(std::unique_ptr sink) noexcept; /** * Access the server service. diff -r 99c52213e3bd -r 0dbe1842a7d8 libirccd/irccd/daemon/logger.cpp --- a/libirccd/irccd/daemon/logger.cpp Tue Jul 17 20:31:00 2018 +0200 +++ b/libirccd/irccd/daemon/logger.cpp Tue Jul 17 22:30:00 2018 +0200 @@ -27,38 +27,41 @@ # include #endif // !HAVE_SYSLOG -namespace irccd { +namespace irccd::logger { -void logger::buffer::debug(std::string line) +void logger::debug(const std::string& line) { // Print only in debug mode, the buffer is flushed anyway. #if !defined(NDEBUG) - parent_.write_debug(parent_.filter_->pre_debug(std::move(line))); + parent_.write_debug(parent_.filter_->pre_debug(category_, component_, line)); #else (void)line; #endif } -void logger::buffer::info(std::string line) +void logger::info(const std::string& line) { // Print only if verbose, the buffer will be flushed anyway. if (parent_.verbose_) - parent_.write_info(parent_.filter_->pre_info(std::move(line))); + parent_.write_info(parent_.filter_->pre_info(category_, component_, line)); } -void logger::buffer::warning(std::string line) +void logger::warning(const std::string& line) { - parent_.write_warning(parent_.filter_->pre_warning(std::move(line))); + parent_.write_warning(parent_.filter_->pre_warning(category_, component_, line)); } -logger::buffer::buffer(logger& parent, level level) noexcept - : parent_(parent) +logger::logger(sink& parent, level level, std::string_view category, std::string_view component) noexcept + : std::ostream(this) , level_(level) + , parent_(parent) + , category_(category) + , component_(component) { assert(level >= level::debug && level <= level::warning); } -int logger::buffer::sync() +int logger::sync() { std::string buffer = str(); std::string::size_type pos; @@ -71,13 +74,13 @@ switch (level_) { case level::debug: - debug(std::move(line)); + debug(line); break; case level::info: - info(std::move(line)); + info(line); break; case level::warning: - warning(std::move(line)); + warning(line); break; default: break; @@ -89,158 +92,156 @@ return 0; } -/* - * console_logger - * ------------------------------------------------------------------ - */ - -void console_logger::write_info(const std::string& line) +void console_sink::write_info(const std::string& line) { std::cout << line << std::endl; } -void console_logger::write_warning(const std::string& line) +void console_sink::write_warning(const std::string& line) { std::cerr << line << std::endl; } -void console_logger::write_debug(const std::string& line) +void console_sink::write_debug(const std::string& line) { std::cout << line << std::endl; } -/* - * file_logger - * ------------------------------------------------------------------ - */ - -file_logger::file_logger(std::string normal, std::string errors) +file_sink::file_sink(std::string normal, std::string errors) : output_normal_(std::move(normal)) , output_error_(std::move(errors)) { } -void file_logger::write_info(const std::string& line) +void file_sink::write_info(const std::string& line) { std::ofstream(output_normal_, std::ofstream::out | std::ofstream::app) << line << std::endl; } -void file_logger::write_warning(const std::string& line) +void file_sink::write_warning(const std::string& line) { std::ofstream(output_error_, std::ofstream::out | std::ofstream::app) << line << std::endl; } -void file_logger::write_debug(const std::string& line) +void file_sink::write_debug(const std::string& line) { std::ofstream(output_normal_, std::ofstream::out | std::ofstream::app) << line << std::endl; } -/* - * silent_logger - * ------------------------------------------------------------------ - */ - -void silent_logger::write_info(const std::string&) +void silent_sink::write_info(const std::string&) { } -void silent_logger::write_warning(const std::string&) +void silent_sink::write_warning(const std::string&) { } -void silent_logger::write_debug(const std::string&) +void silent_sink::write_debug(const std::string&) { } -/* - * syslog_logger - * ------------------------------------------------------------------ - */ - #if defined(HAVE_SYSLOG) -syslog_logger::syslog_logger() +syslog_sink::syslog_sink() { openlog("irccd", LOG_PID, LOG_DAEMON); } -syslog_logger::~syslog_logger() +syslog_sink::~syslog_sink() { closelog(); } -void syslog_logger::write_info(const std::string& line) +void syslog_sink::write_info(const std::string& line) { syslog(LOG_INFO | LOG_USER, "%s", line.c_str()); } -void syslog_logger::write_warning(const std::string& line) +void syslog_sink::write_warning(const std::string& line) { syslog(LOG_WARNING | LOG_USER, "%s", line.c_str()); } -void syslog_logger::write_debug(const std::string& line) +void syslog_sink::write_debug(const std::string& line) { syslog(LOG_DEBUG | LOG_USER, "%s", line.c_str()); } #endif // !HAVE_SYSLOG -/* - * logger - * ------------------------------------------------------------------ - */ - -logger::logger() - : buffer_info_(*this, buffer::level::info) - , buffer_warning_(*this, buffer::level::warning) - , buffer_debug_(*this, buffer::level::debug) - , stream_info_(&buffer_info_) - , stream_warning_(&buffer_warning_) - , stream_debug_(&buffer_debug_) - , filter_(std::make_unique()) +sink::sink() + : filter_(new filter) { } -bool logger::is_verbose() const noexcept +auto sink::is_verbose() const noexcept -> bool { return verbose_; } -void logger::set_verbose(bool mode) noexcept +void sink::set_verbose(bool mode) noexcept { verbose_ = mode; } -void logger::set_filter(std::unique_ptr newfilter) noexcept +void sink::set_filter(std::unique_ptr filter) noexcept { - assert(newfilter); + assert(filter); - filter_ = std::move(newfilter); + filter_ = std::move(filter); } -std::ostream& logger::info(const std::string& message) +auto sink::info(std::string_view category, std::string_view component) -> logger +{ + return logger(*this, logger::level::info, category, component);; +} + +auto sink::warning(std::string_view category, std::string_view component) -> logger { - if (!message.empty()) - stream_info_ << message << std::endl; + return logger(*this, logger::level::warning, category, component);; +} - return stream_info_; +auto sink::debug(std::string_view category, std::string_view component) -> logger +{ + return logger(*this, logger::level::debug, category, component);; } -std::ostream& logger::warning(const std::string& message) +auto filter::pre(std::string_view category, + std::string_view component, + std::string_view message) const -> std::string { - if (!message.empty()) - stream_warning_ << message << std::endl; + std::ostringstream oss; + + oss << category; - return stream_warning_; + if (!component.empty()) + oss << " " << component; + + oss << ": "; + oss << message; + + return oss.str(); } -std::ostream& logger::debug(const std::string& message) +auto filter::pre_debug(std::string_view category, + std::string_view component, + std::string_view message) const -> std::string { - if (!message.empty()) - stream_debug_ << message << std::endl; - - return stream_debug_; + return pre(category, component, message); } -} // !irccd +auto filter::pre_info(std::string_view category, + std::string_view component, + std::string_view message) const -> std::string +{ + return pre(category, component, message); +} + +auto filter::pre_warning(std::string_view category, + std::string_view component, + std::string_view message) const -> std::string +{ + return pre(category, component, message); +} + +} // !irccd::logger diff -r 99c52213e3bd -r 0dbe1842a7d8 libirccd/irccd/daemon/logger.hpp --- a/libirccd/irccd/daemon/logger.hpp Tue Jul 17 20:31:00 2018 +0200 +++ b/libirccd/irccd/daemon/logger.hpp Tue Jul 17 22:30:00 2018 +0200 @@ -29,11 +29,49 @@ #include #include #include +#include #include -namespace irccd { +namespace irccd::logger { + +class filter; +class sink; + +/** + * \brief Traits for loggable objects. + * + * Specialize this structure and add the following static functions to be able + * to log object with convenience: + * + * ```cpp + * static auto get_category(const T&) noexcept -> std::string_view; + * static auto get_component(const T&) noexcept -> std::string_view; + * ``` + */ +template +struct loggable_traits; -class logger_filter; +class logger : public std::ostream, public std::stringbuf { +private: + friend class sink; + + enum class level { + debug, + info, + warning + } level_; + + sink& parent_; + + std::string_view category_; + std::string_view component_; + + void debug(const std::string&); + void info(const std::string&); + void warning(const std::string&); + auto sync() -> int override; + logger(sink&, level, std::string_view, std::string_view) noexcept; +}; /** * \brief Interface to implement new logger mechanisms. @@ -41,48 +79,18 @@ * Derive from this class and implement write_info, write_warning and * write_debug functions. * - * \see file_logger - * \see console_logger - * \see syslog_logger - * \see silent_logger + * \see file_sink + * \see console_sink + * \see syslog_sink + * \see silent_sink */ -class logger { +class sink { private: - class buffer : public std::stringbuf { - public: - enum class level { - debug, - info, - warning - }; - - private: - logger& parent_; - level level_; - - void debug(std::string line); - void info(std::string line); - void warning(std::string line); - - public: - buffer(logger& parent, level level) noexcept; - - virtual int sync() override; - }; - - // Buffers. - buffer buffer_info_; - buffer buffer_warning_; - buffer buffer_debug_; - - // Stream outputs. - std::ostream stream_info_; - std::ostream stream_warning_; - std::ostream stream_debug_; + friend class logger; // User options. bool verbose_{false}; - std::unique_ptr filter_; + std::unique_ptr filter_; protected: /** @@ -119,19 +127,19 @@ /** * Default constructor. */ - logger(); + sink(); /** * Virtual destructor defaulted. */ - virtual ~logger() = default; + virtual ~sink() = default; /** * Tells if logger is verbose. * * \return true if verbose */ - bool is_verbose() const noexcept; + auto is_verbose() const noexcept -> bool; /** * Set the verbosity mode. @@ -146,92 +154,158 @@ * \pre filter must not be null * \param filter the filter */ - void set_filter(std::unique_ptr filter) noexcept; + void set_filter(std::unique_ptr filter) noexcept; /** * Get the stream for informational messages. * * If message is specified, a new line character is appended. * - * \param message the optional message to write - * \return the stream + * \param category the category subsystem + * \param component the optional component + * \return the output stream * \note Has no effect if verbose is set to false. */ - std::ostream& info(const std::string& message = ""); + auto info(std::string_view category, std::string_view component) -> logger; + + /** + * Convenient function with loggable objects. + * + * \param loggable the loggable object + * \return the output stream + * \see loggable_traits + */ + template + auto info(const Loggable& loggable) -> logger + { + return info( + loggable_traits::get_category(loggable), + loggable_traits::get_component(loggable) + ); + } /** * Get the stream for warnings. * * If message is specified, a new line character is appended. * - * \param message the optional message to write - * \return the stream + * \param category the category subsystem + * \param component the optional component + * \return the output stream */ - std::ostream& warning(const std::string& message = ""); + auto warning(std::string_view category, std::string_view component) -> logger; + + /** + * Convenient function with loggable objects. + * + * \param loggable the loggable object + * \return the output stream + * \see loggable_traits + */ + template + auto warning(const Loggable& loggable) -> logger + { + return warning( + loggable_traits::get_category(loggable), + loggable_traits::get_component(loggable) + ); + } /** * Get the stream for debug messages. * * If message is specified, a new line character is appended. * - * \param message the optional message to write - * \return the stream + * \param category the category subsystem + * \param component the optional component + * \return the output stream * \note Has no effect if compiled in release mode. */ - std::ostream& debug(const std::string& message = ""); + auto debug(std::string_view category, std::string_view component) -> logger; + + /** + * Convenient function with loggable objects. + * + * \param loggable the loggable object + * \return the output stream + * \see loggable_traits + */ + template + auto debug(const Loggable& loggable) -> logger + { + return debug( + loggable_traits::get_category(loggable), + loggable_traits::get_component(loggable) + ); + } }; /** * \brief Filter messages before printing them. - * - * Derive from this class and use log::setFilter. */ -class logger_filter { +class filter { +private: public: /** * Virtual destructor defaulted. */ - virtual ~logger_filter() = default; + virtual ~filter() = default; + + /** + * Default function called for each virtual ones. + * + * \param category the category subsystem + * \param component the optional component + * \param message the message + * \return default formatted message + */ + auto pre(std::string_view category, + std::string_view component, + std::string_view message) const -> std::string; + /** * Update the debug message. * - * \param input the message - * \return the updated message + * \param category the category subsystem + * \param component the optional component + * \param message the message + * \return the message */ - virtual std::string pre_debug(std::string input) const - { - return input; - } + virtual auto pre_debug(std::string_view category, + std::string_view component, + std::string_view message) const -> std::string; /** * Update the information message. * - * \param input the message + * \param category the category subsystem + * \param component the optional component + * \param message the message * \return the updated message */ - virtual std::string pre_info(std::string input) const - { - return input; - } + virtual auto pre_info(std::string_view category, + std::string_view component, + std::string_view message) const -> std::string; /** * Update the warning message. * - * \param input the message + * \param category the category subsystem + * \param component the optional component + * \param message the message * \return the updated message */ - virtual std::string pre_warning(std::string input) const - { - return input; - } + virtual auto pre_warning(std::string_view category, + std::string_view component, + std::string_view message) const -> std::string; }; /** * \brief Logger implementation for console output using std::cout and * std::cerr. */ -class console_logger : public logger { +class console_sink : public sink { protected: /** * \copydoc logger::write_debug @@ -252,7 +326,7 @@ /** * \brief Output to a files. */ -class file_logger : public logger { +class file_sink : public sink { private: std::string output_normal_; std::string output_error_; @@ -280,7 +354,7 @@ * \param normal the path to the normal logs * \param errors the path to the errors logs */ - file_logger(std::string normal, std::string errors); + file_sink(std::string normal, std::string errors); }; /** @@ -288,7 +362,7 @@ * * Useful for unit tests when some classes may emits log. */ -class silent_logger : public logger { +class silent_sink : public sink { protected: /** * \copydoc logger::write_debug @@ -311,7 +385,7 @@ /** * \brief Implements logger into syslog. */ -class syslog_logger : public logger { +class syslog_sink : public sink { protected: /** * \copydoc logger::write_debug @@ -332,16 +406,16 @@ /** * Open the syslog. */ - syslog_logger(); + syslog_sink(); /** * Close the syslog. */ - ~syslog_logger(); + ~syslog_sink(); }; #endif // !HAVE_SYSLOG -} // !irccd +} // !irccd::logger #endif // !IRCCD_DAEMON_LOGGER_HPP diff -r 99c52213e3bd -r 0dbe1842a7d8 libirccd/irccd/daemon/plugin.cpp --- a/libirccd/irccd/daemon/plugin.cpp Tue Jul 17 20:31:00 2018 +0200 +++ b/libirccd/irccd/daemon/plugin.cpp Tue Jul 17 22:30:00 2018 +0200 @@ -68,13 +68,13 @@ { std::ostringstream oss; - oss << "plugin " << name_ << ": " << code().message(); + oss << code().message(); std::istringstream iss(message_); std::string line; while (getline(iss, line)) - oss << "\nplugin " << name_ << ": " << line; + oss << "\n" << line; what_ = oss.str(); } diff -r 99c52213e3bd -r 0dbe1842a7d8 libirccd/irccd/daemon/service/plugin_service.cpp --- a/libirccd/irccd/daemon/service/plugin_service.cpp Tue Jul 17 20:31:00 2018 +0200 +++ b/libirccd/irccd/daemon/service/plugin_service.cpp Tue Jul 17 22:30:00 2018 +0200 @@ -52,7 +52,7 @@ try { plugin->handle_unload(irccd_); } catch (const std::exception& ex) { - irccd_.get_log().warning() << "plugin: " << plugin->get_name() << ": " << ex.what() << std::endl; + irccd_.get_log().warning(*plugin) << ex.what() << std::endl; } } } @@ -153,7 +153,7 @@ if (plugin) return plugin; } catch (const std::exception& ex) { - irccd_.get_log().warning() << "plugin " << id << ": " << ex.what() << std::endl; + irccd_.get_log().warning("plugin", id) << ex.what() << std::endl; } } @@ -225,10 +225,25 @@ try { load(name, option.value()); } catch (const std::exception& ex) { - irccd_.get_log().warning(ex.what()); + irccd_.get_log().warning("plugin", name) << ex.what() << std::endl; } } } } +namespace logger { + +auto loggable_traits::get_category(const plugin&) -> std::string_view +{ + return "plugin"; +} + +auto loggable_traits::get_component(const plugin& plugin) -> std::string_view +{ + // TODO: get id instead. + return plugin.get_name(); +} + +} // !logger + } // !irccd diff -r 99c52213e3bd -r 0dbe1842a7d8 libirccd/irccd/daemon/service/plugin_service.hpp --- a/libirccd/irccd/daemon/service/plugin_service.hpp Tue Jul 17 20:31:00 2018 +0200 +++ b/libirccd/irccd/daemon/service/plugin_service.hpp Tue Jul 17 22:30:00 2018 +0200 @@ -27,6 +27,7 @@ #include #include #include +#include #include #include @@ -244,6 +245,35 @@ void load(const config& cfg) noexcept; }; +namespace logger { + +template +struct loggable_traits; + +/** + * \brief Implement Loggable traits for plugin. + */ +template <> +struct loggable_traits { + /** + * Return "plugin" + * + * \param plugin the plugin + * \return the category + */ + static auto get_category(const plugin& plugin) -> std::string_view; + + /** + * Return the plugin id. + * + * \param plugin the plugin + * \return the plugin id + */ + static auto get_component(const plugin& plugin) -> std::string_view; +}; + +} // !logger + } // !irccd #endif // !IRCCD_DAEMON_PLUGIN_SERVICE_HPP diff -r 99c52213e3bd -r 0dbe1842a7d8 libirccd/irccd/daemon/service/rule_service.cpp --- a/libirccd/irccd/daemon/service/rule_service.cpp Tue Jul 17 20:31:00 2018 +0200 +++ b/libirccd/irccd/daemon/service/rule_service.cpp Tue Jul 17 22:30:00 2018 +0200 @@ -77,22 +77,24 @@ { bool result = true; - irccd_.get_log().debug(string_util::sprintf( - "rule: solving for server=%s, channel=%s, origin=%s, plugin=%s, event=%s", - server, channel, origin, plugin, event - )); + irccd_.get_log().debug("rule", "") + << "solving for server=" << server + << ", channel=" << channel + << ", origin=" << origin + << ", plugin=" << plugin + << ", event=" << event << std::endl; int i = 0; for (const auto& rule : rules_) { auto action = rule.get_action() == rule::action::accept ? "accept" : "drop"; - irccd_.get_log().debug() << " candidate " << i++ << ":\n" - << " servers: " << string_util::join(rule.get_servers()) << "\n" - << " channels: " << string_util::join(rule.get_channels()) << "\n" - << " origins: " << string_util::join(rule.get_origins()) << "\n" - << " plugins: " << string_util::join(rule.get_plugins()) << "\n" - << " events: " << string_util::join(rule.get_events()) << "\n" - << " action: " << action << std::endl; + irccd_.get_log().debug(rule) << "candidate " << i++ << ":" << std::endl; + irccd_.get_log().debug(rule) << " servers: " << string_util::join(rule.get_servers()) << std::endl; + irccd_.get_log().debug(rule) << " channels: " << string_util::join(rule.get_channels()) << std::endl; + irccd_.get_log().debug(rule) << " origins: " << string_util::join(rule.get_origins()) << std::endl; + irccd_.get_log().debug(rule) << " plugins: " << string_util::join(rule.get_plugins()) << std::endl; + irccd_.get_log().debug(rule) << " events: " << string_util::join(rule.get_events()) << std::endl; + irccd_.get_log().debug(rule) << " action: " << action << std::endl; if (rule.match(server, channel, origin, plugin, event)) result = rule.get_action() == rule::action::accept; @@ -112,9 +114,23 @@ try { rules_.push_back(rule_util::from_config(section)); } catch (const std::exception& ex) { - irccd_.get_log().warning() << "rule: " << ex.what() << std::endl; + irccd_.get_log().warning("rule", "") << ex.what() << std::endl; } } } +namespace logger { + +auto loggable_traits::get_category(const rule&) -> std::string_view +{ + return "rule"; +} + +auto loggable_traits::get_component(const rule&) -> std::string_view +{ + return ""; +} + +} // !logger + } // !irccd diff -r 99c52213e3bd -r 0dbe1842a7d8 libirccd/irccd/daemon/service/rule_service.hpp --- a/libirccd/irccd/daemon/service/rule_service.hpp Tue Jul 17 20:31:00 2018 +0200 +++ b/libirccd/irccd/daemon/service/rule_service.hpp Tue Jul 17 22:30:00 2018 +0200 @@ -133,6 +133,20 @@ void load(const config& cfg) noexcept; }; +namespace logger { + +template +struct loggable_traits; + +template <> +struct loggable_traits { + static auto get_category(const rule& rule) -> std::string_view; + + static auto get_component(const rule& rule) -> std::string_view; +}; + +} // !logger + } // !irccd #endif // !IRCCD_DAEMON_RULE_SERVICE_HPP diff -r 99c52213e3bd -r 0dbe1842a7d8 libirccd/irccd/daemon/service/server_service.cpp --- a/libirccd/irccd/daemon/service/server_service.cpp Tue Jul 17 20:31:00 2018 +0200 +++ b/libirccd/irccd/daemon/service/server_service.cpp Tue Jul 17 22:30:00 2018 +0200 @@ -45,17 +45,16 @@ const auto allowed = daemon.rules().solve(server, target, origin, plugin->get_name(), eventname); if (!allowed) { - daemon.get_log().debug("rule: event skipped on match"); + daemon.get_log().debug("rule", "") << "event skipped on match" << std::endl; continue; } - daemon.get_log().debug("rule: event allowed"); + daemon.get_log().debug("rule", "") << "event allowed" << std::endl; try { exec_func(*plugin); } catch (const std::exception& ex) { - daemon.get_log().warning() << "plugin " << plugin->get_name() << ": error: " - << ex.what() << std::endl; + daemon.get_log().warning(*plugin) << ex.what() << std::endl; } } } @@ -64,7 +63,7 @@ void server_service::handle_connect(const connect_event& ev) { - irccd_.get_log().debug() << "server " << ev.server->get_name() << ": event onConnect" << std::endl; + irccd_.get_log().debug(*ev.server) << "event onConnect" << std::endl; irccd_.transports().broadcast(nlohmann::json::object({ { "event", "onConnect" }, { "server", ev.server->get_name() } @@ -82,7 +81,7 @@ void server_service::handle_disconnect(const disconnect_event& ev) { - irccd_.get_log().debug() << "server " << ev.server->get_name() << ": event onDisconnect" << std::endl; + irccd_.get_log().debug(*ev.server) << "event onDisconnect" << std::endl; irccd_.transports().broadcast(nlohmann::json::object({ { "event", "onDisconnect" }, { "server", ev.server->get_name() } @@ -105,10 +104,10 @@ void server_service::handle_invite(const invite_event& ev) { - irccd_.get_log().debug() << "server " << ev.server->get_name() << ": event onInvite:\n"; - irccd_.get_log().debug() << " origin: " << ev.origin << "\n"; - irccd_.get_log().debug() << " channel: " << ev.channel << "\n"; - irccd_.get_log().debug() << " target: " << ev.nickname << std::endl; + irccd_.get_log().debug(*ev.server) << "event onInvite:" << std::endl; + irccd_.get_log().debug(*ev.server) << " origin: " << ev.origin << std::endl; + irccd_.get_log().debug(*ev.server) << " channel: " << ev.channel << std::endl; + irccd_.get_log().debug(*ev.server) << " target: " << ev.nickname << std::endl; irccd_.transports().broadcast(nlohmann::json::object({ { "event", "onInvite" }, @@ -129,9 +128,9 @@ void server_service::handle_join(const join_event& ev) { - irccd_.get_log().debug() << "server " << ev.server->get_name() << ": event onJoin:\n"; - irccd_.get_log().debug() << " origin: " << ev.origin << "\n"; - irccd_.get_log().debug() << " channel: " << ev.channel << std::endl; + irccd_.get_log().debug(*ev.server) << "event onJoin:" << std::endl; + irccd_.get_log().debug(*ev.server) << " origin: " << ev.origin << std::endl; + irccd_.get_log().debug(*ev.server) << " channel: " << ev.channel << std::endl; irccd_.transports().broadcast(nlohmann::json::object({ { "event", "onJoin" }, @@ -152,11 +151,11 @@ void server_service::handle_kick(const kick_event& ev) { - irccd_.get_log().debug() << "server " << ev.server->get_name() << ": event onKick:\n"; - irccd_.get_log().debug() << " origin: " << ev.origin << "\n"; - irccd_.get_log().debug() << " channel: " << ev.channel << "\n"; - irccd_.get_log().debug() << " target: " << ev.target << "\n"; - irccd_.get_log().debug() << " reason: " << ev.reason << std::endl; + irccd_.get_log().debug(*ev.server) << "event onKick:" << std::endl; + irccd_.get_log().debug(*ev.server) << " origin: " << ev.origin << std::endl; + irccd_.get_log().debug(*ev.server) << " channel: " << ev.channel << std::endl; + irccd_.get_log().debug(*ev.server) << " target: " << ev.target << std::endl; + irccd_.get_log().debug(*ev.server) << " reason: " << ev.reason << std::endl; irccd_.transports().broadcast(nlohmann::json::object({ { "event", "onKick" }, @@ -179,10 +178,10 @@ void server_service::handle_message(const message_event& ev) { - irccd_.get_log().debug() << "server " << ev.server->get_name() << ": event onMessage:\n"; - irccd_.get_log().debug() << " origin: " << ev.origin << "\n"; - irccd_.get_log().debug() << " channel: " << ev.channel << "\n"; - irccd_.get_log().debug() << " message: " << ev.message << std::endl; + irccd_.get_log().debug(*ev.server) << "event onMessage:" << std::endl; + irccd_.get_log().debug(*ev.server) << " origin: " << ev.origin << std::endl; + irccd_.get_log().debug(*ev.server) << " channel: " << ev.channel << std::endl; + irccd_.get_log().debug(*ev.server) << " message: " << ev.message << std::endl; irccd_.transports().broadcast(nlohmann::json::object({ { "event", "onMessage" }, @@ -220,10 +219,10 @@ void server_service::handle_me(const me_event& ev) { - irccd_.get_log().debug() << "server " << ev.server->get_name() << ": event onMe:\n"; - irccd_.get_log().debug() << " origin: " << ev.origin << "\n"; - irccd_.get_log().debug() << " target: " << ev.channel << "\n"; - irccd_.get_log().debug() << " message: " << ev.message << std::endl; + irccd_.get_log().debug(*ev.server) << "event onMe:" << std::endl; + irccd_.get_log().debug(*ev.server) << " origin: " << ev.origin << std::endl; + irccd_.get_log().debug(*ev.server) << " target: " << ev.channel << std::endl; + irccd_.get_log().debug(*ev.server) << " message: " << ev.message << std::endl; irccd_.transports().broadcast(nlohmann::json::object({ { "event", "onMe" }, @@ -245,13 +244,13 @@ void server_service::handle_mode(const mode_event& ev) { - irccd_.get_log().debug() << "server " << ev.server->get_name() << ": event onMode\n"; - irccd_.get_log().debug() << " origin: " << ev.origin << "\n"; - irccd_.get_log().debug() << " channel: " << ev.channel << "\n"; - irccd_.get_log().debug() << " mode: " << ev.mode << "\n"; - irccd_.get_log().debug() << " limit: " << ev.limit << "\n"; - irccd_.get_log().debug() << " user: " << ev.user << "\n"; - irccd_.get_log().debug() << " mask: " << ev.mask << std::endl; + irccd_.get_log().debug(*ev.server) << "event onMode" << std::endl; + irccd_.get_log().debug(*ev.server) << " origin: " << ev.origin << std::endl; + irccd_.get_log().debug(*ev.server) << " channel: " << ev.channel << std::endl; + irccd_.get_log().debug(*ev.server) << " mode: " << ev.mode << std::endl; + irccd_.get_log().debug(*ev.server) << " limit: " << ev.limit << std::endl; + irccd_.get_log().debug(*ev.server) << " user: " << ev.user << std::endl; + irccd_.get_log().debug(*ev.server) << " mask: " << ev.mask << std::endl; irccd_.transports().broadcast(nlohmann::json::object({ { "event", "onMode" }, @@ -276,9 +275,9 @@ void server_service::handle_names(const names_event& ev) { - irccd_.get_log().debug() << "server " << ev.server->get_name() << ": event onNames:\n"; - irccd_.get_log().debug() << " channel: " << ev.channel << "\n"; - irccd_.get_log().debug() << " names: " << string_util::join(ev.names.begin(), ev.names.end(), ", ") << std::endl; + irccd_.get_log().debug(*ev.server) << "event onNames:" << std::endl; + irccd_.get_log().debug(*ev.server) << " channel: " << ev.channel << std::endl; + irccd_.get_log().debug(*ev.server) << " names: " << string_util::join(ev.names.begin(), ev.names.end(), ", ") << std::endl; auto names = nlohmann::json::array(); @@ -304,9 +303,9 @@ void server_service::handle_nick(const nick_event& ev) { - irccd_.get_log().debug() << "server " << ev.server->get_name() << ": event onNick:\n"; - irccd_.get_log().debug() << " origin: " << ev.origin << "\n"; - irccd_.get_log().debug() << " nickname: " << ev.nickname << std::endl; + irccd_.get_log().debug(*ev.server) << "event onNick:" << std::endl; + irccd_.get_log().debug(*ev.server) << " origin: " << ev.origin << std::endl; + irccd_.get_log().debug(*ev.server) << " nickname: " << ev.nickname << std::endl; irccd_.transports().broadcast(nlohmann::json::object({ { "event", "onNick" }, @@ -327,10 +326,10 @@ void server_service::handle_notice(const notice_event& ev) { - irccd_.get_log().debug() << "server " << ev.server->get_name() << ": event onNotice:\n"; - irccd_.get_log().debug() << " origin: " << ev.origin << "\n"; - irccd_.get_log().debug() << " channel: " << ev.channel << "\n"; - irccd_.get_log().debug() << " message: " << ev.message << std::endl; + irccd_.get_log().debug(*ev.server) << "event onNotice:" << std::endl; + irccd_.get_log().debug(*ev.server) << " origin: " << ev.origin << std::endl; + irccd_.get_log().debug(*ev.server) << " channel: " << ev.channel << std::endl; + irccd_.get_log().debug(*ev.server) << " message: " << ev.message << std::endl; irccd_.transports().broadcast(nlohmann::json::object({ { "event", "onNotice" }, @@ -352,10 +351,10 @@ void server_service::handle_part(const part_event& ev) { - irccd_.get_log().debug() << "server " << ev.server->get_name() << ": event onPart:\n"; - irccd_.get_log().debug() << " origin: " << ev.origin << "\n"; - irccd_.get_log().debug() << " channel: " << ev.channel << "\n"; - irccd_.get_log().debug() << " reason: " << ev.reason << std::endl; + irccd_.get_log().debug(*ev.server) << "event onPart:" << std::endl; + irccd_.get_log().debug(*ev.server) << " origin: " << ev.origin << std::endl; + irccd_.get_log().debug(*ev.server) << " channel: " << ev.channel << std::endl; + irccd_.get_log().debug(*ev.server) << " reason: " << ev.reason << std::endl; irccd_.transports().broadcast(nlohmann::json::object({ { "event", "onPart" }, @@ -377,10 +376,10 @@ void server_service::handle_topic(const topic_event& ev) { - irccd_.get_log().debug() << "server " << ev.server->get_name() << ": event onTopic:\n"; - irccd_.get_log().debug() << " origin: " << ev.origin << "\n"; - irccd_.get_log().debug() << " channel: " << ev.channel << "\n"; - irccd_.get_log().debug() << " topic: " << ev.topic << std::endl; + irccd_.get_log().debug(*ev.server) << "event onTopic:" << std::endl; + irccd_.get_log().debug(*ev.server) << " origin: " << ev.origin << std::endl; + irccd_.get_log().debug(*ev.server) << " channel: " << ev.channel << std::endl; + irccd_.get_log().debug(*ev.server) << " topic: " << ev.topic << std::endl; irccd_.transports().broadcast(nlohmann::json::object({ { "event", "onTopic" }, @@ -402,12 +401,12 @@ void server_service::handle_whois(const whois_event& ev) { - irccd_.get_log().debug() << "server " << ev.server->get_name() << ": event onWhois\n"; - irccd_.get_log().debug() << " nickname: " << ev.whois.nick << "\n"; - irccd_.get_log().debug() << " username: " << ev.whois.user << "\n"; - irccd_.get_log().debug() << " host: " << ev.whois.host << "\n"; - irccd_.get_log().debug() << " realname: " << ev.whois.realname << "\n"; - irccd_.get_log().debug() << " channels: " << string_util::join(ev.whois.channels, ", ") << std::endl; + irccd_.get_log().debug(*ev.server) << "event onWhois" << std::endl; + irccd_.get_log().debug(*ev.server) << " nickname: " << ev.whois.nick << std::endl; + irccd_.get_log().debug(*ev.server) << " username: " << ev.whois.user << std::endl; + irccd_.get_log().debug(*ev.server) << " host: " << ev.whois.host << std::endl; + irccd_.get_log().debug(*ev.server) << " realname: " << ev.whois.realname << std::endl; + irccd_.get_log().debug(*ev.server) << " channels: " << string_util::join(ev.whois.channels, ", ") << std::endl; irccd_.transports().broadcast(nlohmann::json::object({ { "event", "onWhois" }, @@ -520,6 +519,8 @@ if (section.key() != "server") continue; + const auto id = section.get("name").value(); + try { auto server = server_util::from_config(irccd_.get_service(), cfg, section); @@ -528,10 +529,24 @@ add(std::move(server)); } catch (const std::exception& ex) { - irccd_.get_log().warning() << "server " << section.get("name").value() << ": " - << ex.what() << std::endl; + irccd_.get_log().warning("server", id) << ex.what() << std::endl; } } } +namespace logger { + +auto loggable_traits::get_category(const server&) -> std::string_view +{ + return "server"; +} + +auto loggable_traits::get_component(const server& sv) -> std::string_view +{ + // TODO: get id instead. + return sv.get_name(); +} + +} // !logger + } // !irccd diff -r 99c52213e3bd -r 0dbe1842a7d8 libirccd/irccd/daemon/service/server_service.hpp --- a/libirccd/irccd/daemon/service/server_service.hpp Tue Jul 17 20:31:00 2018 +0200 +++ b/libirccd/irccd/daemon/service/server_service.hpp Tue Jul 17 22:30:00 2018 +0200 @@ -133,6 +133,20 @@ void load(const config& cfg) noexcept; }; +namespace logger { + +template +struct loggable_traits; + +template <> +struct loggable_traits { + static auto get_category(const server& server) -> std::string_view; + + static auto get_component(const server& server) -> std::string_view; +}; + +} // !logger + } // !irccd #endif // !IRCCD_DAEMON_SERVER_SERVICE_HPP diff -r 99c52213e3bd -r 0dbe1842a7d8 libirccd/irccd/daemon/service/transport_service.cpp --- a/libirccd/irccd/daemon/service/transport_service.cpp Tue Jul 17 20:31:00 2018 +0200 +++ b/libirccd/irccd/daemon/service/transport_service.cpp Tue Jul 17 22:30:00 2018 +0200 @@ -56,8 +56,9 @@ } catch (const std::system_error& ex) { tc->error(ex.code(), (*cmd)->get_name()); } catch (const std::exception& ex) { - irccd_.get_log().warning() << "transport: unknown error not reported" << std::endl; - irccd_.get_log().warning() << "transport: " << ex.what() << std::endl; + irccd_.get_log().warning("transport", "") + << "unknown error not reported: " + << ex.what() << std::endl; } } } @@ -67,7 +68,7 @@ tc->read([this, tc] (auto code, auto json) { switch (static_cast(code.value())) { case std::errc::not_connected: - irccd_.get_log().info("transport: client disconnected"); + irccd_.get_log().info("transport", "") << "client disconnected" << std::endl; break; case std::errc::invalid_argument: tc->error(irccd_error::invalid_message); @@ -93,7 +94,7 @@ do_accept(ts); do_recv(std::move(client)); - irccd_.get_log().info() << "transport: new client connected" << std::endl; + irccd_.get_log().info("transport", "") << "new client connected" << std::endl; } }); } @@ -131,7 +132,7 @@ try { add(transport_util::from_config(irccd_.get_service(), section)); } catch (const std::exception& ex) { - irccd_.get_log().warning() << "transport: " << ex.what() << std::endl; + irccd_.get_log().warning("transport", "") << ex.what() << std::endl; } } } diff -r 99c52213e3bd -r 0dbe1842a7d8 tests/src/libirccd-js/jsapi-logger/main.cpp --- a/tests/src/libirccd-js/jsapi-logger/main.cpp Tue Jul 17 20:31:00 2018 +0200 +++ b/tests/src/libirccd-js/jsapi-logger/main.cpp Tue Jul 17 22:30:00 2018 +0200 @@ -36,12 +36,12 @@ std::string line_warning; std::string line_debug; - class my_logger : public logger { + class sample_sink : public logger::sink { private: logger_test& test_; public: - inline my_logger(logger_test& test) noexcept + inline sample_sink(logger_test& test) noexcept : test_(test) { } @@ -65,7 +65,7 @@ logger_test() : js_test(CMAKE_CURRENT_SOURCE_DIR "/empty.js") { - irccd_.set_log(std::make_unique(*this)); + irccd_.set_log(std::make_unique(*this)); irccd_.get_log().set_verbose(true); } }; diff -r 99c52213e3bd -r 0dbe1842a7d8 tests/src/libirccd/logger/main.cpp --- a/tests/src/libirccd/logger/main.cpp Tue Jul 17 20:31:00 2018 +0200 +++ b/tests/src/libirccd/logger/main.cpp Tue Jul 17 22:30:00 2018 +0200 @@ -20,14 +20,18 @@ #define BOOST_TEST_MODULE "Logger" #include +#include #include +using boost::format; +using boost::str; + namespace irccd { namespace { -class my_logger : public logger { +class sample_sink : public logger::sink { public: std::string line_debug; std::string line_info; @@ -49,31 +53,37 @@ } }; -class my_filter : public logger_filter { +class sample_filter : public logger::filter { public: - std::string pre_debug(std::string input) const override + auto pre_debug(std::string_view category, + std::string_view component, + std::string_view message) const -> std::string override { - return std::reverse(input.begin(), input.end()), input; + return str(format("DEBUG %s:%s:%s") % category % component % message); } - std::string pre_info(std::string input) const override + auto pre_info(std::string_view category, + std::string_view component, + std::string_view message) const -> std::string override { - return std::reverse(input.begin(), input.end()), input; + return str(format("INFO %s:%s:%s") % category % component % message); } - std::string pre_warning(std::string input) const override + auto pre_warning(std::string_view category, + std::string_view component, + std::string_view message) const -> std::string override { - return std::reverse(input.begin(), input.end()), input; + return str(format("WARN %s:%s:%s") % category % component % message); } }; class logger_test { public: - my_logger log_; + sample_sink log_; logger_test() { - log_.set_filter(std::make_unique()); + log_.set_filter(std::make_unique()); log_.set_verbose(true); } }; @@ -84,33 +94,33 @@ BOOST_AUTO_TEST_CASE(debug) { - log_.debug("debug"); + log_.debug("test", "debug") << "success" << std::endl; - BOOST_REQUIRE_EQUAL("gubed", log_.line_debug); + BOOST_TEST(log_.line_debug == "DEBUG test:debug:success"); } #endif BOOST_AUTO_TEST_CASE(info) { - log_.info("info"); + log_.info("test", "info") << "success" << std::endl; - BOOST_REQUIRE_EQUAL("ofni", log_.line_info); + BOOST_TEST(log_.line_info == "INFO test:info:success"); } BOOST_AUTO_TEST_CASE(info_quiet) { log_.set_verbose(false); - log_.info("info"); + log_.info("test", "info") << "success" << std::endl; BOOST_REQUIRE(log_.line_info.empty()); } BOOST_AUTO_TEST_CASE(warning) { - log_.warning("warning"); + log_.warning("test", "warning") << "success" << std::endl; - BOOST_REQUIRE_EQUAL("gninraw", log_.line_warning); + BOOST_TEST(log_.line_warning == "WARN test:warning:success"); } BOOST_AUTO_TEST_SUITE_END() diff -r 99c52213e3bd -r 0dbe1842a7d8 tests/src/libirccd/rules/main.cpp --- a/tests/src/libirccd/rules/main.cpp Tue Jul 17 20:31:00 2018 +0200 +++ b/tests/src/libirccd/rules/main.cpp Tue Jul 17 22:30:00 2018 +0200 @@ -75,7 +75,7 @@ rules_test() { - daemon_.set_log(std::make_unique()); + daemon_.set_log(std::make_unique()); // #1 {