diff --git a/src/log.hh b/src/log.hh new file mode 100644 index 0000000..dda3af8 --- /dev/null +++ b/src/log.hh @@ -0,0 +1,147 @@ +/* log.hh + * vim: set tw=80: + * Eryn Wells + */ + +#ifndef __LOG_HH__ +#define __LOG_HH__ + +#include +#include + +#include +#include +#include +#include +#include + + +namespace charles { +namespace log { + +/** Useful predefined levels. */ +namespace level { + unsigned int Error = 10; + unsigned int Warning = 20; + unsigned int Info = 30; + unsigned int Debug = 40; + unsigned int Trace = 50; +}; + + +struct Log +{ + static void Init(const std::string& filename); + static void Close(); + + Log(const std::string& name = "root", unsigned int level = level::Info); + ~Log(); + + template Log& operator<<(const T& item); + +private: + struct Logger + { + Logger(unsigned int level = level::Info); + + unsigned int level; + }; + + typedef std::map LoggerMap; + + static std::ostream* sOutput; + static LoggerMap sLoggers; + + static Logger& GetLogger(const std::string& name); + + const std::string& mName; + unsigned int mLevel; + Logger& mOutput; +}; + + +std::ostream* Log::sOutput = nullptr; +Log::LoggerMap Log::sLoggers; + + +/* static */ void +Log::Init(const std::string& filename) +{ + assert(sOutput == nullptr); + sOutput = new std::ofstream(filename); + + Log("root", level::Error) << "Opening log file: " << filename; +} + + +/* static */ void +Log::Close() +{ + assert(sOutput != nullptr); + delete sOutput; + sOutput = nullptr; +} + + +/** + * Construct a Log object. + * + * @param [in] name The name of the log stream. If this name hasn't been + * seen before, a new one will be created for you. + * @param [in] level The level. If this is higher than the level of the log + * stream, nothing will be output. + */ +Log::Log(const std::string& name, + unsigned int level) + : mName(name), + mLevel(level), + mOutput(Log::GetLogger(name)) +{ + using namespace std::chrono; + + /* Write a log message leader: "