diff --git a/c11logtest/c11logtest/c11logtest.vcxproj b/c11logtest/c11logtest/c11logtest.vcxproj
index a3c4d9d7..dea51281 100644
--- a/c11logtest/c11logtest/c11logtest.vcxproj
+++ b/c11logtest/c11logtest/c11logtest.vcxproj
@@ -95,8 +95,8 @@
+
-
@@ -114,6 +114,9 @@
+
+
+
diff --git a/c11logtest/c11logtest/c11logtest.vcxproj.filters b/c11logtest/c11logtest/c11logtest.vcxproj.filters
index 7d6eba11..6373709b 100644
--- a/c11logtest/c11logtest/c11logtest.vcxproj.filters
+++ b/c11logtest/c11logtest/c11logtest.vcxproj.filters
@@ -84,9 +84,6 @@
Header Files\c11log
-
- Header Files\c11log
-
Header Files\c11log\details
@@ -96,6 +93,9 @@
Header Files\c11log\details
+
+ Header Files\c11log
+
@@ -108,4 +108,7 @@
Source Files
+
+
+
\ No newline at end of file
diff --git a/example/bench.cpp b/example/bench.cpp
index c15ee905..a0e24f6f 100644
--- a/example/bench.cpp
+++ b/example/bench.cpp
@@ -2,63 +2,40 @@
//
#include
#include "c11log/logger.h"
-#include "c11log/factory.h"
#include "c11log/sinks/async_sink.h"
#include "c11log/sinks/file_sinks.h"
#include "c11log/sinks/stdout_sinks.h"
#include "c11log/sinks/null_sink.h"
#include "utils.h"
+#include "c11log/details/registry.h"
using namespace std::chrono;
using namespace c11log;
using namespace utils;
-std::ostringstream f1(int i)
-{
-
- std::ostringstream oss;
- oss << "Hello oss " << i;
- return oss;
-}
-
-details::fast_oss f2(int i)
-{
-
- details::fast_oss oss;
- oss << "Hello oss " << i;
- return oss;
-}
int main(int argc, char* argv[])
{
const unsigned int howmany = argc <= 1 ? 600000 : atoi(argv[1]);
- const std::string pattern = "%+";
- auto formatter = std::make_shared(pattern);
- //logger cout_logger("bench", { std::make_shared() }, pattern);
- //logger::default_formatter(formatter);
- logger cout_logger("bench", { std::make_shared() });
- logger::default_formatter(formatter);
- cout_logger.info() << "Hello logger " << 12.4 << 5 << ',' << 6 << 7 <<8<<9<<10;
- auto nullsink = std::make_shared();
- auto rotating = std::make_shared("myrotating", "txt", 1024 * 1024 * 5, 20, 100);
-
- logger my_logger("my_logger", { nullsink });
-
-
+ auto console = c11log::create("reporter");
+ console->set_format("[%n %l] %t");
+ console->set_level(c11log::level::INFO);
+ console->info("Starting bench with", howmany, "iterations..");
+ auto bench = c11log::create("bench", "myrotating", "txt", 1024 * 1024 * 5, 3, 100);
auto start = system_clock::now();
for (unsigned int i = 1; i <= howmany; ++i)
{
- my_logger.info() << "Hello logger: msg #" << i;
+ bench->info() << "Hello logger: msg number " << i;
}
auto delta = system_clock::now() - start;
auto delta_d = duration_cast> (delta).count();
- cout_logger.info("Total:") << format(howmany);
- cout_logger.info("Delta:") << format(delta_d);
- cout_logger.info("Rate:") << format(howmany / delta_d) << "/sec";
+ console->info("Total:") << format(howmany);
+ console->info("Delta:") << format(delta_d);
+ console->info("Rate:") << format(howmany / delta_d) << "/sec";
return 0;
}
diff --git a/example/example.cpp b/example/example.cpp
index 55b17ed8..c9b0ae50 100644
--- a/example/example.cpp
+++ b/example/example.cpp
@@ -4,7 +4,6 @@
#include
#include "c11log/logger.h"
-#include "c11log/factory.h"
#include "c11log/sinks/stdout_sinks.h"
#include "c11log/sinks/file_sinks.h"
using namespace std;
diff --git a/include/c11log/common.h b/include/c11log/common.h
index cfcc0430..32666ca1 100644
--- a/include/c11log/common.h
+++ b/include/c11log/common.h
@@ -25,8 +25,8 @@ typedef enum
TRACE,
DEBUG,
INFO,
- WARNING,
- ERROR,
+ WARN,
+ ERR,
CRITICAL,
NONE = 99
} level_enum;
diff --git a/include/c11log/details/pattern_formatter.h b/include/c11log/details/pattern_formatter.h
index 70f6dfeb..98d07b75 100644
--- a/include/c11log/details/pattern_formatter.h
+++ b/include/c11log/details/pattern_formatter.h
@@ -19,7 +19,9 @@ public:
virtual void format(details::log_msg& msg) = 0;
};
-// log name appender
+///////////////////////////////////////////////////////////////////////
+// name & level pattern appenders
+///////////////////////////////////////////////////////////////////////
class name_formatter :public flag_formatter
{
void format(details::log_msg& msg) override
diff --git a/include/c11log/details/registry.h b/include/c11log/details/registry.h
new file mode 100644
index 00000000..9b0ae81b
--- /dev/null
+++ b/include/c11log/details/registry.h
@@ -0,0 +1,59 @@
+#pragma once
+// Loggers registy of unique name->logger pointer
+// If 2 loggers with same name are added, the last will be used
+// If user requests a non existing logger, nullptr will be returned
+// This class is thread safe
+
+#include
+#include
+#include
+#include "../logger.h"
+#include "../common.h"
+
+namespace c11log {
+namespace details {
+class registry {
+public:
+ std::shared_ptr get(const std::string& name)
+ {
+ std::lock_guard l(_mutex);
+ auto found = _loggers.find(name);
+ return found == _loggers.end() ? nullptr : found->second;
+ }
+ std::shared_ptr create(const std::string& logger_name, sinks_init_list sinks)
+ {
+ std::lock_guard l(_mutex);
+ return _loggers[logger_name] = std::make_shared(logger_name, sinks);
+ }
+
+ std::shared_ptr create(const std::string& logger_name, sink_ptr sink)
+ {
+ create(logger_name, { sink });
+ }
+
+
+ template
+ std::shared_ptr create (const std::string& logger_name, const It& sinks_begin, const It& sinks_end)
+ {
+ std::lock_guard l(_mutex);
+ return _loggers[logger_name] = std::make_shared(logger_name, sinks_begin, sinks_end);
+ }
+
+
+
+
+ static registry& instance()
+ {
+ static registry s_instance;
+ return s_instance;
+ }
+
+private:
+ registry() = default;
+ registry(const registry&) = delete;
+ std::mutex _mutex;
+ std::unordered_map > _loggers;
+
+};
+}
+}
diff --git a/include/c11log/factory.h b/include/c11log/factory.h
deleted file mode 100644
index bb184f3f..00000000
--- a/include/c11log/factory.h
+++ /dev/null
@@ -1,106 +0,0 @@
-#pragma once
-#include
-#include "logger.h"
-#include "sinks/file_sinks.h"
-#include "sinks/stdout_sinks.h"
-
-//
-// logger creation shotcuts
-//
-namespace c11log
-{
-namespace factory
-{
-//
-//
-//std::shared_ptr get(const std::string& name);
-//std::shared_ptr create(const std::string& name, sinks_init_list , formatter_ptr);
-//std::shared_ptr create(const std::string& name, sinks_init_list, string format);
-//template
-//std::shared_ptr create (const std::string& name, const It& begin, const It& end);
-
-
-
-//
-//
-////
-//// console loggers single/multi threaded
-////
-//std::unique_ptr stdout_logger(const std::string& name = "")
-//{
-// auto sink = std::make_shared();
-// 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 }));
-//}
-//
-////
-//// simple file logger single/multi threaded
-////
-//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 }));
-//
-//}
-//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 }));
-//}
-//
-////
-//// daily file logger single/multi threaded
-////
-//std::unique_ptr daily_file_logger(
-// const std::string &filename,
-// const std::string &extension,
-// const std::size_t flush_every,
-// const std::string& logger_name = "")
-//{
-// auto fsink = std::make_shared(filename, extension, flush_every);
-// return std::unique_ptr(new c11log::logger(logger_name, { fsink }));
-//}
-//
-//std::unique_ptr daily_file_logger_mt(
-// const std::string &filename,
-// const std::string &extension,
-// const std::size_t flush_every,
-// const std::string& logger_name = "")
-//{
-// auto fsink = std::make_shared(filename, extension, flush_every);
-// return std::unique_ptr(new c11log::logger(logger_name, { fsink }));
-//}
-//
-////
-//// rotating file logger single/multi threaded
-////
-//std::unique_ptr rotating_file_logger(
-// const std::string &filename,
-// const std::string &extension,
-// const std::size_t max_size,
-// const std::size_t max_files,
-// const std::size_t flush_every,
-// 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 }));
-//}
-//
-//std::unique_ptr rotating_file_logger_mt(
-// const std::string &filename,
-// const std::string &extension,
-// const std::size_t max_size,
-// const std::size_t max_files,
-// const std::size_t flush_every,
-// 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 }));
-//}
-} // ns factory
-} // ns c11log
diff --git a/include/c11log/logger.h b/include/c11log/logger.h
index a6857a87..d405697e 100644
--- a/include/c11log/logger.h
+++ b/include/c11log/logger.h
@@ -16,6 +16,7 @@
#include "common.h"
#include "details/pattern_formatter.h"
+
namespace c11log
{
@@ -32,20 +33,15 @@ public:
template
logger(const std::string& name, const It& begin, const It& end);
-
- //get/set default formatter
- static formatter_ptr& default_formatter(formatter_ptr formatter = nullptr);
-
+ void c11log::logger::set_format(const std::string& format);
void set_formatter(formatter_ptr);
formatter_ptr get_formatter() const;
-
-
logger(const logger&) = delete;
logger& operator=(const logger&) = delete;
- void level(level::level_enum);
+ void set_level(level::level_enum);
level::level_enum level() const;
const std::string& name() const;
@@ -59,6 +55,11 @@ public:
template details::line_logger error(const Args&... args);
template details::line_logger critical(const Args&... args);
+ //static functions
+ //get/set default formatter
+ static formatter_ptr default_formatter(formatter_ptr formatter = nullptr);
+ static formatter_ptr default_format(const std::string& format);
+
private:
friend details::line_logger;
std::string _name;
@@ -70,10 +71,27 @@ private:
void _variadic_log(details::line_logger&l, const First& first, const Rest&... rest);
void _log_msg(details::log_msg& msg);
};
+
+//
+// Registry functions for easy loggers creation and retrieval
+// example
+// auto console_logger = c11log::create("my_logger", c11log::sinks);
+// auto same_logger = c11log::get("my_logger");
+// auto file_logger = c11
+//
+std::shared_ptr get(const std::string& name);
+
+std::shared_ptr create(const std::string& logger_name, sinks_init_list sinks);
+
+template
+std::shared_ptr create(const std::string& logger_name, const Args&... args);
+
+template
+std::shared_ptr create(const std::string& logger_name, const It& sinks_begin, const It& sinks_end);
}
//
-// trace & debug macros
+// Trace & debug macros
//
#ifdef FFLOG_ENABLE_TRACE
#define FFLOG_TRACE(logger, ...) logger->log(c11log::level::TRACE, __FILE__, " #", __LINE__,": " __VA_ARGS__)
@@ -114,12 +132,17 @@ inline void c11log::logger::set_formatter(c11log::formatter_ptr msg_formatter)
_formatter = msg_formatter;
}
+inline void c11log::logger::set_format(const std::string& format)
+{
+ _formatter = std::make_shared(format);
+}
+
inline c11log::formatter_ptr c11log::logger::get_formatter() const
{
return _formatter;
}
-inline c11log::formatter_ptr& c11log::logger::default_formatter(formatter_ptr formatter)
+inline c11log::formatter_ptr c11log::logger::default_formatter(formatter_ptr formatter)
{
static formatter_ptr g_default_formatter = std::make_shared("[%Y-%m-%d %H:%M:%S.%e] [%n] [%l] %t");
if (formatter)
@@ -127,6 +150,11 @@ inline c11log::formatter_ptr& c11log::logger::default_formatter(formatter_ptr fo
return g_default_formatter;
}
+inline c11log::formatter_ptr c11log::logger::default_format(const std::string& format)
+{
+ return default_formatter(std::make_shared(format));
+}
+
template
inline c11log::details::line_logger c11log::logger::log(level::level_enum lvl, const Args&... args) {
bool msg_enabled = should_log(lvl);
@@ -157,13 +185,13 @@ inline c11log::details::line_logger c11log::logger::info(const Args&... args)
template
inline c11log::details::line_logger c11log::logger::warn(const Args&... args)
{
- return log(level::WARNING, args...);
+ return log(level::WARN, args...);
}
template
inline c11log::details::line_logger c11log::logger::error(const Args&... args)
{
- return log(level::ERROR, args...);
+ return log(level::ERR, args...);
}
template
@@ -177,7 +205,7 @@ inline const std::string& c11log::logger::name() const
return _name;
}
-inline void c11log::logger::level(c11log::level::level_enum log_level)
+inline void c11log::logger::set_level(c11log::level::level_enum log_level)
{
_level.store(log_level);
}
@@ -201,15 +229,49 @@ template
void c11log::logger::_variadic_log(c11log::details::line_logger& l, const First& first, const Rest&... rest)
{
l.write(first);
+ l.write(' ');
_variadic_log(l, rest...);
}
inline void c11log::logger::_log_msg(details::log_msg& msg)
{
- auto& formatter = _formatter ? _formatter : logger::default_formatter();
- formatter->format(msg);
+ if(!_formatter)
+ _formatter = logger::default_formatter();
+ _formatter->format(msg);
for (auto &sink : _sinks)
sink->log(msg);
}
+//
+// Global registry functions
+//
+#include "details/registry.h"
+inline std::shared_ptr c11log::get(const std::string& name)
+{
+ return details::registry::instance().get(name);
+}
+
+inline std::shared_ptr c11log::create(const std::string& logger_name, c11log::sinks_init_list sinks)
+{
+ return details::registry::instance().create(logger_name, sinks);
+}
+
+
+template
+inline std::shared_ptr c11log::create(const std::string& logger_name, const Args&... args)
+{
+ sink_ptr sink = std::make_shared(args...);
+ return details::registry::instance().create(logger_name, { sink });
+}
+
+
+
+template
+inline std::shared_ptr c11log::create(const std::string& logger_name, const It& sinks_begin, const It& sinks_end)
+{
+ std::lock_guard l(_mutex);
+ return details::registry::instance().create(logger_name, std::forward(sinks_begin), std::forward(sinks_end));
+}
+
+