diff --git a/demo/work.cpp b/demo/work.cpp index db12419..eef528f 100644 --- a/demo/work.cpp +++ b/demo/work.cpp @@ -62,7 +62,7 @@ using namespace work::models; // payload.is_polymorphic_type(); int main() { - logger::default_min_log_level(logger::log_level::LVL_DEBUG); + logger::default_min_log_level(logger::log_level::Debug); logger::add_log_sink(logger::create_stdout_sink()); // sql::connection_pool pool("postgres://news:news@127.0.0.1:15432/matador", 4); diff --git a/include/matador/logger/log_domain.hpp b/include/matador/logger/log_domain.hpp index 8ac9de7..00d41c7 100644 --- a/include/matador/logger/log_domain.hpp +++ b/include/matador/logger/log_domain.hpp @@ -101,7 +101,7 @@ public: void clear(); private: - void get_time_stamp(char* timestamp_buffer) const; + static void get_time_stamp(char* timestamp_buffer); private: static std::map level_strings; diff --git a/include/matador/logger/log_level.hpp b/include/matador/logger/log_level.hpp index 819f3c7..862cf9c 100644 --- a/include/matador/logger/log_level.hpp +++ b/include/matador/logger/log_level.hpp @@ -8,15 +8,14 @@ namespace matador::logger { /** * Represents all available log levels */ -enum class log_level -{ - LVL_FATAL, /**< If a serious error occurred, use FATAL level */ - LVL_ERROR, /**< On error use ERROR level */ - LVL_WARN, /**< Warnings should use WARN level */ - LVL_INFO, /**< Information should go with INFO level */ - LVL_DEBUG, /**< Debug output should use DEBUG level */ - LVL_TRACE, /**< Trace information should use TRACE level */ - LVL_ALL /**< This level represents all log levels and should be used for logging */ +enum class log_level { + Fatal, /**< If a serious error occurred, use FATAL level */ + Error, /**< On error use ERROR level */ + Warn, /**< Warnings should use WARN level */ + Info, /**< Information should go with INFO level */ + Debug, /**< Debug output should use DEBUG level */ + Trace, /**< Trace information should use TRACE level */ + All /**< This level represents all log levels and should be used for logging */ }; /** @@ -31,10 +30,9 @@ std::ostream& operator<<(std::ostream &os, log_level lvl); /// @cond MATADOR_DEV -struct log_level_range -{ - log_level min_level = log_level::LVL_INFO; - log_level max_level = log_level::LVL_FATAL; +struct log_level_range { + log_level min_level = log_level::Info; + log_level max_level = log_level::Fatal; }; /// @endcond diff --git a/include/matador/logger/log_manager.hpp b/include/matador/logger/log_manager.hpp index ab4330a..f402478 100644 --- a/include/matador/logger/log_manager.hpp +++ b/include/matador/logger/log_manager.hpp @@ -123,11 +123,8 @@ public: protected: /// @cond MATADOR_DEV - log_manager() - { - default_log_domain_ = log_domain_map_.insert(std::make_pair("default", std::make_shared("default", default_log_level_range_))).first->second; - } - /// @endcond + log_manager(); + /// @endcond private: std::shared_ptr acquire_domain(const std::string &name); @@ -140,6 +137,8 @@ private: std::map> log_domain_map_; static log_level_range default_log_level_range_; + + std::mutex mutex_; }; /** @@ -285,15 +284,10 @@ void log_default(log_level lvl, const std::string &source, const char *message); * @param args The arguments for the message */ template -void log(const log_level lvl, const std::string &source, const char *what, ARGS const &... args) -{ - char message_buffer[16384]; +void log(const log_level lvl, const std::string &source, const char *what, ARGS const &... args) { + char message_buffer[logger::buffer_size]; -#ifdef _MSC_VER - sprintf_s(message_buffer, 912, what, args...); -#else - sprintf(message_buffer, what, args...); -#endif + snprintf(message_buffer, logger::buffer_size, what, args...); log_default(lvl, source, message_buffer); } diff --git a/include/matador/logger/logger.hpp b/include/matador/logger/logger.hpp index 55305ed..3f99e54 100644 --- a/include/matador/logger/logger.hpp +++ b/include/matador/logger/logger.hpp @@ -9,7 +9,6 @@ #include namespace matador::logger { - /** * @brief logger to write log messages to log domains * @@ -31,9 +30,9 @@ namespace matador::logger { * All log messages are written through the internal * log_domain object to the sinks. */ -class logger final -{ +class logger final { public: + static constexpr size_t buffer_size = 16384; /** * Create a logger with a given source name connected @@ -69,7 +68,7 @@ public: * @param args The arguments to be replaced in the message */ template - void fatal(const char *what, ARGS const &... args) const { log(log_level::LVL_FATAL, what, args...); } + void fatal(const char *what, ARGS const &... args) const { log(log_level::Fatal, what, args...); } /** * Writes a log message string with log level LVL_FATAL @@ -91,7 +90,7 @@ public: * @param args The arguments to be replaced in the message */ template - void error(const char *what, ARGS const &... args) const { log(log_level::LVL_ERROR, what, args...); } + void error(const char *what, ARGS const &... args) const { log(log_level::Error, what, args...); } /** * Writes a log message string with log level LVL_FATAL @@ -113,7 +112,7 @@ public: * @param args The arguments to be replaced in the message */ template - void warn(const char *what, ARGS const &... args) const { log(log_level::LVL_WARN, what, args...); } + void warn(const char *what, ARGS const &... args) const { log(log_level::Warn, what, args...); } /** * Writes a log message string with log level LVL_FATAL @@ -135,7 +134,7 @@ public: * @param args The arguments to be replaced in the message */ template - void info(const char *what, ARGS const &... args) const { log(log_level::LVL_INFO, what, args...); } + void info(const char *what, ARGS const &... args) const { log(log_level::Info, what, args...); } /** * Writes a log message string with log level LVL_FATAL @@ -157,7 +156,7 @@ public: * @param args The arguments to be replaced in the message */ template - void debug(const char *what, ARGS const &... args) const { log(log_level::LVL_DEBUG, what, args...); } + void debug(const char *what, ARGS const &... args) const { log(log_level::Debug, what, args...); } /** * Writes a log message string with log level LVL_FATAL @@ -179,7 +178,7 @@ public: * @param args The arguments to be replaced in the message */ template - void trace(const char *what, ARGS const &... args) const { log(log_level::LVL_TRACE, what, args...); } + void trace(const char *what, ARGS const &... args) const { log(log_level::Trace, what, args...); } /** * Writes a log message represented by a char pointer @@ -222,14 +221,10 @@ private: }; template -void logger::log(log_level lvl, const char *what, ARGS const &... args) const { - char message_buffer[16384]; +void logger::log(const log_level lvl, const char *what, ARGS const &... args) const { + char message_buffer[buffer_size]; -#ifdef _MSC_VER - sprintf_s(message_buffer, 16384, what, args...); -#else - sprintf(message_buffer, what, args...); -#endif + snprintf(message_buffer, buffer_size, what, args...); logger_domain_->log(lvl, source_, message_buffer); } diff --git a/source/core/logger/log_domain.cpp b/source/core/logger/log_domain.cpp index badb1d5..369fd72 100644 --- a/source/core/logger/log_domain.cpp +++ b/source/core/logger/log_domain.cpp @@ -44,11 +44,13 @@ char* gettimestamp(char* const buffer, const size_t size) { } std::map log_domain::level_strings = { /* NOLINT */ - { log_level::LVL_DEBUG, "DEBUG" }, - { log_level::LVL_INFO, "INFO" }, - { log_level::LVL_WARN, "WARN" }, - { log_level::LVL_ERROR, "ERROR" }, - { log_level::LVL_TRACE, "TRACE" } + { log_level::Fatal, "Fatal" }, + { log_level::Debug, "Debug" }, + { log_level::Info, "Info" }, + { log_level::Warn, "Warn" }, + { log_level::Error, "Error" }, + { log_level::Trace, "Trace" }, + { log_level::All, "All" } }; log_domain::log_domain(std::string name, const log_level_range log_range) @@ -61,33 +63,29 @@ std::string log_domain::name() const return name_; } -void log_domain::max_log_level(log_level max_level) -{ +void log_domain::max_log_level(const log_level max_level) { log_level_range_.max_level = max_level; } -log_level log_domain::max_log_level() const -{ +log_level log_domain::max_log_level() const { return log_level_range_.max_level; } -void log_domain::min_log_level(log_level min_level) -{ +void log_domain::min_log_level(const log_level min_level) { log_level_range_.min_level = min_level; } -log_level log_domain::min_log_level() const -{ +log_level log_domain::min_log_level() const { return log_level_range_.min_level; } -void log_domain::add_sink(sink_ptr sink) -{ +void log_domain::add_sink(sink_ptr sink) { + std::lock_guard l(mutex_); sinks.push_back(std::move(sink)); } -void log_domain::log(log_level lvl, const std::string &source, const char *message) const { - if (lvl < log_level_range_.max_level || lvl > log_level_range_.min_level) { +void log_domain::log(const log_level lvl, const std::string &source, const char *message) const { + if (lvl < log_level_range_.min_level || lvl > log_level_range_.max_level) { return; } @@ -97,9 +95,9 @@ void log_domain::log(log_level lvl, const std::string &source, const char *messa char buffer[1024]; #ifdef _MSC_VER - int ret = sprintf_s(buffer, 1024, "%s [Thread %zu] [%-7s] [%s]: %s\n", timestamp, details::acquire_thread_index(std::this_thread::get_id()), level_strings[lvl].c_str(), source.c_str(), message); + const int ret = sprintf_s(buffer, 1024, "%s [Thread %zu] [%-7s] [%s]: %s\n", timestamp, details::acquire_thread_index(std::this_thread::get_id()), level_strings[lvl].c_str(), source.c_str(), message); #else - int ret = sprintf(buffer, "%s [Thread %lu] [%-7s] [%s]: %s\n", timestamp, details::acquire_thread_index(std::this_thread::get_id()), level_strings[lvl].c_str(), source.c_str(), message); + const int ret = sprintf(buffer, "%s [Thread %lu] [%-7s] [%s]: %s\n", timestamp, details::acquire_thread_index(std::this_thread::get_id()), level_strings[lvl].c_str(), source.c_str(), message); #endif std::lock_guard l(mutex_); @@ -108,13 +106,12 @@ void log_domain::log(log_level lvl, const std::string &source, const char *messa } } -void log_domain::clear() -{ +void log_domain::clear() { + std::lock_guard l(mutex_); sinks.clear(); } -void log_domain::get_time_stamp(char* const timestamp_buffer) const { - std::lock_guard l(mutex_); +void log_domain::get_time_stamp(char* const timestamp_buffer) { details::gettimestamp(timestamp_buffer, 80); } diff --git a/source/core/logger/log_level.cpp b/source/core/logger/log_level.cpp index edd760a..d7f3b99 100644 --- a/source/core/logger/log_level.cpp +++ b/source/core/logger/log_level.cpp @@ -7,25 +7,25 @@ namespace matador::logger { std::ostream& operator<<(std::ostream &os, const log_level lvl) { switch (lvl) { - case log_level::LVL_ERROR: + case log_level::Error: os << "ERROR"; break; - case log_level::LVL_FATAL: + case log_level::Fatal: os << "FATAL"; break; - case log_level::LVL_DEBUG: + case log_level::Debug: os << "DEBUG"; break; - case log_level::LVL_INFO: + case log_level::Info: os << "INFO"; break; - case log_level::LVL_TRACE: + case log_level::Trace: os << "TRACE"; break; - case log_level::LVL_WARN: + case log_level::Warn: os << "WARN"; break; - case log_level::LVL_ALL: + case log_level::All: os << "ALL"; break; default: diff --git a/source/core/logger/log_manager.cpp b/source/core/logger/log_manager.cpp index fac5fb2..6f4e08f 100644 --- a/source/core/logger/log_manager.cpp +++ b/source/core/logger/log_manager.cpp @@ -5,19 +5,18 @@ namespace matador::logger { log_level_range log_manager::default_log_level_range_ = {}; logger log_manager::create_logger(std::string source) const { - return logger(std::move(source), default_log_domain_); + return {std::move(source), default_log_domain_}; } logger log_manager::create_logger(std::string source, const std::string &domain_name) { - return logger(std::move(source), acquire_domain(domain_name)); + return {std::move(source), acquire_domain(domain_name)}; } void log_manager::add_sink(sink_ptr sink) const { default_log_domain_->add_sink(std::move(sink)); } -void log_manager::add_sink(sink_ptr sink, const std::string &domain_name) -{ +void log_manager::add_sink(sink_ptr sink, const std::string &domain_name) { const auto log_domain = acquire_domain(domain_name); log_domain->add_sink(std::move(sink)); @@ -27,44 +26,40 @@ void log_manager::clear_all_sinks() const { default_log_domain_->clear(); } -void log_manager::clear_all_sinks(const std::string &domain_name) -{ +void log_manager::clear_all_sinks(const std::string &domain_name) { + std::lock_guard lock(mutex_); if (const auto it = log_domain_map_.find(domain_name); it != log_domain_map_.end()) { it->second->clear(); } } -void log_manager::clear() -{ +void log_manager::clear() { + std::lock_guard lock(mutex_); log_domain_map_.clear(); - default_log_domain_->clear(); } -void log_manager::max_default_log_level(log_level max_level) -{ +void log_manager::max_default_log_level(const log_level max_level) { default_log_level_range_.max_level = max_level; } -log_level log_manager::max_default_log_level() -{ +log_level log_manager::max_default_log_level() { return default_log_level_range_.max_level; } -void log_manager::min_default_log_level(log_level min_level) -{ +void log_manager::min_default_log_level(const log_level min_level) { default_log_level_range_.min_level = min_level; } -log_level log_manager::min_default_log_level() -{ +log_level log_manager::min_default_log_level() { return default_log_level_range_.min_level; } -std::shared_ptr log_manager::acquire_domain(const std::string &name) -{ +std::shared_ptr log_manager::acquire_domain(const std::string &name) { if (name == "default") { return default_log_domain_; } + + std::lock_guard lock(mutex_); auto it = log_domain_map_.find(name); if (it == log_domain_map_.end()) { it = log_domain_map_.insert(std::make_pair(name, std::make_shared(name, default_log_level_range_))).first; @@ -72,34 +67,34 @@ std::shared_ptr log_manager::acquire_domain(const std::string &name) return it->second; } -std::shared_ptr log_manager::find_domain(const std::string &name) -{ +std::shared_ptr log_manager::find_domain(const std::string &name) { if (name == "default") { return default_log_domain_; } - auto it = log_domain_map_.find(name); - if (it != log_domain_map_.end()) { + std::lock_guard lock(mutex_); + if (const auto it = log_domain_map_.find(name); it != log_domain_map_.end()) { return it->second; } - return std::shared_ptr(); + return {}; } void log_manager::log_default(const log_level lvl, const std::string &source, const char *message) const { default_log_domain_->log(lvl, source, message); } -std::shared_ptr create_file_sink(const std::string &logfile) -{ +log_manager::log_manager() { + default_log_domain_ = std::make_shared("default", default_log_level_range_); +} + +std::shared_ptr create_file_sink(const std::string &logfile) { return std::make_shared(logfile); } -std::shared_ptr create_stderr_sink() -{ +std::shared_ptr create_stderr_sink() { return std::make_shared(); } -std::shared_ptr create_stdout_sink() -{ +std::shared_ptr create_stdout_sink() { return std::make_shared(); } @@ -128,7 +123,7 @@ void domain_min_log_level(const std::string &name, const log_level min_lvl) void domain_max_log_level(const std::string &name, const log_level max_lvl) { if (const auto domain = log_manager::instance().find_domain(name)) { - domain->min_log_level(max_lvl); + domain->max_log_level(max_lvl); } } diff --git a/test/core/logger/LoggerTest.cpp b/test/core/logger/LoggerTest.cpp index a1d9f4d..e8e77de 100644 --- a/test/core/logger/LoggerTest.cpp +++ b/test/core/logger/LoggerTest.cpp @@ -18,8 +18,7 @@ using namespace matador::logger; namespace filehelper { -class std_stream_switcher -{ +class std_stream_switcher { public: explicit std_stream_switcher(FILE *str, const char* redirect) : stream(str) { @@ -56,8 +55,6 @@ TEST_CASE("Test log file sink", "[logger][log][file_sink]") { REQUIRE(matador::os::exists("test.txt")); - // UNIT_ASSERT_EQUAL("test.txt", test.path()); - test.close(); if (::remove("test.txt") == -1) { @@ -136,28 +133,28 @@ TEST_CASE("Test log rotating file sink", "[logger][log][rotate_file_sink]") { } TEST_CASE("Test log level range", "[logger][level][range]") { - REQUIRE(log_level::LVL_INFO == log_manager::min_default_log_level()); - REQUIRE(log_level::LVL_FATAL == log_manager::max_default_log_level()); + REQUIRE(log_level::Info == log_manager::min_default_log_level()); + REQUIRE(log_level::Fatal == log_manager::max_default_log_level()); - default_min_log_level(log_level::LVL_DEBUG); - default_max_log_level(log_level::LVL_ERROR); + default_min_log_level(log_level::Debug); + default_max_log_level(log_level::Error); - REQUIRE(log_level::LVL_DEBUG == log_manager::min_default_log_level()); - REQUIRE(log_level::LVL_ERROR == log_manager::max_default_log_level()); + REQUIRE(log_level::Debug == log_manager::min_default_log_level()); + REQUIRE(log_level::Error == log_manager::max_default_log_level()); log_level_range llr; - llr.min_level = log_level::LVL_DEBUG; - llr.max_level = log_level::LVL_TRACE; + llr.min_level = log_level::Debug; + llr.max_level = log_level::Trace; log_domain ld("test", llr); - REQUIRE(log_level::LVL_DEBUG == ld.min_log_level()); - REQUIRE(log_level::LVL_TRACE == ld.max_log_level()); + REQUIRE(log_level::Debug == ld.min_log_level()); + REQUIRE(log_level::Trace == ld.max_log_level()); - ld.min_log_level(log_level::LVL_INFO); - ld.max_log_level(log_level::LVL_ERROR); + ld.min_log_level(log_level::Info); + ld.max_log_level(log_level::Error); - REQUIRE(log_level::LVL_INFO == ld.min_log_level()); - REQUIRE(log_level::LVL_ERROR == ld.max_log_level()); + REQUIRE(log_level::Info == ld.min_log_level()); + REQUIRE(log_level::Error == ld.max_log_level()); } TEST_CASE("Test basic logger functions", "[logger][basic]") { @@ -205,8 +202,8 @@ TEST_CASE("Test basic logger functions", "[logger][basic]") { } TEST_CASE("Test logging", "[logger][logging]") { - domain_min_log_level("default", log_level::LVL_FATAL); - domain_max_log_level("default", log_level::LVL_TRACE); + domain_min_log_level("default", log_level::Fatal); + domain_max_log_level("default", log_level::Trace); auto logger = create_logger("test"); @@ -230,7 +227,7 @@ TEST_CASE("Test logging", "[logger][logging]") { logger.trace("tracing something %s", "important"); logger.error("big error"); logger.error("big error %s", "important"); - log(log_level::LVL_ERROR, "test", "global log test %d", 4711); + log(log_level::Error, "test", "global log test %d", 4711); logsink->close(); @@ -308,43 +305,43 @@ TEST_CASE("Test log stderr", "[logger][logging][stderr]") { TEST_CASE("Test log levels", "[logger][levels]") { std::stringstream out; - out << log_level::LVL_ERROR; + out << log_level::Error; REQUIRE("ERROR" == out.str()); out.str(""); out.clear(); - out << log_level::LVL_DEBUG; + out << log_level::Debug; REQUIRE("DEBUG" == out.str()); out.str(""); out.clear(); - out << log_level::LVL_INFO; + out << log_level::Info; REQUIRE("INFO" == out.str()); out.str(""); out.clear(); - out << log_level::LVL_FATAL; + out << log_level::Fatal; REQUIRE("FATAL" == out.str()); out.str(""); out.clear(); - out << log_level::LVL_TRACE; + out << log_level::Trace; REQUIRE("TRACE" == out.str()); out.str(""); out.clear(); - out << log_level::LVL_WARN; + out << log_level::Warn; REQUIRE("WARN" == out.str()); out.str(""); out.clear(); - out << log_level::LVL_ALL; + out << log_level::All; REQUIRE("ALL" == out.str()); } diff --git a/test/models/student.hpp b/test/models/student.hpp index ad48917..7e4fc6e 100644 --- a/test/models/student.hpp +++ b/test/models/student.hpp @@ -5,6 +5,7 @@ #include "matador/utils/foreign_attributes.hpp" #include "matador/object/object_ptr.hpp" +#include "matador/object/collection.hpp" #include "matador/object/many_to_many_relation.hpp" #include @@ -16,7 +17,7 @@ struct course; struct student { unsigned int id{}; std::string name; - std::vector > courses; + object::collection > courses; student() = default; @@ -37,7 +38,7 @@ struct student { struct course { unsigned int id{}; std::string title; - std::vector > students; + object::collection > students; course() = default;