diff --git a/example/bench.cpp b/example/bench.cpp index f3e19d7e..988e2d21 100644 --- a/example/bench.cpp +++ b/example/bench.cpp @@ -17,27 +17,23 @@ using namespace utils; int main(int argc, char* argv[]) { - const unsigned int howmany = argc <= 1 ? 500000 : atoi(argv[1]); + const unsigned int howmany = argc <= 1 ? 1000000 : atoi(argv[1]); - std::string pattern = "%Y:%m:%d %H:%M:%S.%e [%n:%l] %t"; - auto formatter1 = std::unique_ptr(new details::pattern_formatter(pattern)); + //std::string pattern = "%Y:%m:%d %H:%M:%S.%e ---> [%n:%l] %t"; + //auto formatter = std::make_shared(pattern); - logger cout_logger("bench", std::make_shared() , std::move(formatter1)); - cout_logger.info() << "Hello logger"; + logger cout_logger("bench", { std::make_shared() }); + cout_logger.info() << "Hello logger " << std::setw(10) << std::setfill('x') << 1234.55; - auto nullsink = std::make_shared>(); + auto nullsink = std::make_shared(); auto rotating = std::make_shared("myrotating", "txt", 1024 * 1024 * 5, 5, 100); - - auto formatter2 = std::unique_ptr(new details::pattern_formatter(pattern)); - logger my_logger("my_logger", rotating, std::move(formatter2)); + logger my_logger("my_logger", { nullsink }); auto start = system_clock::now(); for (unsigned int i = 1; i <= howmany; ++i) my_logger.info() << "Hello logger: msg #" << i; - - auto delta = system_clock::now() - start; auto delta_d = duration_cast> (delta).count(); diff --git a/example/example.cpp b/example/example.cpp index c00f868e..465dd630 100644 --- a/example/example.cpp +++ b/example/example.cpp @@ -9,7 +9,7 @@ #include "c11log/sinks/file_sinks.h" using namespace std; -int main(int, char* []) +int main2(int, char* []) { auto console = c11log::factory::stdout_logger(); diff --git a/include/c11log/details/fast_istostr.h b/include/c11log/details/fast_istostr.h index 3221962d..50f2ad35 100644 --- a/include/c11log/details/fast_istostr.h +++ b/include/c11log/details/fast_istostr.h @@ -3,7 +3,7 @@ //Fast to int to string //Source: http://stackoverflow.com/a/4351484/192001 -//Modified version to pad zeros according to min_size +//Modified version to pad zeros according to padding arg namespace c11log { namespace details { diff --git a/include/c11log/details/fast_oss.h b/include/c11log/details/fast_oss.h index 121f0310..9744fb24 100644 --- a/include/c11log/details/fast_oss.h +++ b/include/c11log/details/fast_oss.h @@ -105,21 +105,21 @@ public: _dev.clear(); } - // The following were added because they add significant boost to perfromance + // + // The following were added because they significantly boost to perfromance + // void putc(char c) { _dev.sputc(c); + this->width(4); } - // put int and pad with zeroes if smalled than min_width - void put_int(int n, int min_width) + void put_int(int n, int padding) { std::string s; - details::fast_itostr(n, s, min_width); + details::fast_itostr(n, s, padding); _dev.sputn(s.data(), s.size()); - //sprintf_s(buf, "%d", n); - //_dev.sputn(buf, width); } void put_str(const std::string& s) diff --git a/include/c11log/details/pattern_formatter.h b/include/c11log/details/pattern_formatter.h index 22041d80..58e932d0 100644 --- a/include/c11log/details/pattern_formatter.h +++ b/include/c11log/details/pattern_formatter.h @@ -8,19 +8,20 @@ #include "../formatter.h" #include "log_msg.h" #include "fast_oss.h" +#include "os.h" namespace c11log { namespace details { -class pattern_appender +class pattern_compiler { public: virtual void append(const details::log_msg& msg, details::fast_oss& oss) = 0; }; // log name appender -class name_appender :public pattern_appender +class name_compiler :public pattern_compiler { void append(const details::log_msg& msg, details::fast_oss& oss) override { @@ -29,7 +30,7 @@ class name_appender :public pattern_appender }; // log level appender -class level_appender :public pattern_appender +class level_compiler :public pattern_compiler { void append(const details::log_msg& msg, details::fast_oss& oss) override { @@ -42,7 +43,7 @@ class level_appender :public pattern_appender /////////////////////////////////////////////////////////////////////// // year - 4 digit -class Y_appender :public pattern_appender +class Y_compiler :public pattern_compiler { void append(const details::log_msg& msg, details::fast_oss& oss) override { @@ -51,7 +52,7 @@ class Y_appender :public pattern_appender }; // year - 2 digit -class y_appender :public pattern_appender +class y_compiler :public pattern_compiler { void append(const details::log_msg& msg, details::fast_oss& oss) override { @@ -59,7 +60,7 @@ class y_appender :public pattern_appender } }; // month 1-12 -class m_appender :public pattern_appender +class m_compiler :public pattern_compiler { void append(const details::log_msg& msg, details::fast_oss& oss) override { @@ -67,9 +68,8 @@ class m_appender :public pattern_appender } }; - // day of month 1-31 -class d_appender :public pattern_appender +class d_compiler :public pattern_compiler { void append(const details::log_msg& msg, details::fast_oss& oss) override { @@ -78,7 +78,7 @@ class d_appender :public pattern_appender }; // hours in 24 format 0-23 -class H_appender :public pattern_appender +class H_compiler :public pattern_compiler { void append(const details::log_msg& msg, details::fast_oss& oss) override { @@ -87,7 +87,7 @@ class H_appender :public pattern_appender }; // hours in 12 format 1-12 -class I_appender :public pattern_appender +class I_compiler :public pattern_compiler { void append(const details::log_msg& msg, details::fast_oss& oss) override { @@ -96,7 +96,7 @@ class I_appender :public pattern_appender }; // ninutes 0-59 -class M_appender :public pattern_appender +class M_compiler :public pattern_compiler { void append(const details::log_msg& msg, details::fast_oss& oss) override { @@ -105,7 +105,7 @@ class M_appender :public pattern_appender }; // seconds 0-59 -class S_appender :public pattern_appender +class S_compiler :public pattern_compiler { void append(const details::log_msg& msg, details::fast_oss& oss) override { @@ -114,7 +114,7 @@ class S_appender :public pattern_appender }; // milliseconds -class e_appender :public pattern_appender +class e_compiler :public pattern_compiler { void append(const details::log_msg& msg, details::fast_oss& oss) override { @@ -125,7 +125,7 @@ class e_appender :public pattern_appender }; -class t_appender :public pattern_appender +class t_compiler :public pattern_compiler { void append(const details::log_msg& msg, details::fast_oss& oss) override { @@ -133,10 +133,10 @@ class t_appender :public pattern_appender } }; -class ch_appender :public pattern_appender +class ch_compiler :public pattern_compiler { public: - explicit ch_appender(char ch) : _ch(ch) + explicit ch_compiler(char ch) : _ch(ch) {} void append(const details::log_msg&, details::fast_oss& oss) override { @@ -147,10 +147,10 @@ private: }; -class str_appender :public pattern_appender +class str_compiler :public pattern_compiler { public: - str_appender() + str_compiler() {} void add_ch(char ch) { @@ -175,7 +175,7 @@ public: void format(details::log_msg& msg) override; private: const std::string _pattern; - std::vector> _appenders; + std::vector> _compilers; void handle_flag(char flag); void compile_pattern(const std::string& pattern); }; @@ -204,7 +204,7 @@ inline void c11log::details::pattern_formatter::compile_pattern(const std::strin else { // chars not following the % sign should be displayed as is - _appenders.push_back(std::unique_ptr(new details::ch_appender(*it))); + _compilers.push_back(std::unique_ptr(new details::ch_compiler(*it))); } } @@ -215,66 +215,65 @@ inline void c11log::details::pattern_formatter::handle_flag(char flag) { // logger name case 'n': - _appenders.push_back(std::unique_ptr(new details::name_appender())); + _compilers.push_back(std::unique_ptr(new details::name_compiler())); break; // message log level case 'l': - _appenders.push_back(std::unique_ptr(new details::level_appender())); + _compilers.push_back(std::unique_ptr(new details::level_compiler())); break; // message text case('t') : - _appenders.push_back(std::unique_ptr(new details::t_appender())); + _compilers.push_back(std::unique_ptr(new details::t_compiler())); break; // year case('Y') : - _appenders.push_back(std::unique_ptr(new details::Y_appender())); + _compilers.push_back(std::unique_ptr(new details::Y_compiler())); break; // year 2 digits case('y') : - _appenders.push_back(std::unique_ptr(new details::y_appender())); + _compilers.push_back(std::unique_ptr(new details::y_compiler())); break; // month case('m') : // minute - _appenders.push_back(std::unique_ptr(new details::m_appender())); + _compilers.push_back(std::unique_ptr(new details::m_compiler())); break; // day in month case('d') : - _appenders.push_back(std::unique_ptr(new details::d_appender())); + _compilers.push_back(std::unique_ptr(new details::d_compiler())); break; // hour (24) case('H') : - _appenders.push_back(std::unique_ptr(new details::H_appender())); + _compilers.push_back(std::unique_ptr(new details::H_compiler())); break; // hour (12) case('I') : - _appenders.push_back(std::unique_ptr(new details::I_appender())); + _compilers.push_back(std::unique_ptr(new details::I_compiler())); break; // minutes case('M') : - _appenders.push_back(std::unique_ptr(new details::M_appender())); + _compilers.push_back(std::unique_ptr(new details::M_compiler())); break; // seconds case('S') : - _appenders.push_back(std::unique_ptr(new details::S_appender())); + _compilers.push_back(std::unique_ptr(new details::S_compiler())); break; // milliseconds part case('e'): - _appenders.push_back(std::unique_ptr(new details::e_appender())); + _compilers.push_back(std::unique_ptr(new details::e_compiler())); break; // % sign case('%') : - _appenders.push_back(std::unique_ptr(new details::ch_appender('%'))); + _compilers.push_back(std::unique_ptr(new details::ch_compiler('%'))); break; } - } inline void c11log::details::pattern_formatter::format(details::log_msg& msg) { details::fast_oss oss; - for (auto &appender : _appenders) + for (auto &appender : _compilers) { appender->append(msg, oss); } diff --git a/include/c11log/factory.h b/include/c11log/factory.h index dfca8bf3..309a7098 100644 --- a/include/c11log/factory.h +++ b/include/c11log/factory.h @@ -18,13 +18,13 @@ namespace factory std::unique_ptr stdout_logger(const std::string& name = "") { auto sink = std::make_shared(); - return std::unique_ptr(new logger(name, sink)); + return std::unique_ptr(new logger(name, { sink })); } std::unique_ptr stdout_logger_mt(const std::string& name = "") { auto sink = std::make_shared(); - return std::unique_ptr(new logger(name, sink)); + return std::unique_ptr(new logger(name, { sink })); } // @@ -33,13 +33,13 @@ std::unique_ptr stdout_logger_mt(const std::string& name = "") std::unique_ptr simple_file_logger(const std::string& filename, const std::string& logger_name = "" ) { auto fsink = std::make_shared(filename); - return std::unique_ptr(new c11log::logger(logger_name, fsink)); + return std::unique_ptr(new c11log::logger(logger_name, { fsink })); } std::unique_ptr simple_file_logger_mt(const std::string& filename, const std::string& logger_name = "") { auto fsink = std::make_shared(filename); - return std::unique_ptr(new c11log::logger(logger_name, fsink)); + return std::unique_ptr(new c11log::logger(logger_name, { fsink })); } // @@ -52,7 +52,7 @@ std::unique_ptr daily_file_logger( const std::string& logger_name = "") { auto fsink = std::make_shared(filename, extension, flush_every); - return std::unique_ptr(new c11log::logger(logger_name, fsink)); + return std::unique_ptr(new c11log::logger(logger_name, { fsink })); } std::unique_ptr daily_file_logger_mt( @@ -62,7 +62,7 @@ std::unique_ptr daily_file_logger_mt( const std::string& logger_name = "") { auto fsink = std::make_shared(filename, extension, flush_every); - return std::unique_ptr(new c11log::logger(logger_name, fsink)); + return std::unique_ptr(new c11log::logger(logger_name, { fsink })); } // @@ -77,7 +77,7 @@ std::unique_ptr rotating_file_logger( const std::string& logger_name = "") { auto fsink = std::make_shared(filename, extension, max_size, max_files, flush_every); - return std::unique_ptr(new c11log::logger(logger_name, fsink)); + return std::unique_ptr(new c11log::logger(logger_name, { fsink })); } std::unique_ptr rotating_file_logger_mt( @@ -89,7 +89,7 @@ std::unique_ptr rotating_file_logger_mt( const std::string& logger_name = "") { auto fsink = std::make_shared(filename, extension, max_size, max_files, flush_every); - return std::unique_ptr(new c11log::logger(logger_name, fsink)); + return std::unique_ptr(new c11log::logger(logger_name, { fsink })); } } // ns factory } // ns c11log diff --git a/include/c11log/formatter.h b/include/c11log/formatter.h index cea5c920..f7b2b5fd 100644 --- a/include/c11log/formatter.h +++ b/include/c11log/formatter.h @@ -1,19 +1,5 @@ #pragma once - -#include -#include - -#include -#include -#include -#include - -#include "common.h" -#include "details/os.h" #include "details/log_msg.h" -#include "details/fast_oss.h" - - namespace c11log { diff --git a/include/c11log/logger.h b/include/c11log/logger.h index abf523f8..14c6d7c8 100644 --- a/include/c11log/logger.h +++ b/include/c11log/logger.h @@ -29,15 +29,11 @@ class logger { public: using sink_ptr = std::shared_ptr; - using sinks_vector_t = std::vector; - using sinks_init_list = std::initializer_list; - using formatter_ptr = std::unique_ptr; + using formatter_ptr = std::shared_ptr; - logger(const std::string& name, sinks_init_list, formatter_ptr = nullptr); + logger(const std::string& name, std::initializer_list, formatter_ptr formatter = nullptr); template - logger(const std::string& name, It begin, It end, formatter_ptr = nullptr); - logger(const std::string& name, sink_ptr, formatter_ptr = nullptr); - ~logger() = default; + logger(const std::string& name, const It& begin, const It& end); logger(const logger&) = delete; logger& operator=(const logger&) = delete; @@ -48,6 +44,9 @@ public: const std::string& name() const; bool should_log(level::level_enum) const; + void formatter(formatter_ptr); + formatter_ptr formatter() const; + template details::line_logger log(level::level_enum lvl, const Args&... args); template details::line_logger trace(const Args&... args); @@ -57,20 +56,18 @@ public: template details::line_logger error(const Args&... args); template details::line_logger critical(const Args&... args); - - - private: friend details::line_logger; std::string _name; formatter_ptr _formatter; - sinks_vector_t _sinks; + std::vector _sinks; std::atomic_int _level; - void _variadic_log(details::line_logger& l); template void _variadic_log(details::line_logger&l, const First& first, const Rest&... rest); void _log_msg(details::log_msg& msg); + formatter_ptr _default_formatter(); + const char* _default_pattern = "[%Y:%m:%d %H:%M:%S.%e] [%n:%l] %t"; }; @@ -98,30 +95,24 @@ private: #include "details/line_logger.h" -inline c11log::logger::logger(const std::string& logger_name, sinks_init_list sinks_list, formatter_ptr f) : +inline c11log::logger::logger(const std::string& logger_name, std::initializer_list sinks_list, formatter_ptr formatter) : _name(logger_name), - _formatter(std::move(f)), + _formatter(formatter), _sinks(sinks_list) { - //Seems that vs2013 doesn't support std::atomic member initialization yet + if (!formatter) //default formatter + _formatter = std::make_shared(_default_pattern); + + //Seems that vs2013 doesn't support atomic member initialization yet _level = level::INFO; - if(!_formatter) - _formatter = formatter_ptr(new details::pattern_formatter("%t")); } template -inline c11log::logger::logger(const std::string& logger_name, It begin, It end, formatter_ptr f): +inline c11log::logger::logger(const std::string& logger_name, const It& begin, const It& end): _name(logger_name), - _formatter(std::move(f)), _sinks(begin, end) -{ - -} - -inline c11log::logger::logger(const std::string& logger_name, sink_ptr sink, formatter_ptr f) : - logger(logger_name, {sink}, std::move(f)) {} - +{} template inline c11log::details::line_logger c11log::logger::log(level::level_enum lvl, const Args&... args) { @@ -130,35 +121,36 @@ inline c11log::details::line_logger c11log::logger::log(level::level_enum lvl, c return l; } - template -inline c11log::details::line_logger c11log::logger::trace(const Args&... args) { +inline c11log::details::line_logger c11log::logger::trace(const Args&... args) +{ return log(level::TRACE, args...); } template -inline c11log::details::line_logger c11log::logger::debug(const Args&... args) { +inline c11log::details::line_logger c11log::logger::debug(const Args&... args) +{ return log(level::DEBUG, args...); } template -inline c11log::details::line_logger c11log::logger::info(const Args&... args) { +inline c11log::details::line_logger c11log::logger::info(const Args&... args) +{ return log(level::INFO, args...); } - template -inline c11log::details::line_logger c11log::logger::warn(const Args&... args) { +inline c11log::details::line_logger c11log::logger::warn(const Args&... args) +{ return log(level::WARNING, args...); } template -inline c11log::details::line_logger c11log::logger::critical(const Args&... args) { +inline c11log::details::line_logger c11log::logger::critical(const Args&... args) +{ return log(level::CRITICAL, args...); } - - inline const std::string& c11log::logger::name() const { return _name; @@ -180,6 +172,18 @@ inline bool c11log::logger::should_log(c11log::level::level_enum msg_level) cons } +inline void c11log::logger::formatter(formatter_ptr formatter) +{ + _formatter = formatter; +} + +inline c11log::logger::formatter_ptr c11log::logger::formatter() const +{ + return _formatter; +} + + + inline void c11log::logger::_variadic_log(c11log::details::line_logger&) {} template diff --git a/include/c11log/sinks/async_sink.h b/include/c11log/sinks/async_sink.h index 8860f88d..48a1abfa 100644 --- a/include/c11log/sinks/async_sink.h +++ b/include/c11log/sinks/async_sink.h @@ -39,7 +39,7 @@ protected: void _thread_loop(); private: - c11log::logger::sinks_vector_t _sinks; + std::vector> _sinks; std::atomic _active; q_type _q; std::thread _back_thread; diff --git a/include/c11log/sinks/null_sink.h b/include/c11log/sinks/null_sink.h index 4526eef6..30c62714 100644 --- a/include/c11log/sinks/null_sink.h +++ b/include/c11log/sinks/null_sink.h @@ -1,6 +1,8 @@ #pragma once - +#include #include "base_sink.h" +#include "../details/null_mutex.h" + namespace c11log { namespace sinks { @@ -13,6 +15,9 @@ protected: {} }; +typedef null_sink null_sink_st; +typedef null_sink null_sink_mt; + } }