/** * @file logger.h * * Defines the base Logger class */ #pragma once #include #include #include #include namespace l3pp { namespace detail { /** * Internal function to get all configured loggers. Should not be used * directly, see Logger::getLogger() */ static inline std::map& GetLoggers() { static std::map loggers; return loggers; } } inline LogStream::~LogStream() { if (level != LogLevel::OFF) { logger.log(level, stream.str(), context); } } inline void Logger::logEntry(EntryContext const& context, std::string const& msg) { for(auto& sink: sinks) { sink->log(context, msg); } if (additive && parent) { parent->logEntry(context, msg); } } inline void Logger::removeSink(SinkPtr sink) { std::vector::iterator pos = std::find(sinks.begin(), sinks.end(), sink); if (pos != sinks.end()) { sinks.erase(pos); } } inline void Logger::log(LogLevel level, std::string const& msg, EntryContext context) { if (level < getLevel()) { return; } context.level = level; context.logger = this; logEntry(context, msg); } inline LogStream Logger::log(LogLevel level, EntryContext context) { if (level < getLevel()) { // Effectively disables the stream return LogStream(*this, LogLevel::OFF, context); } else { return LogStream(*this, level, context); } } inline void Logger::initialize() { // Setup root logger getRootLogger(); // Set wall time Formatter::initialize(); } inline void Logger::deinitialize() { detail::GetLoggers().clear(); getRootLogger()->sinks.clear(); } inline LogPtr Logger::getRootLogger() { static LogPtr rootLogger = LogPtr(new Logger()); return rootLogger; } inline LogPtr Logger::getLogger(std::string name) { if (name.size() == 0) { // Root logger return getRootLogger(); } auto& loggers = detail::GetLoggers(); auto it = loggers.find(name); if (it != loggers.end()) { return it->second; } else { auto n = name.rfind('.'); LogPtr parent; if (n == std::string::npos) { parent = getRootLogger(); } else{ parent = getLogger(name.substr(0, n)); } LogPtr newLogger = LogPtr(new Logger(name, parent)); loggers.emplace(name, newLogger); return newLogger; } } template inline LogStream const& operator<<(LogStream const& stream, T const& val) { if (stream.level != LogLevel::OFF) { stream.stream << val; } return stream; } inline LogStream const& operator<<(LogStream const& stream, std::ostream& (*F)(std::ostream&)) { if (stream.level != LogLevel::OFF) { stream.stream << F; } return stream; } }