Mercurial > irccd
changeset 599:e531f04507aa
Irccd: move logger into libirccd, closes #740
line wrap: on
line diff
--- a/irccd/main.cpp Wed Dec 06 14:12:57 2017 +0100 +++ b/irccd/main.cpp Wed Dec 06 21:32:10 2017 +0100 @@ -33,7 +33,6 @@ #include <csignal> #include <iostream> -#include <irccd/logger.hpp> #include <irccd/options.hpp> #include <irccd/string_util.hpp> #include <irccd/system.hpp> @@ -41,6 +40,7 @@ #include <irccd/daemon/command_service.hpp> #include <irccd/daemon/config.hpp> #include <irccd/daemon/irccd.hpp> +#include <irccd/daemon/logger.hpp> #include <irccd/daemon/plugin_service.hpp> #include <irccd/daemon/rule_service.hpp> #include <irccd/daemon/server_service.hpp> @@ -109,7 +109,7 @@ sys::set_program_name("irccd"); // Default logging to console. - log::set_verbose(false); + instance->log().set_verbose(false); -- argc; ++ argv; @@ -143,10 +143,10 @@ version(result); // NOTREACHED if (pair.first == "-v" || pair.first == "--verbose") - log::set_verbose(true); + instance->log().set_verbose(true); } } catch (const std::exception& ex) { - log::warning() << "irccd: " << ex.what() << std::endl; + instance->log().warning() << "irccd: " << ex.what() << std::endl; usage(); } @@ -171,14 +171,15 @@ { using namespace irccd; - init(argc, argv); - boost::asio::io_service service; boost::asio::signal_set sigs(service, SIGINT, SIGTERM); + instance = std::make_unique<class irccd>(service); + + init(argc, argv); + auto options = parse(argc, argv); - instance = std::make_unique<class irccd>(service); instance->commands().add(std::make_unique<plugin_config_command>()); instance->commands().add(std::make_unique<plugin_info_command>()); instance->commands().add(std::make_unique<plugin_list_command>()); @@ -230,7 +231,7 @@ instance->set_config(open(options)); instance->load(); } catch (const std::exception& ex) { - log::warning() << "abort: " << ex.what() << std::endl; + std::cerr << "abort: " << ex.what() << std::endl; return 1; }
--- a/irccdctl/main.cpp Wed Dec 06 14:12:57 2017 +0100 +++ b/irccdctl/main.cpp Wed Dec 06 21:32:10 2017 +0100 @@ -25,7 +25,6 @@ #include <irccd/ini.hpp> #include <irccd/json_util.hpp> -#include <irccd/logger.hpp> #include <irccd/options.hpp> #include <irccd/string_util.hpp> #include <irccd/system.hpp> @@ -86,6 +85,9 @@ #endif +// Global options. +bool verbose = true; + // Connection to instance. std::unique_ptr<connection> conn; std::unique_ptr<controller> ctl; @@ -213,10 +215,10 @@ */ void read_general(const ini::section& sc) { - auto verbose = sc.find("verbose"); + auto value = sc.find("verbose"); - if (verbose != sc.end()) - log::set_verbose(string_util::is_boolean(verbose->value())); + if (value != sc.end()) + verbose = string_util::is_boolean(value->value()); } /* @@ -276,7 +278,7 @@ } } } catch (const std::exception &ex) { - log::warning() << path << ": " << ex.what() << std::endl; + std::cerr << path << ": " << ex.what() << std::endl; } } @@ -393,9 +395,9 @@ // NOTREACHED if (result.count("-v") != 0 || result.count("--verbose") != 0) - log::set_verbose(true); + verbose = true; } catch (const std::exception& ex) { - log::warning() << "irccdctl: " << ex.what() << std::endl; + std::cerr << "irccdctl: " << ex.what() << std::endl; usage(); } @@ -512,10 +514,11 @@ if (code) throw boost::system::system_error(code); - log::info(string_util::sprintf("connected to irccd %d.%d.%d", - json_util::to_int(info["major"]), - json_util::to_int(info["minor"]), - json_util::to_int(info["patch"]))); + if (verbose) + std::cout << string_util::sprintf("connected to irccd %d.%d.%d\n", + json_util::to_int(info["major"]), + json_util::to_int(info["minor"]), + json_util::to_int(info["patch"])); connected = true; }); @@ -580,7 +583,7 @@ } } } catch (const std::exception& ex) { - irccd::log::warning() << "abort: " << ex.what() << std::endl; + std::cerr << "abort: " << ex.what() << std::endl; return 1; } @@ -589,7 +592,7 @@ // NOTREACHED if (!irccd::ctl::ctl) { - irccd::log::warning("abort: no connection specified"); + std::cerr << "abort: no connection specified" << std::endl; return 1; }
--- a/libcommon/CMakeLists.txt Wed Dec 06 14:12:57 2017 +0100 +++ b/libcommon/CMakeLists.txt Wed Dec 06 21:32:10 2017 +0100 @@ -25,7 +25,6 @@ ${libcommon_SOURCE_DIR}/irccd/fs_util.hpp ${libcommon_SOURCE_DIR}/irccd/ini.hpp ${libcommon_SOURCE_DIR}/irccd/json_util.hpp - ${libcommon_SOURCE_DIR}/irccd/logger.hpp ${libcommon_SOURCE_DIR}/irccd/network_stream.hpp ${libcommon_SOURCE_DIR}/irccd/options.hpp ${libcommon_SOURCE_DIR}/irccd/string_util.hpp @@ -38,7 +37,6 @@ SOURCES ${libcommon_SOURCE_DIR}/irccd/ini.cpp ${libcommon_SOURCE_DIR}/irccd/json_util.cpp - ${libcommon_SOURCE_DIR}/irccd/logger.cpp ${libcommon_SOURCE_DIR}/irccd/options.cpp ${libcommon_SOURCE_DIR}/irccd/string_util.cpp ${libcommon_SOURCE_DIR}/irccd/system.cpp
--- a/libcommon/irccd/logger.cpp Wed Dec 06 14:12:57 2017 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,299 +0,0 @@ -/* - * logger.cpp -- irccd logging - * - * Copyright (c) 2013-2017 David Demelier <markand@malikania.fr> - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include <atomic> -#include <cassert> -#include <cerrno> -#include <cstring> -#include <fstream> -#include <iostream> -#include <stdexcept> -#include <streambuf> - -#include "logger.hpp" -#include "system.hpp" - -#if defined(HAVE_SYSLOG) -# include <syslog.h> -#endif // !HAVE_SYSLOG - -namespace irccd { - -namespace log { - -namespace { - -/* - * User definable options. - * ------------------------------------------------------------------ - */ - -std::atomic<bool> verbose{false}; -std::unique_ptr<logger> use_iface{new console_logger}; -std::unique_ptr<filter> use_filter{new filter}; - -/* - * buffer -- output buffer. - * ------------------------------------------------------------------ - * - * This class inherits from std::stringbuf and writes the messages to the - * specified interface function which is one of info, warning and debug. - */ - -class buffer : public std::stringbuf { -public: - enum class level { - debug, - info, - warning - }; - -private: - level level_; - - void debug(std::string line) - { - // Print only in debug mode, the buffer is flushed anyway. -#if !defined(NDEBUG) - use_iface->debug(use_filter->pre_debug(std::move(line))); -#else - (void)line; -#endif - } - - void info(std::string line) - { - // Print only if verbose, the buffer will be flushed anyway. - if (verbose) - use_iface->info(use_filter->pre_info(std::move(line))); - } - - void warning(std::string line) - { - use_iface->warning(use_filter->pre_warning(std::move(line))); - } - -public: - inline buffer(level level) noexcept - : level_(level) - { - assert(level >= level::debug && level <= level::warning); - } - - virtual int sync() override - { - std::string buffer = str(); - std::string::size_type pos; - - while ((pos = buffer.find("\n")) != std::string::npos) { - auto line = buffer.substr(0, pos); - - // Remove this line. - buffer.erase(buffer.begin(), buffer.begin() + pos + 1); - - switch (level_) { - case level::debug: - debug(std::move(line)); - break; - case level::info: - info(std::move(line)); - break; - case level::warning: - warning(std::move(line)); - break; - default: - break; - } - } - - str(buffer); - - return 0; - } -}; - -/* - * Local variables. - * ------------------------------------------------------------------ - */ - -// Buffers. -buffer buffer_info{buffer::level::info}; -buffer buffer_warning{buffer::level::warning}; -buffer buffer_debug{buffer::level::debug}; - -// Stream outputs. -std::ostream stream_info(&buffer_info); -std::ostream stream_warning(&buffer_warning); -std::ostream stream_debug(&buffer_debug); - -} // !namespace - -/* - * console_logger - * ------------------------------------------------------------------ - */ - -void console_logger::info(const std::string& line) -{ - std::cout << line << std::endl; -} - -void console_logger::warning(const std::string& line) -{ - std::cerr << line << std::endl; -} - -void console_logger::debug(const std::string& line) -{ - std::cout << line << std::endl; -} - -/* - * file_logger - * ------------------------------------------------------------------ - */ - -file_logger::file_logger(std::string normal, std::string errors) - : output_normal_(std::move(normal)) - , output_error_(std::move(errors)) -{ -} - -void file_logger::info(const std::string& line) -{ - std::ofstream(output_normal_, std::ofstream::out | std::ofstream::app) << line << std::endl; -} - -void file_logger::warning(const std::string& line) -{ - std::ofstream(output_error_, std::ofstream::out | std::ofstream::app) << line << std::endl; -} - -void file_logger::debug(const std::string& line) -{ - std::ofstream(output_normal_, std::ofstream::out | std::ofstream::app) << line << std::endl; -} - -/* - * silent_logger - * ------------------------------------------------------------------ - */ - -void silent_logger::info(const std::string&) -{ -} - -void silent_logger::warning(const std::string&) -{ -} - -void silent_logger::debug(const std::string&) -{ -} - -/* - * syslog_logger - * ------------------------------------------------------------------ - */ - -#if defined(HAVE_SYSLOG) - -syslog_logger::syslog_logger() -{ - openlog("irccd", LOG_PID, LOG_DAEMON); -} - -syslog_logger::~syslog_logger() -{ - closelog(); -} - -void syslog_logger::info(const std::string& line) -{ - syslog(LOG_INFO | LOG_USER, "%s", line.c_str()); -} - -void syslog_logger::warning(const std::string& line) -{ - syslog(LOG_WARNING | LOG_USER, "%s", line.c_str()); -} - -void syslog_logger::debug(const std::string& line) -{ - syslog(LOG_DEBUG | LOG_USER, "%s", line.c_str()); -} - -#endif // !HAVE_SYSLOG - -/* - * Functions - * ------------------------------------------------------------------ - */ - -void set_logger(std::unique_ptr<logger> new_iface) noexcept -{ - assert(new_iface); - - use_iface = std::move(new_iface); -} - -void set_filter(std::unique_ptr<filter> newfilter) noexcept -{ - assert(newfilter); - - use_filter = std::move(newfilter); -} - -std::ostream& info(const std::string& message) -{ - if (!message.empty()) - stream_info << message << std::endl; - - return stream_info; -} - -std::ostream& warning(const std::string& message) -{ - if (!message.empty()) - stream_warning << message << std::endl; - - return stream_warning; -} - -std::ostream& debug(const std::string& message) -{ - if (!message.empty()) - stream_debug << message << std::endl; - - return stream_debug; -} - -bool is_verbose() noexcept -{ - return verbose; -} - -void set_verbose(bool mode) noexcept -{ - verbose = mode; -} - -} // !log - -} // !irccd
--- a/libcommon/irccd/logger.hpp Wed Dec 06 14:12:57 2017 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,345 +0,0 @@ -/* - * logger.hpp -- irccd logging - * - * Copyright (c) 2013-2017 David Demelier <markand@malikania.fr> - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#ifndef IRCCD_LOGGER_HPP -#define IRCCD_LOGGER_HPP - -/** - * \file logger.hpp - * \brief Logging facilities. - */ - -#include <memory> -#include <sstream> -#include <utility> - -#include "sysconfig.hpp" - -namespace irccd { - -namespace log { - -/* - * logger -- abstract logging interface - * ------------------------------------------------------------------ - */ - -/** - * \brief Interface to implement new logger mechanisms. - * - * Derive from this class and use log::set_logger() to change logging system. - * - * \see file_logger - * \see console_logger - * \see syslog_logger - * \see silent_logger - */ -class logger { -public: - /** - * Virtual destructor defaulted. - */ - virtual ~logger() = default; - - /** - * Write a debug message. - * - * This function is called only if NDEBUG is not defined. - * - * \param line the data - * \see log::debug - */ - virtual void debug(const std::string& line) = 0; - - /** - * Write a information message. - * - * The function is called only if verbose is true. - * - * \param line the data - * \see log::info - */ - virtual void info(const std::string& line) = 0; - - /** - * Write an error message. - * - * This function is always called. - * - * \param line the data - * \see log::warning - */ - virtual void warning(const std::string& line) = 0; -}; - -/* - * filter -- modify messages before printing - * ------------------------------------------------------------------ - */ - -/** - * \brief Filter messages before printing them. - * - * Derive from this class and use log::setFilter. - */ -class filter { -public: - /** - * Virtual destructor defaulted. - */ - virtual ~filter() = default; - - /** - * Update the debug message. - * - * \param input the message - * \return the updated message - */ - virtual std::string pre_debug(std::string input) const - { - return input; - } - - /** - * Update the information message. - * - * \param input the message - * \return the updated message - */ - virtual std::string pre_info(std::string input) const - { - return input; - } - - /** - * Update the warning message. - * - * \param input the message - * \return the updated message - */ - virtual std::string pre_warning(std::string input) const - { - return input; - } -}; - -/* - * console_logger -- logs to console - * ------------------------------------------------------------------ - */ - -/** - * \brief Logger implementation for console output using std::cout and - * std::cerr. - */ -class console_logger : public logger { -public: - /** - * \copydoc logger::debug - */ - void debug(const std::string& line) override; - - /** - * \copydoc logger::info - */ - void info(const std::string& line) override; - - /** - * \copydoc logger::warning - */ - void warning(const std::string& line) override; -}; - -/* - * file_logger -- logs to a file - * ------------------------------------------------------------------ - */ - -/** - * \brief Output to a files. - */ -class file_logger : public logger { -private: - std::string output_normal_; - std::string output_error_; - -public: - /** - * Outputs to files. - * - * \param normal the path to the normal logs - * \param errors the path to the errors logs - */ - file_logger(std::string normal, std::string errors); - - /** - * \copydoc logger::debug - */ - void debug(const std::string& line) override; - - /** - * \copydoc logger::info - */ - void info(const std::string& line) override; - - /** - * \copydoc logger::warning - */ - void warning(const std::string& line) override; -}; - -/* - * silent_logger -- disable all logs - * ------------------------------------------------------------------ - */ - -/** - * \brief Use to disable logs. - * - * Useful for unit tests when some classes may emits log. - */ -class silent_logger : public logger { -public: - /** - * \copydoc logger::debug - */ - void debug(const std::string& line) override; - - /** - * \copydoc logger::info - */ - void info(const std::string& line) override; - - /** - * \copydoc logger::warning - */ - void warning(const std::string& line) override; -}; - -/* - * syslog_logger -- system logger - * ------------------------------------------------------------------ - */ - -#if defined(HAVE_SYSLOG) - -/** - * \brief Implements logger into syslog. - */ -class syslog_logger : public logger { -public: - /** - * Open the syslog. - */ - syslog_logger(); - - /** - * Close the syslog. - */ - ~syslog_logger(); - - /** - * \copydoc logger::debug - */ - void debug(const std::string& line) override; - - /** - * \copydoc logger::info - */ - void info(const std::string& line) override; - - /** - * \copydoc logger::warning - */ - void warning(const std::string& line) override; -}; - -#endif // !HAVE_SYSLOG - -/* - * Functions - * ------------------------------------------------------------------ - */ - -/** - * Update the logger interface. - * - * \pre iface must not be null - * \param iface the new interface - */ -IRCCD_EXPORT void set_logger(std::unique_ptr<logger> iface) noexcept; - -/** - * Set an optional filter. - * - * \pre filter must not be null - * \param filter the filter - */ -IRCCD_EXPORT void set_filter(std::unique_ptr<filter> 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 - * \note Has no effect if verbose is set to false. - */ -IRCCD_EXPORT std::ostream& info(const std::string& message = ""); - -/** - * 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 - */ -IRCCD_EXPORT std::ostream& warning(const std::string& message = ""); - -/** - * 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 - * \note Has no effect if compiled in release mode. - */ -IRCCD_EXPORT std::ostream& debug(const std::string& message = ""); - -/** - * Tells if verbose is enabled. - * - * \return true if enabled - */ -IRCCD_EXPORT bool is_verbose() noexcept; - -/** - * Set the verbosity mode. - * - * \param mode the new mode - */ -IRCCD_EXPORT void set_verbose(bool mode) noexcept; - -} // !log - -} // !irccd - -#endif // !IRCCD_LOGGER_HPP
--- a/libirccd-js/irccd/js/logger_jsapi.cpp Wed Dec 06 14:12:57 2017 +0100 +++ b/libirccd-js/irccd/js/logger_jsapi.cpp Wed Dec 06 21:32:10 2017 +0100 @@ -16,8 +16,10 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#include <irccd/logger.hpp> +#include <irccd/daemon/logger.hpp> +#include <irccd/daemon/irccd.hpp> +#include "irccd_jsapi.hpp" #include "js_plugin.hpp" #include "logger_jsapi.hpp" #include "plugin_jsapi.hpp" @@ -44,7 +46,7 @@ */ duk_ret_t info(duk_context* ctx) { - return print(ctx, log::info()); + return print(ctx, dukx_get_irccd(ctx).log().info()); } /* @@ -58,7 +60,7 @@ */ duk_ret_t warning(duk_context* ctx) { - return print(ctx, log::warning()); + return print(ctx, dukx_get_irccd(ctx).log().warning()); } /* @@ -72,7 +74,7 @@ */ duk_ret_t debug(duk_context* ctx) { - return print(ctx, log::debug()); + return print(ctx, dukx_get_irccd(ctx).log().debug()); } const duk_function_list_entry functions[] = {
--- a/libirccd-js/irccd/js/timer_jsapi.cpp Wed Dec 06 14:12:57 2017 +0100 +++ b/libirccd-js/irccd/js/timer_jsapi.cpp Wed Dec 06 21:32:10 2017 +0100 @@ -18,9 +18,8 @@ #include <boost/asio.hpp> -#include <irccd/logger.hpp> - #include <irccd/daemon/irccd.hpp> +#include <irccd/daemon/logger.hpp> #include "irccd_jsapi.hpp" #include "js_plugin.hpp" @@ -86,8 +85,10 @@ duk_remove(ctx, -2); if (duk_pcall(ctx, 0)) { - log::warning() << "plugin: " << plugin->name() << " timer error:" << std::endl; - log::warning() << " " << dukx_stack(ctx, -1).what() << std::endl; + dukx_get_irccd(ctx).log().warning() << "plugin: " << plugin->name() + << " timer error:" << std::endl; + dukx_get_irccd(ctx).log().warning() << " " + << dukx_stack(ctx, -1).what() << std::endl; } else duk_pop(ctx); } @@ -188,7 +189,7 @@ duk_del_prop_string(ctx, -1, ptr->key().c_str()); duk_pop(ctx); - log::debug("timer: destroyed"); + dukx_get_irccd(ctx).log().debug("timer: destroyed"); delete ptr;
--- a/libirccd-test/irccd/command_test.hpp Wed Dec 06 14:12:57 2017 +0100 +++ b/libirccd-test/irccd/command_test.hpp Wed Dec 06 21:32:10 2017 +0100 @@ -21,11 +21,10 @@ #include <memory> -#include <irccd/logger.hpp> - #include <irccd/daemon/command_service.hpp> #include <irccd/daemon/ip_transport_server.hpp> #include <irccd/daemon/irccd.hpp> +#include <irccd/daemon/logger.hpp> #include <irccd/daemon/transport_service.hpp> #include <irccd/ctl/ip_connection.hpp> @@ -79,8 +78,6 @@ { using boost::asio::ip::tcp; - log::set_logger(std::make_unique<log::silent_logger>()); - // Bind to a random port. tcp::endpoint ep(tcp::v4(), 0); tcp::acceptor acc(service_, ep); @@ -91,6 +88,7 @@ // Add the server and the command. add<Commands...>(); + daemon_->set_log(std::make_unique<silent_logger>()); daemon_->transports().add(std::make_unique<ip_transport_server>(std::move(acc))); timer_.expires_from_now(boost::posix_time::seconds(10));
--- a/libirccd-test/irccd/js_test.hpp Wed Dec 06 14:12:57 2017 +0100 +++ b/libirccd-test/irccd/js_test.hpp Wed Dec 06 21:32:10 2017 +0100 @@ -26,9 +26,8 @@ #include <boost/asio.hpp> -#include <irccd/logger.hpp> - #include <irccd/daemon/irccd.hpp> +#include <irccd/daemon/logger.hpp> #include <irccd/js/js_plugin.hpp> #include <irccd/js/irccd_jsapi.hpp> @@ -71,7 +70,7 @@ : plugin_(new js_plugin("test", plugin_path)) , server_(new journal_server(service_, "test")) { - log::set_logger(std::make_unique<log::silent_logger>()); + irccd_.set_log(std::make_unique<silent_logger>()); // Irccd is mandatory at the moment. add<irccd_jsapi>();
--- a/libirccd-test/irccd/plugin_test.cpp Wed Dec 06 14:12:57 2017 +0100 +++ b/libirccd-test/irccd/plugin_test.cpp Wed Dec 06 21:32:10 2017 +0100 @@ -18,8 +18,7 @@ #include <cassert> -#include <irccd/logger.hpp> - +#include <irccd/daemon/logger.hpp> #include <irccd/daemon/plugin_service.hpp> #include <irccd/daemon/server_service.hpp> @@ -43,12 +42,11 @@ plugin_test::plugin_test(std::string name, std::string path) : server_(std::make_shared<journal_server>(service_, "test")) { - log::set_verbose(false); - log::set_logger(std::make_unique<log::silent_logger>()); - server_->set_nickname("irccd"); plugin_ = std::make_unique<js_plugin>(std::move(name), std::move(path)); + irccd_.log().set_verbose(false); + irccd_.set_log(std::make_unique<silent_logger>()); irccd_.plugins().add(plugin_); irccd_.servers().add(server_);
--- a/libirccd/CMakeLists.txt Wed Dec 06 14:12:57 2017 +0100 +++ b/libirccd/CMakeLists.txt Wed Dec 06 21:32:10 2017 +0100 @@ -32,6 +32,7 @@ ${libirccd_SOURCE_DIR}/irccd/daemon/irccd.hpp ${libirccd_SOURCE_DIR}/irccd/daemon/irc.hpp ${libirccd_SOURCE_DIR}/irccd/daemon/local_transport_server.hpp + ${libirccd_SOURCE_DIR}/irccd/daemon/logger.hpp ${libirccd_SOURCE_DIR}/irccd/daemon/plugin.hpp ${libirccd_SOURCE_DIR}/irccd/daemon/plugin_service.hpp ${libirccd_SOURCE_DIR}/irccd/daemon/rule.hpp @@ -52,6 +53,7 @@ ${libirccd_SOURCE_DIR}/irccd/daemon/dynlib_plugin.cpp ${libirccd_SOURCE_DIR}/irccd/daemon/irccd.cpp ${libirccd_SOURCE_DIR}/irccd/daemon/irc.cpp + ${libirccd_SOURCE_DIR}/irccd/daemon/logger.cpp ${libirccd_SOURCE_DIR}/irccd/daemon/plugin.cpp ${libirccd_SOURCE_DIR}/irccd/daemon/plugin_service.cpp ${libirccd_SOURCE_DIR}/irccd/daemon/rule.cpp
--- a/libirccd/irccd/daemon/irccd.cpp Wed Dec 06 14:12:57 2017 +0100 +++ b/libirccd/irccd/daemon/irccd.cpp Wed Dec 06 21:32:10 2017 +0100 @@ -16,12 +16,12 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#include <irccd/logger.hpp> #include <irccd/string_util.hpp> #include <irccd/system.hpp> #include "command_service.hpp" #include "irccd.hpp" +#include "logger.hpp" #include "plugin_service.hpp" #include "rule_service.hpp" #include "server_service.hpp" @@ -31,7 +31,7 @@ namespace { -class log_filter : public log::filter { +class log_filter : public logger_filter { private: std::string info_; std::string warning_; @@ -74,7 +74,9 @@ } }; -void load_log_file(const ini::section& sc) +} // !namespace + +void irccd::load_logs_file(const ini::section& sc) { /* * TODO: improve that with CMake options. @@ -95,23 +97,21 @@ errors = it->value(); try { - log::set_logger(std::make_unique<log::file_logger>(std::move(normal), std::move(errors))); + logger_ = std::make_unique<file_logger>(std::move(normal), std::move(errors)); } catch (const std::exception& ex) { - log::warning() << "logs: " << ex.what() << std::endl; + logger_->warning() << "logs: " << ex.what() << std::endl; } } -void load_log_syslog() +void irccd::load_logs_syslog() { #if defined(HAVE_SYSLOG) - log::set_logger(std::make_unique<log::syslog_logger>()); + logger_ = std::make_unique<syslog_logger>(); #else - log::warning() << "logs: syslog is not available on this platform" << std::endl; + logger_->warning() << "logs: syslog is not available on this platform" << std::endl; #endif // !HAVE_SYSLOG } -} // !namespace - void irccd::load_logs() { auto sc = config_.section("logs"); @@ -119,18 +119,18 @@ if (sc.empty()) return; - log::set_verbose(string_util::is_identifier(sc.get("verbose").value())); + logger_->set_verbose(string_util::is_identifier(sc.get("verbose").value())); auto type = sc.get("type").value(); if (!type.empty()) { // Console is the default, no test case. if (type == "file") - load_log_file(sc); + load_logs_file(sc); else if (type == "syslog") - load_log_syslog(); + load_logs_syslog(); else if (type != "console") - log::warning() << "logs: invalid log type '" << type << std::endl; + logger_->warning() << "logs: invalid log type '" << type << std::endl; } } @@ -141,7 +141,7 @@ if (sc.empty()) return; - log::set_filter(std::make_unique<log_filter>( + logger_->set_filter(std::make_unique<log_filter>( sc.get("info").value(), sc.get("warning").value(), sc.get("debug").value() @@ -159,13 +159,13 @@ std::ofstream out(path, std::ofstream::trunc); if (!out) - log::warning() << "irccd: could not open" << path << ": " << std::strerror(errno) << std::endl; + logger_->warning() << "irccd: could not open" << path << ": " << std::strerror(errno) << std::endl; else { - log::debug() << "irccd: pid written in " << path << std::endl; + logger_->debug() << "irccd: pid written in " << path << std::endl; out << getpid() << std::endl; } #else - log::warning() << "irccd: pidfile not supported on this platform" << std::endl; + logger_->warning() << "irccd: pidfile not supported on this platform" << std::endl; #endif } @@ -179,12 +179,12 @@ #if defined(HAVE_SETGID) try { sys::set_gid(gid); - log::info() << "irccd: setting gid to: " << gid << std::endl; + logger_->info() << "irccd: setting gid to: " << gid << std::endl; } catch (const std::exception& ex) { - log::warning() << "irccd: failed to set gid: " << ex.what() << std::endl; + logger_->warning() << "irccd: failed to set gid: " << ex.what() << std::endl; } #else - log::warning() << "irccd: gid option not supported" << std::endl; + logger_->warning() << "irccd: gid option not supported" << std::endl; #endif } @@ -198,28 +198,36 @@ #if defined(HAVE_SETUID) try { sys::set_uid(uid); - log::info() << "irccd: setting uid to: " << uid << std::endl; + logger_->info() << "irccd: setting uid to: " << uid << std::endl; } catch (const std::exception& ex) { - log::warning() << "irccd: failed to set uid: " << ex.what() << std::endl; + logger_->warning() << "irccd: failed to set uid: " << ex.what() << std::endl; } #else - log::warning() << "irccd: uid option not supported" << std::endl; + logger_->warning() << "irccd: uid option not supported" << std::endl; #endif } irccd::irccd(boost::asio::io_service& service, std::string config) : config_(std::move(config)) , service_(service) + , logger_(std::make_unique<console_logger>()) , command_service_(std::make_unique<command_service>()) , server_service_(std::make_unique<server_service>(*this)) , tpt_service_(std::make_unique<transport_service>(*this)) - , rule_service_(std::make_unique<rule_service>()) + , rule_service_(std::make_unique<rule_service>(*this)) , plugin_service_(std::make_unique<plugin_service>(*this)) { } irccd::~irccd() = default; +void irccd::set_log(std::unique_ptr<logger> logger) noexcept +{ + assert(logger); + + logger_ = std::move(logger); +} + void irccd::load() noexcept { /* @@ -234,9 +242,9 @@ load_formats(); if (!loaded_) - log::info() << "irccd: loading configuration from " << config_.path() << std::endl; + logger_->info() << "irccd: loading configuration from " << config_.path() << std::endl; else - log::info() << "irccd: reloading configuration" << std::endl; + logger_->info() << "irccd: reloading configuration" << std::endl; // [general] section. if (!loaded_) {
--- a/libirccd/irccd/daemon/irccd.hpp Wed Dec 06 14:12:57 2017 +0100 +++ b/libirccd/irccd/daemon/irccd.hpp Wed Dec 06 21:32:10 2017 +0100 @@ -38,6 +38,7 @@ namespace irccd { class command_service; +class logger; class plugin_service; class rule_service; class server_service; @@ -57,6 +58,9 @@ // Tells if the configuration has already been called. bool loaded_{false}; + // Custom logger. + std::unique_ptr<logger> logger_; + // Services. std::shared_ptr<command_service> command_service_; std::shared_ptr<server_service> server_service_; @@ -72,6 +76,8 @@ irccd& operator=(irccd&&) = delete; // Load functions. + void load_logs_file(const ini::section&); + void load_logs_syslog(); void load_logs(); void load_formats(); void load_pid(); @@ -133,6 +139,34 @@ } /** + * Access the logger. + * + * \return the logger + */ + inline const logger& log() const noexcept + { + return *logger_; + } + + /** + * Overloaded function. + * + * \return the logger + */ + inline logger& log() noexcept + { + return *logger_; + } + + /** + * Set the logger. + * + * \pre logger != nullptr + * \param logger the new logger + */ + void set_log(std::unique_ptr<logger> logger) noexcept; + + /** * Access the command service. * * \return the service
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libirccd/irccd/daemon/logger.cpp Wed Dec 06 21:32:10 2017 +0100 @@ -0,0 +1,251 @@ +/* + * logger.cpp -- irccd logging + * + * Copyright (c) 2013-2017 David Demelier <markand@malikania.fr> + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include <atomic> +#include <cassert> +#include <cerrno> +#include <cstring> +#include <fstream> +#include <iostream> +#include <stdexcept> +#include <streambuf> + +#include "logger.hpp" +#include "system.hpp" + +#if defined(HAVE_SYSLOG) +# include <syslog.h> +#endif // !HAVE_SYSLOG + +namespace irccd { + +void logger::buffer::debug(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))); +#else + (void)line; +#endif +} + +void logger::buffer::info(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))); +} + +void logger::buffer::warning(std::string line) +{ + parent_.write_warning(parent_.filter_->pre_warning(std::move(line))); +} + +logger::buffer::buffer(logger& parent, level level) noexcept + : parent_(parent) + , level_(level) +{ + assert(level >= level::debug && level <= level::warning); +} + +int logger::buffer::sync() +{ + std::string buffer = str(); + std::string::size_type pos; + + while ((pos = buffer.find("\n")) != std::string::npos) { + auto line = buffer.substr(0, pos); + + // Remove this line. + buffer.erase(buffer.begin(), buffer.begin() + pos + 1); + + switch (level_) { + case level::debug: + debug(std::move(line)); + break; + case level::info: + info(std::move(line)); + break; + case level::warning: + warning(std::move(line)); + break; + default: + break; + } + } + + str(buffer); + + return 0; +} + +/* + * console_logger + * ------------------------------------------------------------------ + */ + +void console_logger::write_info(const std::string& line) +{ + std::cout << line << std::endl; +} + +void console_logger::write_warning(const std::string& line) +{ + std::cerr << line << std::endl; +} + +void console_logger::write_debug(const std::string& line) +{ + std::cout << line << std::endl; +} + +/* + * file_logger + * ------------------------------------------------------------------ + */ + +file_logger::file_logger(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) +{ + std::ofstream(output_normal_, std::ofstream::out | std::ofstream::app) << line << std::endl; +} + +void file_logger::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) +{ + 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_logger::write_warning(const std::string&) +{ +} + +void silent_logger::write_debug(const std::string&) +{ +} + +/* + * syslog_logger + * ------------------------------------------------------------------ + */ + +#if defined(HAVE_SYSLOG) + +syslog_logger::syslog_logger() +{ + openlog("irccd", LOG_PID, LOG_DAEMON); +} + +syslog_logger::~syslog_logger() +{ + closelog(); +} + +void syslog_logger::write_info(const std::string& line) +{ + syslog(LOG_INFO | LOG_USER, "%s", line.c_str()); +} + +void syslog_logger::write_warning(const std::string& line) +{ + syslog(LOG_WARNING | LOG_USER, "%s", line.c_str()); +} + +void syslog_logger::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<logger_filter>()) +{ +} + +bool logger::is_verbose() const noexcept +{ + return verbose_; +} + +void logger::set_verbose(bool mode) noexcept +{ + verbose_ = mode; +} + +void logger::set_filter(std::unique_ptr<logger_filter> newfilter) noexcept +{ + assert(newfilter); + + filter_ = std::move(newfilter); +} + +std::ostream& logger::info(const std::string& message) +{ + if (!message.empty()) + stream_info_ << message << std::endl; + + return stream_info_; +} + +std::ostream& logger::warning(const std::string& message) +{ + if (!message.empty()) + stream_warning_ << message << std::endl; + + return stream_warning_; +} + +std::ostream& logger::debug(const std::string& message) +{ + if (!message.empty()) + stream_debug_ << message << std::endl; + + return stream_debug_; +} + +} // !irccd
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libirccd/irccd/daemon/logger.hpp Wed Dec 06 21:32:10 2017 +0100 @@ -0,0 +1,346 @@ +/* + * logger.hpp -- irccd logging + * + * Copyright (c) 2013-2017 David Demelier <markand@malikania.fr> + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef IRCCD_DAEMON_LOGGER_HPP +#define IRCCD_DAEMON_LOGGER_HPP + +/** + * \file logger.hpp + * \brief Logging facilities. + */ + +#include <memory> +#include <sstream> +#include <utility> + +#include "sysconfig.hpp" + +namespace irccd { + +class logger_filter; + +/** + * \brief Interface to implement new logger mechanisms. + * + * 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 + */ +class logger { +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_; + + // User options. + bool verbose_{false}; + std::unique_ptr<logger_filter> filter_; + +protected: + /** + * Write a debug message. + * + * This function is called only if NDEBUG is not defined. + * + * \param line the data + * \see log::debug + */ + virtual void write_debug(const std::string& line) = 0; + + /** + * Write a information message. + * + * The function is called only if verbose is true. + * + * \param line the data + * \see log::info + */ + virtual void write_info(const std::string& line) = 0; + + /** + * Write an error message. + * + * This function is always called. + * + * \param line the data + * \see log::warning + */ + virtual void write_warning(const std::string& line) = 0; + +public: + /** + * Default constructor. + */ + logger(); + + /** + * Virtual destructor defaulted. + */ + virtual ~logger() = default; + + /** + * Tells if logger is verbose. + * + * \return true if verbose + */ + bool is_verbose() const noexcept; + + /** + * Set the verbosity mode. + * + * \param mode the new mode + */ + void set_verbose(bool mode) noexcept; + + /** + * Set an optional filter. + * + * \pre filter must not be null + * \param filter the filter + */ + void set_filter(std::unique_ptr<logger_filter> newfilter) 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 + * \note Has no effect if verbose is set to false. + */ + std::ostream& info(const std::string& message = ""); + + /** + * 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 + */ + std::ostream& warning(const std::string& message = ""); + + /** + * 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 + * \note Has no effect if compiled in release mode. + */ + std::ostream& debug(const std::string& message = ""); +}; + +/** + * \brief Filter messages before printing them. + * + * Derive from this class and use log::setFilter. + */ +class logger_filter { +public: + /** + * Virtual destructor defaulted. + */ + virtual ~logger_filter() = default; + + /** + * Update the debug message. + * + * \param input the message + * \return the updated message + */ + virtual std::string pre_debug(std::string input) const + { + return input; + } + + /** + * Update the information message. + * + * \param input the message + * \return the updated message + */ + virtual std::string pre_info(std::string input) const + { + return input; + } + + /** + * Update the warning message. + * + * \param input the message + * \return the updated message + */ + virtual std::string pre_warning(std::string input) const + { + return input; + } +}; + +/** + * \brief Logger implementation for console output using std::cout and + * std::cerr. + */ +class console_logger : public logger { +protected: + /** + * \copydoc logger::debug + */ + void write_debug(const std::string& line) override; + + /** + * \copydoc logger::info + */ + void write_info(const std::string& line) override; + + /** + * \copydoc logger::warning + */ + void write_warning(const std::string& line) override; +}; + +/** + * \brief Output to a files. + */ +class file_logger : public logger { +private: + std::string output_normal_; + std::string output_error_; + +protected: + /** + * \copydoc logger::debug + */ + void write_debug(const std::string& line) override; + + /** + * \copydoc logger::info + */ + void write_info(const std::string& line) override; + + /** + * \copydoc logger::warning + */ + void write_warning(const std::string& line) override; + +public: + /** + * Outputs to files. + * + * \param normal the path to the normal logs + * \param errors the path to the errors logs + */ + file_logger(std::string normal, std::string errors); +}; + +/** + * \brief Use to disable logs. + * + * Useful for unit tests when some classes may emits log. + */ +class silent_logger : public logger { +protected: + /** + * \copydoc logger::debug + */ + void write_debug(const std::string& line) override; + + /** + * \copydoc logger::info + */ + void write_info(const std::string& line) override; + + /** + * \copydoc logger::warning + */ + void write_warning(const std::string& line) override; +}; + +#if defined(HAVE_SYSLOG) + +/** + * \brief Implements logger into syslog. + */ +class syslog_logger : public logger { +protected: + /** + * \copydoc logger::debug + */ + void write_debug(const std::string& line) override; + + /** + * \copydoc logger::info + */ + void write_info(const std::string& line) override; + + /** + * \copydoc logger::warning + */ + void write_warning(const std::string& line) override; + +public: + /** + * Open the syslog. + */ + syslog_logger(); + + /** + * Close the syslog. + */ + ~syslog_logger(); +}; + +#endif // !HAVE_SYSLOG + +} // !irccd + +#endif // !IRCCD_DAEMON_LOGGER_HPP
--- a/libirccd/irccd/daemon/plugin_service.cpp Wed Dec 06 14:12:57 2017 +0100 +++ b/libirccd/irccd/daemon/plugin_service.cpp Wed Dec 06 21:32:10 2017 +0100 @@ -17,8 +17,8 @@ */ #include <irccd/string_util.hpp> -#include <irccd/logger.hpp> +#include "logger.hpp" #include "config.hpp" #include "irccd.hpp" #include "plugin_service.hpp" @@ -53,7 +53,7 @@ try { plugin->on_unload(irccd_); } catch (const std::exception& ex) { - log::warning() << "plugin: " << plugin->name() << ": " << ex.what() << std::endl; + irccd_.log().warning() << "plugin: " << plugin->name() << ": " << ex.what() << std::endl; } } } @@ -223,7 +223,7 @@ try { load(name, option.value()); } catch (const std::exception& ex) { - log::warning(ex.what()); + irccd_.log().warning(ex.what()); } } }
--- a/libirccd/irccd/daemon/rule_service.cpp Wed Dec 06 14:12:57 2017 +0100 +++ b/libirccd/irccd/daemon/rule_service.cpp Wed Dec 06 21:32:10 2017 +0100 @@ -18,10 +18,11 @@ #include <stdexcept> -#include <irccd/logger.hpp> #include <irccd/string_util.hpp> #include "config.hpp" +#include "irccd.hpp" +#include "logger.hpp" #include "rule_service.hpp" #include "string_util.hpp" @@ -77,6 +78,11 @@ } // !namespace +rule_service::rule_service(irccd &irccd) + : irccd_(irccd) +{ +} + void rule_service::add(rule rule) { rules_.push_back(std::move(rule)); @@ -120,20 +126,20 @@ { bool result = true; - log::debug(string_util::sprintf("rule: solving for server=%s, channel=%s, origin=%s, plugin=%s, event=%s", + irccd_.log().debug(string_util::sprintf("rule: solving for server=%s, channel=%s, origin=%s, plugin=%s, event=%s", server, channel, origin, plugin, event)); int i = 0; for (const auto& rule : rules_) { auto action = rule.action() == rule::action_type::accept ? "accept" : "drop"; - log::debug() << " candidate " << i++ << ":\n" - << " servers: " << string_util::join(rule.servers()) << "\n" - << " channels: " << string_util::join(rule.channels()) << "\n" - << " origins: " << string_util::join(rule.origins()) << "\n" - << " plugins: " << string_util::join(rule.plugins()) << "\n" - << " events: " << string_util::join(rule.events()) << "\n" - << " action: " << action << std::endl; + irccd_.log().debug() << " candidate " << i++ << ":\n" + << " servers: " << string_util::join(rule.servers()) << "\n" + << " channels: " << string_util::join(rule.channels()) << "\n" + << " origins: " << string_util::join(rule.origins()) << "\n" + << " plugins: " << string_util::join(rule.plugins()) << "\n" + << " events: " << string_util::join(rule.events()) << "\n" + << " action: " << action << std::endl; if (rule.match(server, channel, origin, plugin, event)) result = rule.action() == rule::action_type::accept; @@ -153,7 +159,7 @@ try { rules_.push_back(load_rule(section)); } catch (const std::exception& ex) { - log::warning() << "rule: " << ex.what() << std::endl; + irccd_.log().warning() << "rule: " << ex.what() << std::endl; } } }
--- a/libirccd/irccd/daemon/rule_service.hpp Wed Dec 06 14:12:57 2017 +0100 +++ b/libirccd/irccd/daemon/rule_service.hpp Wed Dec 06 21:32:10 2017 +0100 @@ -31,6 +31,7 @@ namespace irccd { class config; +class irccd; /** * \brief Store and solve rules. @@ -38,10 +39,16 @@ */ class rule_service { private: + irccd& irccd_; std::vector<rule> rules_; public: /** + * Create the rule service. + */ + rule_service(irccd& instance); + + /** * Get the list of rules. * * \return the list of rules
--- a/libirccd/irccd/daemon/server.cpp Wed Dec 06 14:12:57 2017 +0100 +++ b/libirccd/irccd/daemon/server.cpp Wed Dec 06 21:32:10 2017 +0100 @@ -31,7 +31,6 @@ #endif #include "json_util.hpp" -#include "logger.hpp" #include "server.hpp" #include "string_util.hpp" #include "system.hpp" @@ -138,10 +137,8 @@ state_ = state_t::connected; on_connect({shared_from_this()}); - for (const auto& channel : rchannels_) { - log::info() << "server " << name_ << ": auto joining " << channel.name << std::endl; + for (const auto& channel : rchannels_) join(channel.name, channel.password); - } } void server::dispatch_endofnames(const irc::message& msg) @@ -202,6 +199,7 @@ if (msg.arg(i).compare(0, 6, "PREFIX") == 0) { modes_ = isupport_extract_prefixes(msg.arg(i)); +#if 0 #if !defined(NDEBUG) auto show = [this] (auto mode, auto title) { auto it = modes_.find(mode); @@ -217,6 +215,7 @@ show(channel_mode::protection, "protection"); show(channel_mode::voiced, "voiced"); #endif // !NDEBUG +#endif break; } @@ -443,9 +442,6 @@ { assert(state_ == state_t::identifying); - log::debug(string_util::sprintf("server %s: connected, identifying", name_)); - log::debug(string_util::sprintf("server %s: verifying server", name_)); - if (!password_.empty()) conn_->send(string_util::sprintf("PASS %s", password_)); @@ -468,20 +464,17 @@ { if (code) { conn_ = nullptr; +#if 0 log::warning(string_util::sprintf("server %s: error while connecting", name_)); log::warning(string_util::sprintf("server %s: %s", name_, code.message())); +#endif // Wait before reconnecting. if (recotries_ != 0) { if (recotries_ > 0 && recocur_ >= recotries_) { - log::warning() << "server " << name_ << ": giving up" << std::endl; - state_ = state_t::disconnected; on_die(); } else { - log::warning() << "server " << name_ << ": retrying in " << - recodelay_ << " seconds" << std::endl; - state_ = state_t::waiting; wait(); } @@ -518,6 +511,7 @@ void server::connect() noexcept { assert(state_ == state_t::disconnected || state_ == state_t::waiting); + /* * This is needed if irccd is started before DHCP or if DNS cache is * outdated.
--- a/libirccd/irccd/daemon/server_service.cpp Wed Dec 06 14:12:57 2017 +0100 +++ b/libirccd/irccd/daemon/server_service.cpp Wed Dec 06 21:32:10 2017 +0100 @@ -43,16 +43,17 @@ auto allowed = daemon.rules().solve(server, target, origin, plugin->name(), eventname); if (!allowed) { - log::debug() << "rule: event skipped on match" << std::endl; + daemon.log().debug("rule: event skipped on match"); continue; } - log::debug() << "rule: event allowed" << std::endl; + daemon.log().debug("rule: event allowed"); try { exec_func(*plugin); } catch (const std::exception& ex) { - log::warning() << "plugin " << plugin->name() << ": error: " << ex.what() << std::endl; + daemon.log().warning() << "plugin " << plugin->name() << ": error: " + << ex.what() << std::endl; } } } @@ -118,7 +119,7 @@ if (value.empty()) throw server_error(server_error::invalid_hostname, name); - return name; + return value.value(); } std::string to_host(const nlohmann::json& object, const std::string& name) @@ -242,7 +243,7 @@ void server_service::handle_connect(const connect_event& ev) { - log::debug() << "server " << ev.server->name() << ": event onConnect" << std::endl; + irccd_.log().debug() << "server " << ev.server->name() << ": event onConnect" << std::endl; irccd_.transports().broadcast(nlohmann::json::object({ { "event", "onConnect" }, @@ -261,10 +262,10 @@ void server_service::handle_invite(const invite_event& ev) { - log::debug() << "server " << ev.server->name() << ": event onInvite:\n"; - log::debug() << " origin: " << ev.origin << "\n"; - log::debug() << " channel: " << ev.channel << "\n"; - log::debug() << " target: " << ev.nickname << std::endl; + irccd_.log().debug() << "server " << ev.server->name() << ": event onInvite:\n"; + irccd_.log().debug() << " origin: " << ev.origin << "\n"; + irccd_.log().debug() << " channel: " << ev.channel << "\n"; + irccd_.log().debug() << " target: " << ev.nickname << std::endl; irccd_.transports().broadcast(nlohmann::json::object({ { "event", "onInvite" }, @@ -285,9 +286,9 @@ void server_service::handle_join(const join_event& ev) { - log::debug() << "server " << ev.server->name() << ": event onJoin:\n"; - log::debug() << " origin: " << ev.origin << "\n"; - log::debug() << " channel: " << ev.channel << std::endl; + irccd_.log().debug() << "server " << ev.server->name() << ": event onJoin:\n"; + irccd_.log().debug() << " origin: " << ev.origin << "\n"; + irccd_.log().debug() << " channel: " << ev.channel << std::endl; irccd_.transports().broadcast(nlohmann::json::object({ { "event", "onJoin" }, @@ -308,11 +309,11 @@ void server_service::handle_kick(const kick_event& ev) { - log::debug() << "server " << ev.server->name() << ": event onKick:\n"; - log::debug() << " origin: " << ev.origin << "\n"; - log::debug() << " channel: " << ev.channel << "\n"; - log::debug() << " target: " << ev.target << "\n"; - log::debug() << " reason: " << ev.reason << std::endl; + irccd_.log().debug() << "server " << ev.server->name() << ": event onKick:\n"; + irccd_.log().debug() << " origin: " << ev.origin << "\n"; + irccd_.log().debug() << " channel: " << ev.channel << "\n"; + irccd_.log().debug() << " target: " << ev.target << "\n"; + irccd_.log().debug() << " reason: " << ev.reason << std::endl; irccd_.transports().broadcast(nlohmann::json::object({ { "event", "onKick" }, @@ -335,10 +336,10 @@ void server_service::handle_message(const message_event& ev) { - log::debug() << "server " << ev.server->name() << ": event onMessage:\n"; - log::debug() << " origin: " << ev.origin << "\n"; - log::debug() << " channel: " << ev.channel << "\n"; - log::debug() << " message: " << ev.message << std::endl; + irccd_.log().debug() << "server " << ev.server->name() << ": event onMessage:\n"; + irccd_.log().debug() << " origin: " << ev.origin << "\n"; + irccd_.log().debug() << " channel: " << ev.channel << "\n"; + irccd_.log().debug() << " message: " << ev.message << std::endl; irccd_.transports().broadcast(nlohmann::json::object({ { "event", "onMessage" }, @@ -372,10 +373,10 @@ void server_service::handle_me(const me_event& ev) { - log::debug() << "server " << ev.server->name() << ": event onMe:\n"; - log::debug() << " origin: " << ev.origin << "\n"; - log::debug() << " target: " << ev.channel << "\n"; - log::debug() << " message: " << ev.message << std::endl; + irccd_.log().debug() << "server " << ev.server->name() << ": event onMe:\n"; + irccd_.log().debug() << " origin: " << ev.origin << "\n"; + irccd_.log().debug() << " target: " << ev.channel << "\n"; + irccd_.log().debug() << " message: " << ev.message << std::endl; irccd_.transports().broadcast(nlohmann::json::object({ { "event", "onMe" }, @@ -397,13 +398,13 @@ void server_service::handle_mode(const mode_event& ev) { - log::debug() << "server " << ev.server->name() << ": event onMode\n"; - log::debug() << " origin: " << ev.origin << "\n"; - log::debug() << " channel: " << ev.channel << "\n"; - log::debug() << " mode: " << ev.mode << "\n"; - log::debug() << " limit: " << ev.limit << "\n"; - log::debug() << " user: " << ev.user << "\n"; - log::debug() << " mask: " << ev.mask << std::endl; + irccd_.log().debug() << "server " << ev.server->name() << ": event onMode\n"; + irccd_.log().debug() << " origin: " << ev.origin << "\n"; + irccd_.log().debug() << " channel: " << ev.channel << "\n"; + irccd_.log().debug() << " mode: " << ev.mode << "\n"; + irccd_.log().debug() << " limit: " << ev.limit << "\n"; + irccd_.log().debug() << " user: " << ev.user << "\n"; + irccd_.log().debug() << " mask: " << ev.mask << std::endl; irccd_.transports().broadcast(nlohmann::json::object({ { "event", "onMode" }, @@ -428,9 +429,9 @@ void server_service::handle_names(const names_event& ev) { - log::debug() << "server " << ev.server->name() << ": event onNames:\n"; - log::debug() << " channel: " << ev.channel << "\n"; - log::debug() << " names: " << string_util::join(ev.names.begin(), ev.names.end(), ", ") << std::endl; + irccd_.log().debug() << "server " << ev.server->name() << ": event onNames:\n"; + irccd_.log().debug() << " channel: " << ev.channel << "\n"; + irccd_.log().debug() << " names: " << string_util::join(ev.names.begin(), ev.names.end(), ", ") << std::endl; auto names = nlohmann::json::array(); @@ -456,9 +457,9 @@ void server_service::handle_nick(const nick_event& ev) { - log::debug() << "server " << ev.server->name() << ": event onNick:\n"; - log::debug() << " origin: " << ev.origin << "\n"; - log::debug() << " nickname: " << ev.nickname << std::endl; + irccd_.log().debug() << "server " << ev.server->name() << ": event onNick:\n"; + irccd_.log().debug() << " origin: " << ev.origin << "\n"; + irccd_.log().debug() << " nickname: " << ev.nickname << std::endl; irccd_.transports().broadcast(nlohmann::json::object({ { "event", "onNick" }, @@ -479,10 +480,10 @@ void server_service::handle_notice(const notice_event& ev) { - log::debug() << "server " << ev.server->name() << ": event onNotice:\n"; - log::debug() << " origin: " << ev.origin << "\n"; - log::debug() << " channel: " << ev.channel << "\n"; - log::debug() << " message: " << ev.message << std::endl; + irccd_.log().debug() << "server " << ev.server->name() << ": event onNotice:\n"; + irccd_.log().debug() << " origin: " << ev.origin << "\n"; + irccd_.log().debug() << " channel: " << ev.channel << "\n"; + irccd_.log().debug() << " message: " << ev.message << std::endl; irccd_.transports().broadcast(nlohmann::json::object({ { "event", "onNotice" }, @@ -504,10 +505,10 @@ void server_service::handle_part(const part_event& ev) { - log::debug() << "server " << ev.server->name() << ": event onPart:\n"; - log::debug() << " origin: " << ev.origin << "\n"; - log::debug() << " channel: " << ev.channel << "\n"; - log::debug() << " reason: " << ev.reason << std::endl; + irccd_.log().debug() << "server " << ev.server->name() << ": event onPart:\n"; + irccd_.log().debug() << " origin: " << ev.origin << "\n"; + irccd_.log().debug() << " channel: " << ev.channel << "\n"; + irccd_.log().debug() << " reason: " << ev.reason << std::endl; irccd_.transports().broadcast(nlohmann::json::object({ { "event", "onPart" }, @@ -529,10 +530,10 @@ void server_service::handle_topic(const topic_event& ev) { - log::debug() << "server " << ev.server->name() << ": event onTopic:\n"; - log::debug() << " origin: " << ev.origin << "\n"; - log::debug() << " channel: " << ev.channel << "\n"; - log::debug() << " topic: " << ev.topic << std::endl; + irccd_.log().debug() << "server " << ev.server->name() << ": event onTopic:\n"; + irccd_.log().debug() << " origin: " << ev.origin << "\n"; + irccd_.log().debug() << " channel: " << ev.channel << "\n"; + irccd_.log().debug() << " topic: " << ev.topic << std::endl; irccd_.transports().broadcast(nlohmann::json::object({ { "event", "onTopic" }, @@ -554,12 +555,12 @@ void server_service::handle_whois(const whois_event& ev) { - log::debug() << "server " << ev.server->name() << ": event onWhois\n"; - log::debug() << " nickname: " << ev.whois.nick << "\n"; - log::debug() << " username: " << ev.whois.user << "\n"; - log::debug() << " host: " << ev.whois.host << "\n"; - log::debug() << " realname: " << ev.whois.realname << "\n"; - log::debug() << " channels: " << string_util::join(ev.whois.channels, ", ") << std::endl; + irccd_.log().debug() << "server " << ev.server->name() << ": event onWhois\n"; + irccd_.log().debug() << " nickname: " << ev.whois.nick << "\n"; + irccd_.log().debug() << " username: " << ev.whois.user << "\n"; + irccd_.log().debug() << " host: " << ev.whois.host << "\n"; + irccd_.log().debug() << " realname: " << ev.whois.realname << "\n"; + irccd_.log().debug() << " channels: " << string_util::join(ev.whois.channels, ", ") << std::endl; irccd_.transports().broadcast(nlohmann::json::object({ { "event", "onWhois" }, @@ -652,7 +653,7 @@ auto server = ptr.lock(); if (server) { - log::info(string_util::sprintf("server %s: removed", server->name())); + irccd_.log().info(string_util::sprintf("server %s: removed", server->name())); servers_.erase(std::find(servers_.begin(), servers_.end(), server)); } }); @@ -712,7 +713,7 @@ try { add(load_server(irccd_.service(), cfg, section)); } catch (const std::exception& ex) { - log::warning() << "server " << section.get("name").value() << ": " + irccd_.log().warning() << "server " << section.get("name").value() << ": " << ex.what() << std::endl; } }
--- a/libirccd/irccd/daemon/transport_service.cpp Wed Dec 06 14:12:57 2017 +0100 +++ b/libirccd/irccd/daemon/transport_service.cpp Wed Dec 06 21:32:10 2017 +0100 @@ -112,10 +112,8 @@ boost::asio::ip::tcp::acceptor acceptor(service, endpoint, true); - if (pkey.empty()) { - log::info() << "transport: listening on " << port << std::endl; + if (pkey.empty()) return std::make_unique<ip_transport_server>(std::move(acceptor)); - } #if defined(HAVE_SSL) boost::asio::ssl::context ctx(boost::asio::ssl::context::sslv23); @@ -123,8 +121,6 @@ ctx.use_private_key_file(pkey, boost::asio::ssl::context::pem); ctx.use_certificate_file(cert, boost::asio::ssl::context::pem); - log::info() << "transport: listening on " << port << " using SSL" << std::endl; - return std::make_unique<tls_transport_server>(std::move(acceptor), std::move(ctx)); #else throw std::invalid_argument("SSL disabled"); @@ -149,8 +145,6 @@ stream_protocol::endpoint endpoint(it->value()); stream_protocol::acceptor acceptor(service, std::move(endpoint)); - log::info() << "transport: listening on " << it->value() << std::endl; - return std::make_unique<local_transport_server>(std::move(acceptor)); #else (void)sc; @@ -205,8 +199,8 @@ } catch (const boost::system::system_error& ex) { tc->error(ex.code(), cmd->name()); } catch (const std::exception& ex) { - log::warning() << "transport: unknown error not reported" << std::endl; - log::warning() << "transport: " << ex.what() << std::endl; + irccd_.log().warning() << "transport: unknown error not reported" << std::endl; + irccd_.log().warning() << "transport: " << ex.what() << std::endl; } } } @@ -216,7 +210,7 @@ tc->recv([this, tc] (auto code, auto json) { switch (code.value()) { case boost::system::errc::network_down: - log::warning("transport: client disconnected"); + irccd_.log().warning("transport: client disconnected"); break; case boost::system::errc::invalid_argument: tc->error(irccd_error::invalid_message); @@ -236,12 +230,12 @@ { ts.accept([this, &ts] (auto code, auto client) { if (code) - log::warning() << "transport: new client error: " << code.message() << std::endl; + irccd_.log().warning() << "transport: new client error: " << code.message() << std::endl; else { do_accept(ts); do_recv(std::move(client)); - log::info() << "transport: new client connected" << std::endl; + irccd_.log().info() << "transport: new client connected" << std::endl; } }); } @@ -279,7 +273,7 @@ try { add(load_transport(irccd_.service(), section)); } catch (const std::exception& ex) { - log::warning() << "transport: " << ex.what() << std::endl; + irccd_.log().warning() << "transport: " << ex.what() << std::endl; } } }
--- a/tests/src/logger-jsapi/main.cpp Wed Dec 06 14:12:57 2017 +0100 +++ b/tests/src/logger-jsapi/main.cpp Wed Dec 06 21:32:10 2017 +0100 @@ -19,7 +19,7 @@ #define BOOST_TEST_MODULE "Logger Javascript API" #include <boost/test/unit_test.hpp> -#include <irccd/logger.hpp> +#include <irccd/daemon/logger.hpp> #include <irccd/js/logger_jsapi.hpp> #include <irccd/js/plugin_jsapi.hpp> @@ -34,7 +34,7 @@ std::string line_warning; std::string line_debug; - class my_logger : public log::logger { + class my_logger : public logger { private: logger_test& test_; @@ -44,17 +44,17 @@ { } - void info(const std::string& line) override + void write_info(const std::string& line) override { test_.line_info = line; } - void warning(const std::string& line) override + void write_warning(const std::string& line) override { test_.line_warning = line; } - void debug(const std::string& line) override + void write_debug(const std::string& line) override { test_.line_debug = line; } @@ -62,8 +62,8 @@ logger_test() { - log::set_verbose(true); - log::set_logger(std::make_unique<my_logger>(*this)); + irccd_.set_log(std::make_unique<my_logger>(*this)); + irccd_.log().set_verbose(true); } };
--- a/tests/src/logger/main.cpp Wed Dec 06 14:12:57 2017 +0100 +++ b/tests/src/logger/main.cpp Wed Dec 06 21:32:10 2017 +0100 @@ -21,65 +21,58 @@ #define BOOST_TEST_MODULE "Logger" #include <boost/test/unit_test.hpp> -#include <irccd/logger.hpp> +#include <irccd/daemon/logger.hpp> namespace irccd { -class logger_test { +class my_logger : public logger { public: std::string line_debug; std::string line_info; std::string line_warning; - class my_logger : public log::logger { - private: - logger_test& test_; - - public: - inline my_logger(logger_test& test) noexcept - : test_(test) - { - } + void write_debug(const std::string& line) override + { + line_debug = line; + } - void debug(const std::string& line) override - { - test_.line_debug = line; - } + void write_info(const std::string& line) override + { + line_info = line; + } - void info(const std::string& line) override - { - test_.line_info = line; - } + void write_warning(const std::string& line) override + { + line_warning = line; + } +}; - void warning(const std::string& line) override - { - test_.line_warning = line; - } - }; +class my_filter : public logger_filter { +public: + std::string pre_debug(std::string input) const override + { + return std::reverse(input.begin(), input.end()), input; + } - class my_filter : public log::filter { - public: - std::string pre_debug(std::string input) const override - { - return std::reverse(input.begin(), input.end()), input; - } + std::string pre_info(std::string input) const override + { + return std::reverse(input.begin(), input.end()), input; + } - std::string pre_info(std::string input) const override - { - return std::reverse(input.begin(), input.end()), input; - } + std::string pre_warning(std::string input) const override + { + return std::reverse(input.begin(), input.end()), input; + } +}; - std::string pre_warning(std::string input) const override - { - return std::reverse(input.begin(), input.end()), input; - } - }; +class logger_test { +public: + my_logger log_; logger_test() { - log::set_logger(std::make_unique<my_logger>(*this)); - log::set_filter(std::make_unique<my_filter>()); - log::set_verbose(true); + log_.set_filter(std::make_unique<my_filter>()); + log_.set_verbose(true); } }; @@ -89,33 +82,33 @@ BOOST_AUTO_TEST_CASE(debug) { - log::debug("debug"); + log_.debug("debug"); - BOOST_REQUIRE_EQUAL("gubed", line_debug); + BOOST_REQUIRE_EQUAL("gubed", log_.line_debug); } #endif BOOST_AUTO_TEST_CASE(info) { - log::info("info"); + log_.info("info"); - BOOST_REQUIRE_EQUAL("ofni", line_info); + BOOST_REQUIRE_EQUAL("ofni", log_.line_info); } BOOST_AUTO_TEST_CASE(info_quiet) { - log::set_verbose(false); - log::info("info"); + log_.set_verbose(false); + log_.info("info"); - BOOST_REQUIRE(line_info.empty()); + BOOST_REQUIRE(log_.line_info.empty()); } BOOST_AUTO_TEST_CASE(warning) { - log::warning("warning"); + log_.warning("warning"); - BOOST_REQUIRE_EQUAL("gninraw", line_warning); + BOOST_REQUIRE_EQUAL("gninraw", log_.line_warning); } BOOST_AUTO_TEST_SUITE_END()
--- a/tests/src/plugin-logger/main.cpp Wed Dec 06 14:12:57 2017 +0100 +++ b/tests/src/plugin-logger/main.cpp Wed Dec 06 21:32:10 2017 +0100 @@ -22,8 +22,6 @@ #define BOOST_TEST_MODULE "Logger plugin" #include <boost/test/unit_test.hpp> -#include <irccd/logger.hpp> - #include <irccd/daemon/irccd.hpp> #include <irccd/daemon/server.hpp>
--- a/tests/src/plugin-plugin/main.cpp Wed Dec 06 14:12:57 2017 +0100 +++ b/tests/src/plugin-plugin/main.cpp Wed Dec 06 21:32:10 2017 +0100 @@ -19,7 +19,6 @@ #define BOOST_TEST_MODULE "Plugin plugin" #include <boost/test/unit_test.hpp> -#include <irccd/logger.hpp> #include <irccd/string_util.hpp> #include <irccd/daemon/irccd.hpp>
--- a/tests/src/rules/main.cpp Wed Dec 06 14:12:57 2017 +0100 +++ b/tests/src/rules/main.cpp Wed Dec 06 21:32:10 2017 +0100 @@ -19,7 +19,8 @@ #define BOOST_TEST_MODULE "Rules" #include <boost/test/unit_test.hpp> -#include <irccd/logger.hpp> +#include <irccd/daemon/irccd.hpp> +#include <irccd/daemon/logger.hpp> #include <irccd/daemon/rule_service.hpp> namespace irccd { @@ -66,11 +67,13 @@ */ class rules_test { protected: - rule_service rules_; + boost::asio::io_service service_; + irccd daemon_{service_}; + rule_service rules_{daemon_}; rules_test() { - log::set_logger(std::make_unique<log::silent_logger>()); + daemon_.set_log(std::make_unique<silent_logger>()); // #1 {