From df56bb775a416225b42bfcb0ac74cf1d3b33e98a Mon Sep 17 00:00:00 2001 From: gabi Date: Sat, 25 Jan 2014 15:52:10 +0200 Subject: [PATCH] 1. Added test 2. Fixes --- c11log.sln | 31 ++++++ c11log.v12.suo | Bin 0 -> 32768 bytes include/c11log/details/blocking_queue.h | 52 +++++----- include/c11log/logger.h | 75 +++++++------- include/c11log/sinks/async_sink.h | 129 ++++++++++++++++-------- include/c11log/sinks/base_sink.h | 21 ++-- include/c11log/sinks/file_sinks.h | 9 +- include/c11log/sinks/stdout_sinks.h | 61 ++++++----- src/line_logger.cpp | 4 +- test/stdafx.cpp | 8 ++ test/stdafx.h | 16 +++ test/test.cpp | 24 +++++ test/utils.h | 47 +++++++++ 13 files changed, 326 insertions(+), 151 deletions(-) create mode 100644 c11log.sln create mode 100644 c11log.v12.suo create mode 100644 test/stdafx.cpp create mode 100644 test/stdafx.h create mode 100644 test/test.cpp create mode 100644 test/utils.h diff --git a/c11log.sln b/c11log.sln new file mode 100644 index 00000000..582ead83 --- /dev/null +++ b/c11log.sln @@ -0,0 +1,31 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 2013 +VisualStudioVersion = 12.0.21005.1 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "c11log", "c11log.vcxproj", "{BBFA8622-1945-4EB0-BAF4-473BE753ED24}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "test", "test\test.vcxproj", "{429A1E1E-6F89-4941-B4A7-7464CEA22587}" + ProjectSection(ProjectDependencies) = postProject + {BBFA8622-1945-4EB0-BAF4-473BE753ED24} = {BBFA8622-1945-4EB0-BAF4-473BE753ED24} + EndProjectSection +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Release|Win32 = Release|Win32 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {BBFA8622-1945-4EB0-BAF4-473BE753ED24}.Debug|Win32.ActiveCfg = Debug|Win32 + {BBFA8622-1945-4EB0-BAF4-473BE753ED24}.Debug|Win32.Build.0 = Debug|Win32 + {BBFA8622-1945-4EB0-BAF4-473BE753ED24}.Release|Win32.ActiveCfg = Release|Win32 + {BBFA8622-1945-4EB0-BAF4-473BE753ED24}.Release|Win32.Build.0 = Release|Win32 + {429A1E1E-6F89-4941-B4A7-7464CEA22587}.Debug|Win32.ActiveCfg = Debug|Win32 + {429A1E1E-6F89-4941-B4A7-7464CEA22587}.Debug|Win32.Build.0 = Debug|Win32 + {429A1E1E-6F89-4941-B4A7-7464CEA22587}.Release|Win32.ActiveCfg = Release|Win32 + {429A1E1E-6F89-4941-B4A7-7464CEA22587}.Release|Win32.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/c11log.v12.suo b/c11log.v12.suo new file mode 100644 index 0000000000000000000000000000000000000000..da81938b34f00b12e03a566f4387bffde5c6522c GIT binary patch literal 32768 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 UFMK3hx>&B^pDZknY5$zze@&~UjsO4v literal 0 HcmV?d00001 diff --git a/include/c11log/details/blocking_queue.h b/include/c11log/details/blocking_queue.h index 0859b98b..4a9cbb15 100644 --- a/include/c11log/details/blocking_queue.h +++ b/include/c11log/details/blocking_queue.h @@ -21,17 +21,16 @@ public: using size_type = typename queue_t::size_type; using clock = std::chrono::system_clock; - explicit blocking_queue(size_type max_size) :_max_size(max_size), _q() + explicit blocking_queue(size_type max_size) :max_size_(max_size), q_() {} blocking_queue(const blocking_queue&) = delete; - blocking_queue& operator=(const blocking_queue&) = delete; - blocking_queue& operator=(const blocking_queue&) volatile = delete; + blocking_queue& operator=(const blocking_queue&) = delete; ~blocking_queue() = default; size_type size() { - std::lock_guard lock(_mutex); - return _q.size(); + std::lock_guard lock(mutex_); + return q_.size(); } // Push copy of item into the back of the queue. @@ -40,17 +39,17 @@ public: template bool push(const T& item, const std::chrono::duration& timeout) { - std::unique_lock ul(_mutex); - if (_q.size() >= _max_size) + std::unique_lock ul(mutex_); + if (q_.size() >= max_size_) { - if (!_item_popped_cond.wait_until(ul, clock::now() + timeout, [this]() { return this->_q.size() < this->_max_size; })) + if (!item_popped_cond_.wait_until(ul, clock::now() + timeout, [this]() { return this->q_.size() < this->max_size_; })) return false; } - _q.push(item); - if (_q.size() <= 1) + q_.push(item); + if (q_.size() <= 1) { ul.unlock(); //So the notified thread will have better chance to accuire the lock immediatly.. - _item_pushed_cond.notify_one(); + item_pushed_cond_.notify_one(); } return true; } @@ -68,18 +67,18 @@ public: template bool pop(T& item, const std::chrono::duration& timeout) { - std::unique_lock ul(_mutex); - if (_q.empty()) + std::unique_lock ul(mutex_); + if (q_.empty()) { - if (!_item_pushed_cond.wait_until(ul, clock::now() + timeout, [this]() { return !this->_q.empty(); })) + if (!item_pushed_cond_.wait_until(ul, clock::now() + timeout, [this]() { return !this->q_.empty(); })) return false; } - item = _q.front(); - _q.pop(); - if (_q.size() >= _max_size - 1) + item = q_.front(); + q_.pop(); + if (q_.size() >= max_size_ - 1) { ul.unlock(); //So the notified thread will have better chance to accuire the lock immediatly.. - _item_popped_cond.notify_one(); + item_popped_cond_.notify_one(); } return true; } @@ -91,12 +90,19 @@ public: while (!pop(item, std::chrono::hours::max())); } + // Clear the queue + void clear() + { + T item; + while (pop(item, std::chrono::milliseconds(0))); + } + private: - size_type _max_size; - std::queue _q; - std::mutex _mutex; - std::condition_variable _item_pushed_cond; - std::condition_variable _item_popped_cond; + size_type max_size_; + std::queue q_; + std::mutex mutex_; + std::condition_variable item_pushed_cond_; + std::condition_variable item_popped_cond_; }; } } \ No newline at end of file diff --git a/include/c11log/logger.h b/include/c11log/logger.h index 3105d82a..0ca87398 100644 --- a/include/c11log/logger.h +++ b/include/c11log/logger.h @@ -1,5 +1,7 @@ #pragma once +// Thread safe logger +// Has log level and vector sinks which do the actual logging #include #include #include @@ -20,15 +22,13 @@ public: typedef std::shared_ptr sink_ptr_t; typedef std::vector sinks_vector_t; - explicit logger(const std::string& name) : _logger_name(name), - _formatter(std::make_unique()) + explicit logger(const std::string& name) : logger_name_(name), + formatter_(std::make_unique()) { - _atomic_level.store(level::INFO); + atomic_level_.store(level::INFO); } - ~logger() - { - }; + ~logger() = default; logger(const logger&) = delete; logger& operator=(const logger&) = delete; @@ -53,30 +53,32 @@ private: friend details::line_logger; - std::string _logger_name = ""; - std::unique_ptr _formatter; - sinks_vector_t _sinks; - std::mutex _mutex; - std::atomic_int _atomic_level; + std::string logger_name_ = ""; + std::unique_ptr formatter_; + sinks_vector_t sinks_; + std::mutex mutex_; + std::atomic_int atomic_level_; - void _log_it(const std::string& msg); + void log_it_(const std::string& msg); }; logger& get_logger(const std::string& name); } -/* -Logger inline impl -*/ - +// +// Logger inline impl +// inline c11log::details::line_logger c11log::logger::log(c11log::level::level_enum msg_level) { - if (msg_level >= _atomic_level.load()) { - std::lock_guard lock(_mutex); + if (msg_level >= atomic_level_.load()) + { + std::lock_guard lock(mutex_); return details::line_logger(this, msg_level); - } else { + } + else + { return details::line_logger(nullptr); } @@ -105,56 +107,57 @@ inline c11log::details::line_logger c11log::logger::fatal() inline void c11log::logger::set_name(const std::string& name) { - std::lock_guard lock(_mutex); - _logger_name = name; + std::lock_guard lock(mutex_); + logger_name_ = name; } inline const std::string& c11log::logger::get_name() { - std::lock_guard lock(_mutex); - return _logger_name; + std::lock_guard lock(mutex_); + return logger_name_; } inline void c11log::logger::add_sink(sink_ptr_t sink_ptr) { - std::lock_guard lock(_mutex); - _sinks.push_back(sink_ptr); + std::lock_guard lock(mutex_); + sinks_.push_back(sink_ptr); } inline void c11log::logger::remove_sink(sink_ptr_t sink_ptr) { - std::lock_guard lock(_mutex); - _sinks.erase(std::remove(_sinks.begin(), _sinks.end(), sink_ptr), _sinks.end()); + std::lock_guard lock(mutex_); + sinks_.erase(std::remove(sinks_.begin(), sinks_.end(), sink_ptr), sinks_.end()); } inline void c11log::logger::set_formatter(std::unique_ptr formatter) { - std::lock_guard lock(_mutex); - _formatter = std::move(formatter); + std::lock_guard lock(mutex_); + formatter_ = std::move(formatter); } inline void c11log::logger::set_level(c11log::level::level_enum level) { - _atomic_level.store(level); + atomic_level_.store(level); } inline c11log::level::level_enum c11log::logger::get_level() const { - return static_cast(_atomic_level.load()); + return static_cast(atomic_level_.load()); } inline bool c11log::logger::should_log(c11log::level::level_enum level) const { - return level >= _atomic_level.load(); + return level >= atomic_level_.load(); } -inline void c11log::logger::_log_it(const std::string& msg) +inline void c11log::logger::log_it_(const std::string& msg) { - level::level_enum level = static_cast(_atomic_level.load()); - std::lock_guard lock(_mutex); - for (auto &sink : _sinks) + level::level_enum level = static_cast(atomic_level_.load()); + std::lock_guard lock(mutex_); + for (auto &sink : sinks_) sink->log(msg, level); } +// Static factory function inline c11log::logger& c11log::get_logger(const std::string& name) { return *(c11log::details::factory::instance().get_logger(name)); diff --git a/include/c11log/sinks/async_sink.h b/include/c11log/sinks/async_sink.h index 8f95c6c5..5d9a9138 100644 --- a/include/c11log/sinks/async_sink.h +++ b/include/c11log/sinks/async_sink.h @@ -1,55 +1,98 @@ #pragma once -#include -#include -#include -#include -#include "../logger.h" +#include +#include +#include +#include + #include "base_sink.h" +#include "../logger.h" +#include "../details/blocking_queue.h" + namespace c11log { namespace sinks { -class async_sink : base_sink { - enum class fullq_policy { - BLOCK=0, - DROP_MSG - }; +class async_sink : public base_sink { + public: - async_sink(std::size_t max_queue_size, fullq_policy q_policy) :_fullq_policy(q_policy), _back_thread(&_thread_loop) - { - - } -protected: - void _sink_it(const std::string& msg) override - { - _msgs_mutex.unlock(); - _msgs.push(msg); - } - void _thread_loop() - { - while (_active) { - _msgs_mutex.lock(); - std::string &msg = _msgs.front(); - _msgs.pop(); - _msgs_mutex.unlock(); - std::cout << "Popped: " << msg << std::endl; - } - } - -private: - c11log::logger::sinks_vector_t _sinks; - fullq_policy _fullq_policy; - std::queue _msgs; - std::thread _back_thread; - bool _active = true; - std::mutex _msgs_mutex; - - + using size_type = c11log::details::blocking_queue::size_type; + explicit async_sink(const std::size_t max_queue_size, const std::chrono::seconds& timeout = std::chrono::seconds::max()); + ~async_sink(); + void add_sink(logger::sink_ptr_t sink); + void remove_sink(logger::sink_ptr_t sink_ptr); + +protected: + void sink_it_(const std::string& msg) override; + void thread_loop_(); + +private: + c11log::logger::sinks_vector_t sinks_; + bool active_ = true; + const std::chrono::seconds timeout_; + c11log::details::blocking_queue q_; + std::thread back_thread_; + void shutdown_(); }; } } -void c11log::sinks::async_sink::_sink_it(const std::string& msg) -{ +// +// async_sink inline impl +// + +inline c11log::sinks::async_sink::async_sink(const std::size_t max_queue_size, const std::chrono::seconds& timeout) + :q_(max_queue_size), + timeout_(timeout), + back_thread_(&async_sink::thread_loop_, this) +{} + +inline c11log::sinks::async_sink::~async_sink() +{ + shutdown_(); +} +inline void c11log::sinks::async_sink::sink_it_(const std::string& msg) +{ + q_.push(msg, timeout_); +} + +inline void c11log::sinks::async_sink::thread_loop_() +{ + std::string msg; + while (active_) + { + if (q_.pop(msg, timeout_)) + { + std::lock_guard lock(mutex_); + for (auto &sink : sinks_) + { + if (active_) + sink->log(msg, _level); + else + break; + } + } + } +} + +inline void c11log::sinks::async_sink::add_sink(logger::sink_ptr_t sink) +{ + std::lock_guard lock(mutex_); + sinks_.push_back(sink); +} + +inline void c11log::sinks::async_sink::remove_sink(logger::sink_ptr_t sink_ptr) +{ + std::lock_guard lock(mutex_); + sinks_.erase(std::remove(sinks_.begin(), sinks_.end(), sink_ptr), sinks_.end()); +} + +inline void c11log::sinks::async_sink::shutdown_() +{ + { + std::lock_guard lock(mutex_); + active_ = false; + } + q_.clear(); + back_thread_.join(); +} -} \ No newline at end of file diff --git a/include/c11log/sinks/base_sink.h b/include/c11log/sinks/base_sink.h index 87349972..bf444729 100644 --- a/include/c11log/sinks/base_sink.h +++ b/include/c11log/sinks/base_sink.h @@ -1,4 +1,5 @@ #pragma once + #include #include #include @@ -10,40 +11,38 @@ namespace c11log { namespace sinks { class base_sink { public: - base_sink() - {} + base_sink() = default; base_sink(level::level_enum l):_level(l) {}; - virtual ~base_sink() - {}; - + virtual ~base_sink() = default; + base_sink(const base_sink&) = delete; base_sink& operator=(const base_sink&) = delete; void log(const std::string &msg, level::level_enum level) { if (level >= _level) { - std::lock_guard lock(_mutex); + std::lock_guard lock(mutex_); if (level >= _level) - _sink_it(msg); + sink_it_(msg); } }; void set_level(level::level_enum level) { - std::lock_guard lock(_mutex); + std::lock_guard lock(mutex_); _level = level; } protected: - virtual void _sink_it(const std::string& msg) = 0; + virtual void sink_it_(const std::string& msg) = 0; level::level_enum _level = level::INFO; - std::mutex _mutex; + std::mutex mutex_; }; class null_sink:public base_sink { protected: - void _sink_it(const std::string& msg) override + void sink_it_(const std::string& msg) override {} }; } diff --git a/include/c11log/sinks/file_sinks.h b/include/c11log/sinks/file_sinks.h index bd729c42..a8edf5c0 100644 --- a/include/c11log/sinks/file_sinks.h +++ b/include/c11log/sinks/file_sinks.h @@ -1,4 +1,5 @@ #pragma once + #include #include @@ -22,7 +23,7 @@ public: _ofstream.open(oss.str(), std::ofstream::app); } protected: - void _sink_it(const std::string& msg) override + void sink_it_(const std::string& msg) override { _ofstream << msg; _ofstream.flush(); @@ -43,7 +44,7 @@ public: virtual ~rotating_file_sink_base() {} protected: - virtual void _sink_it(const std::string& msg) override + virtual void sink_it_(const std::string& msg) override { if (_should_rotate()) _rotate(); @@ -69,10 +70,10 @@ public: } protected: - virtual void _sink_it(const std::string& msg) override + virtual void sink_it_(const std::string& msg) override { _current_size += msg.length(); - rotating_file_sink_base::_sink_it(msg); + rotating_file_sink_base::sink_it_(msg); } bool _should_rotate() const override diff --git a/include/c11log/sinks/stdout_sinks.h b/include/c11log/sinks/stdout_sinks.h index 8f6b3e37..1ec0d7c5 100644 --- a/include/c11log/sinks/stdout_sinks.h +++ b/include/c11log/sinks/stdout_sinks.h @@ -1,41 +1,38 @@ +#pragma once #include #include "base_sink.h" namespace c11log { - namespace sinks +namespace sinks +{ +class ostream_sink: public base_sink +{ +public: + ostream_sink(std::ostream& os):_ostream(os) {} + virtual ~ostream_sink() = default; + +protected: + virtual void sink_it_(const std::string& msg) override { - class ostream_sink:public base_sink - { - public: - ostream_sink(std::ostream& os):_ostream(os) - {} - - virtual ~ostream_sink() - {} - - protected: - virtual void _sink_it(const std::string& msg) - { - _ostream << msg; - } - std::ostream& _ostream; - - }; - - class stdout_sink:public ostream_sink - { - public: - stdout_sink():ostream_sink(std::cout) - {} - }; - - class stderr_sink:public ostream_sink - { - public: - stderr_sink():ostream_sink(std::cerr) - {} - }; + _ostream << msg; } + + std::ostream& _ostream; +}; + +class stdout_sink:public ostream_sink +{ +public: + stdout_sink():ostream_sink(std::cout) {} +}; + +class stderr_sink:public ostream_sink +{ +public: + stderr_sink():ostream_sink(std::cerr) {} + +}; +} } \ No newline at end of file diff --git a/src/line_logger.cpp b/src/line_logger.cpp index f1b984ec..77c8708c 100644 --- a/src/line_logger.cpp +++ b/src/line_logger.cpp @@ -5,7 +5,7 @@ c11log::details::line_logger::line_logger(logger* callback_logger, level::level_ _callback_logger(callback_logger) { if (callback_logger) { - callback_logger->_formatter->format_header(callback_logger->_logger_name, + callback_logger->formatter_->format_header(callback_logger->logger_name_, msg_level, c11log::formatters::timepoint::clock::now(), _oss); @@ -16,6 +16,6 @@ c11log::details::line_logger::~line_logger() { if (_callback_logger) { _oss << '\n'; - _callback_logger->_log_it(_oss.str_ref()); + _callback_logger->log_it_(_oss.str_ref()); } } \ No newline at end of file diff --git a/test/stdafx.cpp b/test/stdafx.cpp new file mode 100644 index 00000000..ab6cf716 --- /dev/null +++ b/test/stdafx.cpp @@ -0,0 +1,8 @@ +// stdafx.cpp : source file that includes just the standard includes +// test.pch will be the pre-compiled header +// stdafx.obj will contain the pre-compiled type information + +#include "stdafx.h" + +// TODO: reference any additional headers you need in STDAFX.H +// and not in this file diff --git a/test/stdafx.h b/test/stdafx.h new file mode 100644 index 00000000..da4e7055 --- /dev/null +++ b/test/stdafx.h @@ -0,0 +1,16 @@ +// stdafx.h : include file for standard system include files, +// or project specific include files that are used frequently, but +// are changed infrequently +// + +#pragma once + +#include +#include +#include + +#include "utils.h" +#include "../include/c11log/logger.h" +#include "../include/c11log/sinks/async_sink.h" +#include "../include/c11log/sinks/stdout_sinks.h" +#include "../include/c11log/sinks/file_sinks.h" diff --git a/test/test.cpp b/test/test.cpp new file mode 100644 index 00000000..d6ec4839 --- /dev/null +++ b/test/test.cpp @@ -0,0 +1,24 @@ +// test.cpp : Defines the entry point for the console application. +// + +#include "stdafx.h" + + +void fn(); +int main(int argc, char* argv[]) +{ + + c11log::logger logger("test"); + + auto sink = std::make_shared(); + auto async = std::make_shared(100); + async->add_sink(sink); + logger.add_sink(async); + logger.info() << "Hello logger!"; + utils::run(std::chrono::seconds(10), fn); + return 0; +} + +static void fn() +{} + diff --git a/test/utils.h b/test/utils.h new file mode 100644 index 00000000..c9b56b18 --- /dev/null +++ b/test/utils.h @@ -0,0 +1,47 @@ +#pragma once + +#include +#include +#include +#include +#include +#include + +namespace utils +{ + +template +std::string format(const T& value) +{ + static std::locale loc(""); + std::stringstream ss; + ss.imbue(loc); + ss << value; + return ss.str(); +} + +inline void run(const std::chrono::milliseconds &duration, const std::function& fn) +{ + using namespace std::chrono; + typedef steady_clock the_clock; + size_t counter = 0; + seconds print_interval(1); + auto start_time = the_clock::now(); + auto lastPrintTime = start_time; + while (true) + { + fn(); + ++counter; + auto now = the_clock::now(); + if (now - start_time >= duration) + break; + auto p = now - lastPrintTime; + if (now - lastPrintTime >= print_interval) + { + std::cout << format(counter) << " per sec" << std::endl; + counter = 0; + lastPrintTime = the_clock::now(); + } + } +} +} \ No newline at end of file