diff --git a/c11logtest/c11logtest/c11logtest.vcxproj b/c11logtest/c11logtest/c11logtest.vcxproj
index dea51281..3c046302 100644
--- a/c11logtest/c11logtest/c11logtest.vcxproj
+++ b/c11logtest/c11logtest/c11logtest.vcxproj
@@ -91,10 +91,11 @@
+
-
+
diff --git a/c11logtest/c11logtest/c11logtest.vcxproj.filters b/c11logtest/c11logtest/c11logtest.vcxproj.filters
index 6373709b..4794c326 100644
--- a/c11logtest/c11logtest/c11logtest.vcxproj.filters
+++ b/c11logtest/c11logtest/c11logtest.vcxproj.filters
@@ -90,11 +90,14 @@
Header Files\c11log\sinks
-
+
+ Header Files\c11log\details
+
+
Header Files\c11log\details
- Header Files\c11log
+ Header Files\c11log\details
diff --git a/example/bench.cpp b/example/bench.cpp
index a0e24f6f..807cb2c3 100644
--- a/example/bench.cpp
+++ b/example/bench.cpp
@@ -1,6 +1,5 @@
// example.cpp : Simple logger example
//
-#include
#include "c11log/logger.h"
#include "c11log/sinks/async_sink.h"
#include "c11log/sinks/file_sinks.h"
@@ -18,16 +17,18 @@ int main(int argc, char* argv[])
{
const unsigned int howmany = argc <= 1 ? 600000 : atoi(argv[1]);
- auto console = c11log::create("reporter");
- console->set_format("[%n %l] %t");
+ c11log::set_format("%t");
+ 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 bench = c11log::create("bench", "myrotating", "txt", 1024 * 1024 * 5, 3, 100);
+ auto bench = c11log::create("bench");
auto start = system_clock::now();
for (unsigned int i = 1; i <= howmany; ++i)
{
- bench->info() << "Hello logger: msg number " << i;
+ c11log::get("bench")->info("Hello logger: msg number", i);
}
auto delta = system_clock::now() - start;
diff --git a/include/c11log/details/logger_impl.h b/include/c11log/details/logger_impl.h
new file mode 100644
index 00000000..aca750a8
--- /dev/null
+++ b/include/c11log/details/logger_impl.h
@@ -0,0 +1,168 @@
+#pragma once
+//
+// Logger implementation
+//
+
+
+#include "details/line_logger.h"
+
+
+inline c11log::logger::logger(const std::string& logger_name, sinks_init_list sinks_list) :
+ _name(logger_name),
+ _sinks(sinks_list)
+{
+ // no support under vs2013 for member initialization for std::atomic
+ _level = level::INFO;
+}
+
+template
+inline c11log::logger::logger(const std::string& logger_name, const It& begin, const It& end) :
+ _name(logger_name),
+ _sinks(begin, end)
+{}
+
+
+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;
+}
+
+
+template
+inline c11log::details::line_logger c11log::logger::log(level::level_enum lvl, const Args&... args) {
+ bool msg_enabled = should_log(lvl);
+ details::line_logger l(this, lvl, msg_enabled);
+ if (msg_enabled)
+ _variadic_log(l, args...);
+ return l;
+}
+
+template
+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)
+{
+ return log(level::DEBUG, args...);
+}
+
+template
+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)
+{
+ return log(level::WARN, args...);
+}
+
+template
+inline c11log::details::line_logger c11log::logger::error(const Args&... args)
+{
+ return log(level::ERR, args...);
+}
+
+template
+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;
+}
+
+inline void c11log::logger::set_level(c11log::level::level_enum log_level)
+{
+ _level.store(log_level);
+}
+
+inline c11log::level::level_enum c11log::logger::level() const
+{
+ return static_cast(_level.load());
+}
+
+inline bool c11log::logger::should_log(c11log::level::level_enum msg_level) const
+{
+ return msg_level >= _level.load();
+}
+
+inline void c11log::logger::_variadic_log(c11log::details::line_logger&) {}
+
+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)
+{
+ if (!_formatter)
+ _formatter = std::make_shared("%+ %t");
+ _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)
+{
+ return details::registry::instance().create(logger_name, std::forward(sinks_begin), std::forward(sinks_end));
+}
+
+
+inline void c11log::formatter(c11log::formatter_ptr f)
+{
+ return details::registry::instance().formatter(f);
+}
+
+inline c11log::formatter_ptr c11log::formatter()
+{
+ return details::registry::instance().formatter();
+}
+
+inline void c11log::set_format(const std::string& format_string)
+{
+ return details::registry::instance().set_format(format_string);
+}
diff --git a/include/c11log/details/pattern_formatter.h b/include/c11log/details/pattern_formatter_impl.h
similarity index 93%
rename from include/c11log/details/pattern_formatter.h
rename to include/c11log/details/pattern_formatter_impl.h
index 98d07b75..cdcf9401 100644
--- a/include/c11log/details/pattern_formatter.h
+++ b/include/c11log/details/pattern_formatter_impl.h
@@ -22,6 +22,7 @@ public:
///////////////////////////////////////////////////////////////////////
// name & level pattern appenders
///////////////////////////////////////////////////////////////////////
+namespace {
class name_formatter :public flag_formatter
{
void format(details::log_msg& msg) override
@@ -29,6 +30,7 @@ class name_formatter :public flag_formatter
msg.formatted << msg.logger_name;
}
};
+}
// log level appender
class level_formatter :public flag_formatter
@@ -374,35 +376,20 @@ class full_formatter :public flag_formatter
}
};
-
-
-class pattern_formatter : public formatter
-{
-
-public:
- explicit pattern_formatter(const std::string& pattern);
- pattern_formatter(const pattern_formatter&) = delete;
- void format(details::log_msg& msg) override;
-private:
- const std::string _pattern;
- std::vector> _formatters;
- void handle_flag(char flag);
- void compile_pattern(const std::string& pattern);
-};
}
}
///////////////////////////////////////////////////////////////////////////////
// pattern_formatter inline impl
///////////////////////////////////////////////////////////////////////////////
-inline c11log::details::pattern_formatter::pattern_formatter(const std::string& pattern)
+inline c11log::pattern_formatter::pattern_formatter(const std::string& pattern)
{
compile_pattern(pattern);
}
-inline void c11log::details::pattern_formatter::compile_pattern(const std::string& pattern)
+inline void c11log::pattern_formatter::compile_pattern(const std::string& pattern)
{
auto end = pattern.end();
- std::unique_ptr user_chars;
+ std::unique_ptr user_chars;
for (auto it = pattern.begin(); it != end; ++it)
{
if (*it == '%')
@@ -418,7 +405,7 @@ inline void c11log::details::pattern_formatter::compile_pattern(const std::strin
else // chars not following the % sign should be displayed as is
{
if (!user_chars)
- user_chars = std::unique_ptr(new aggregate_formatter());
+ user_chars = std::unique_ptr(new details::aggregate_formatter());
user_chars->add_ch(*it);
}
}
@@ -428,7 +415,7 @@ inline void c11log::details::pattern_formatter::compile_pattern(const std::strin
}
}
-inline void c11log::details::pattern_formatter::handle_flag(char flag)
+inline void c11log::pattern_formatter::handle_flag(char flag)
{
switch (flag)
{
@@ -540,7 +527,7 @@ inline void c11log::details::pattern_formatter::handle_flag(char flag)
}
-inline void c11log::details::pattern_formatter::format(details::log_msg& msg)
+inline void c11log::pattern_formatter::format(details::log_msg& msg)
{
for (auto &f : _formatters)
{
diff --git a/include/c11log/details/registry.h b/include/c11log/details/registry.h
index 9b0ae81b..71c0738c 100644
--- a/include/c11log/details/registry.h
+++ b/include/c11log/details/registry.h
@@ -1,6 +1,6 @@
#pragma once
// Loggers registy of unique name->logger pointer
-// If 2 loggers with same name are added, the last will be used
+// If 2 loggers with same name are added, the second will be overrun the first
// If user requests a non existing logger, nullptr will be returned
// This class is thread safe
@@ -23,12 +23,15 @@ public:
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);
+ auto new_logger = std::make_shared(logger_name, sinks);
+ new_logger->set_formatter(_formatter);
+ _loggers[logger_name] = new_logger;
+ return new_logger;
}
std::shared_ptr create(const std::string& logger_name, sink_ptr sink)
{
- create(logger_name, { sink });
+ return create(logger_name, { sink });
}
@@ -36,10 +39,27 @@ public:
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);
+ auto new_logger = std::make_shared(logger_name, sinks_begin, sinks_end);
+ new_logger->set_formatter(_formatter);
+ _loggers[logger_name] = new_logger;
+ return new_logger;
+
}
+ void formatter(formatter_ptr f)
+ {
+ _formatter = f;
+ }
+ formatter_ptr formatter()
+ {
+ return _formatter;
+ }
+
+ void set_format(const std::string& format_string)
+ {
+ _formatter = std::make_shared(format_string);
+ }
static registry& instance()
@@ -53,6 +73,7 @@ private:
registry(const registry&) = delete;
std::mutex _mutex;
std::unordered_map > _loggers;
+ formatter_ptr _formatter;
};
}
diff --git a/include/c11log/formatter.h b/include/c11log/formatter.h
index 9651729f..12c4dfca 100644
--- a/include/c11log/formatter.h
+++ b/include/c11log/formatter.h
@@ -1,7 +1,11 @@
#pragma once
+
#include "details/log_msg.h"
namespace c11log
{
+namespace details {
+class flag_formatter;
+}
class formatter
{
@@ -9,4 +13,21 @@ public:
virtual ~formatter() {}
virtual void format(details::log_msg& msg) = 0;
};
+
+class pattern_formatter : public formatter
+{
+
+public:
+ explicit pattern_formatter(const std::string& pattern);
+ pattern_formatter(const pattern_formatter&) = delete;
+ void format(details::log_msg& msg) override;
+private:
+ const std::string _pattern;
+ std::vector> _formatters;
+ void handle_flag(char flag);
+ void compile_pattern(const std::string& pattern);
+};
}
+
+#include "./details/pattern_formatter_impl.h"
+
diff --git a/include/c11log/logger.h b/include/c11log/logger.h
index d405697e..c43c3782 100644
--- a/include/c11log/logger.h
+++ b/include/c11log/logger.h
@@ -11,11 +11,9 @@
#include
#include
#include
-
+#include
#include "sinks/base_sink.h"
#include "common.h"
-#include "details/pattern_formatter.h"
-
namespace c11log
{
@@ -55,10 +53,6 @@ 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;
@@ -72,6 +66,18 @@ private:
void _log_msg(details::log_msg& msg);
};
+class fflog_exception : public std::exception
+{
+public:
+ fflog_exception(const std::string& msg) :_msg(msg) {};
+ const char* what() const throw() override {
+ return _msg.c_str();
+ }
+private:
+ std::string _msg;
+
+};
+
//
// Registry functions for easy loggers creation and retrieval
// example
@@ -80,14 +86,15 @@ private:
// 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);
+
+void formatter(formatter_ptr f);
+formatter_ptr formatter();
+void set_format(const std::string& format_string);
}
//
@@ -105,173 +112,4 @@ std::shared_ptr create(const std::string& logger_name, const It& sinks_b
#define FFLOG_DEBUG(logger, ...) {}
#endif
-//
-// Logger implementation
-//
-
-#include "details/line_logger.h"
-
-
-inline c11log::logger::logger(const std::string& logger_name, sinks_init_list sinks_list):
- _name(logger_name),
- _sinks(sinks_list)
-{
- // no support under vs2013 for member initialization for std::atomic
- _level = level::INFO;
-}
-
-template
-inline c11log::logger::logger(const std::string& logger_name, const It& begin, const It& end) :
- _name(logger_name),
- _sinks(begin, end)
-{}
-
-
-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)
-{
- static formatter_ptr g_default_formatter = std::make_shared("[%Y-%m-%d %H:%M:%S.%e] [%n] [%l] %t");
- if (formatter)
- g_default_formatter = formatter;
- 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);
- details::line_logger l(this, lvl, msg_enabled);
- if (msg_enabled)
- _variadic_log(l, args...);
- return l;
-}
-
-template
-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)
-{
- return log(level::DEBUG, args...);
-}
-
-template
-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)
-{
- return log(level::WARN, args...);
-}
-
-template
-inline c11log::details::line_logger c11log::logger::error(const Args&... args)
-{
- return log(level::ERR, args...);
-}
-
-template
-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;
-}
-
-inline void c11log::logger::set_level(c11log::level::level_enum log_level)
-{
- _level.store(log_level);
-}
-
-inline c11log::level::level_enum c11log::logger::level() const
-{
- return static_cast(_level.load());
-}
-
-inline bool c11log::logger::should_log(c11log::level::level_enum msg_level) const
-{
- return msg_level >= _level.load();
-}
-
-
-
-
-inline void c11log::logger::_variadic_log(c11log::details::line_logger&) {}
-
-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)
-{
- 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));
-}
-
-
-
+#include "./details/logger_impl.h"
\ No newline at end of file