Hey, I have been coding a 30 minutes logging library for my applications, I would appreciate some comments about it.
Thank You!
Code:#include <iostream> #include <string> #include <cassert> #include <fstream> #include <functional> namespace log_level { enum type { ok, info, warning, error }; const char* get_string(type level) { switch (level) { case ok: return "OK"; case info: return "INFO"; case warning: return "WARNING"; case error: return "ERROR"; } assert(false); return ""; } }; template<class Char, class Traits = std::char_traits<Char> > class basic_log_message { typedef Char char_t; const char_t* m_message; log_level::type m_level; public: const char_t* get_message() const { return m_message; } log_level::type get_level() const { return m_level; } basic_log_message(const char_t* message, log_level::type level = log_level::ok) : m_message(message) , m_level(level) { } }; typedef basic_log_message<wchar_t, std::char_traits<wchar_t> > wlog_message; typedef basic_log_message<char, std::char_traits<char> > log_message; template<class Char> struct basic_formatter; template<class Char, class Traits = std::char_traits<Char>, class Formatter = basic_formatter<Char> > class basic_logger { typedef Char char_t; typedef basic_logger<Char, Traits, Formatter> my_type; typedef basic_log_message<Char, Traits> message_t; // we use reference_wrapper so that we can reassign the output reference std::tr1::reference_wrapper<std::basic_ostream<Char, Traits> > m_output; protected: // unformatted logging template<class T> my_type& operator<<(const T& value) { m_output.get() << value; return *this; } public: basic_logger(std::basic_ostream<Char, Traits>& output) : m_output(std::tr1::ref(output)) { } void redirect(std::basic_ostream<Char, Traits>& output) { m_output = std::tr1::ref(output); } void put(const message_t& message) { Formatter::append_message(*this, message); } void put(const char_t* message) { put(log_message(message)); } friend typename Formatter; }; typedef basic_logger<wchar_t, std::char_traits<wchar_t> > wlogger; typedef basic_logger<char, std::char_traits<char> > logger; extern wlogger wlog(std::wcout); extern logger log(std::cout ); template<class Char, class Traits> basic_logger<Char, Traits>& operator<<(basic_logger<Char, Traits>& other_logger, const basic_log_message<Char, Traits>& message) { other_logger.put(message); return other_logger; } template<class Char> struct basic_formatter { }; template<> struct basic_formatter<char> { template<class Traits> static void append_message(basic_logger<char, Traits, basic_formatter<char> >& logger, const basic_log_message<char, Traits>& message) { logger << '[' << log_level::get_string(message.get_level()) << "] " << message.get_message() << "\n"; } }; template<> struct basic_formatter<wchar_t> { template<class Traits> static void append_message(basic_logger<wchar_t, Traits, basic_formatter<wchar_t> >& logger, const basic_log_message<wchar_t, Traits>& message) { logger << L'[' << log_level::get_string(message.get_level()) << L"] " << message.get_message() << L"\n"; } }; void main() { std::ofstream file("log.txt"); log.redirect(file); log << log_message("teste") << log_message("kk", log_level::error); wlog << wlog_message(L"teste2"); }



LinkBack URL
About LinkBacks
.




