|
|
/**
* @file logger.h * * Defines the base Logger class */
#pragma once
#include <vector>
#include <sstream>
namespace l3pp {
/**
* LogStream is a logger object that can be streamed into, writing an entry * to the logger associated upon destruction. Instances of this classer are * returned by Logger log() functions, so they can be used as such: * logger->debug() << "Message"; */ class LogStream { friend class Logger;
Logger& logger; LogLevel level; EntryContext context; mutable std::ostringstream stream;
LogStream(Logger& logger, LogLevel level, EntryContext context) : logger(logger), level(level), context(context) { }
LogStream(const LogStream&) = delete; LogStream& operator=(const LogStream&) = delete; public: LogStream(LogStream&& other) : logger(other.logger), level(other.level), context(std::move(other.context))/*,
stream(std::move(other.stream))*/ { stream.str(other.stream.str()); } ~LogStream();
template<typename T> friend LogStream const& operator<<(LogStream const& stream, T const& val); friend LogStream const& operator<<(LogStream const& stream, std::ostream& (*F)(std::ostream&)); };
/**
* Main logger class. Keeps track of all Logger instances, and can be used to * log various messages. Before the logging library is used, make sure to * call Logger::initialize(). Loggers are hierarchically nested, by means of * names separated by a period. All loggers are a (indirect) child of the root * logger, see Logger::getRootLogger() and Logger::getLogger(). * A logger is associated with a LogLevel. Any entry with a level below this * level will be filtered out. A LogLevel of INHERIT means the parent log * level will be compared against instead. * A logger can be associated with 1 or more Sinks. A log entry is printed to * each associated sink. If the Logger is set additive (see getAdditive(), * setAdditive()) parent sinks are logged to as well (by default true). * Logging can be performed either as a single string message, or by using a * stream. The latter requires the end() method to be called before the entry * is logged. For convenience, various logging macros are defined at the end * of this header. */ class Logger { friend class Formatter;
typedef std::shared_ptr<Logger> LogPtr;
LogPtr parent; std::string name; LogLevel level; std::vector<SinkPtr> sinks; bool additive;
// Logger constructors are private
Logger() : parent(nullptr), name(""), level(LogLevel::DEFAULT), additive(true) {
}
Logger(std::string const& name, LogPtr parent) : parent(parent), name(name), level(LogLevel::INHERIT), additive(true) { }
void logEntry(EntryContext const& context, std::string const& msg);
public: void addSink(SinkPtr sink) { sinks.push_back(sink); }
void removeSink(SinkPtr sink);
void setLevel(LogLevel level) { if (level == LogLevel::INHERIT && !parent) { return; } this->level = level; }
LogLevel getLevel() const { if (level == LogLevel::INHERIT) { return parent->getLevel(); } return level; }
std::string const& getName() const { return name; }
bool getAdditive() const { return additive; }
void setAdditive(bool additive) { this->additive = additive; }
void log(LogLevel level, std::string const& msg, EntryContext context = EntryContext());
void trace(std::string const& msg, EntryContext context = EntryContext()) { log(LogLevel::TRACE, msg, context); } void debug(std::string const& msg, EntryContext context = EntryContext()) { log(LogLevel::DEBUG, msg, context); } void info(std::string const& msg, EntryContext context = EntryContext()) { log(LogLevel::INFO, msg, context); } void warn(std::string const& msg, EntryContext context = EntryContext()) { log(LogLevel::WARN, msg, context); } void error(std::string const& msg, EntryContext context = EntryContext()) { log(LogLevel::ERR, msg, context); } void fatal(std::string const& msg, EntryContext context = EntryContext()) { log(LogLevel::FATAL, msg, context); }
LogStream log(LogLevel level, EntryContext context = EntryContext());
LogStream trace(EntryContext context = EntryContext()) { return log(LogLevel::TRACE, context); } LogStream debug(EntryContext context = EntryContext()) { return log(LogLevel::DEBUG, context); } LogStream info(EntryContext context = EntryContext()) { return log(LogLevel::INFO, context); } LogStream warn(EntryContext context = EntryContext()) { return log(LogLevel::WARN, context); } LogStream error(EntryContext context = EntryContext()) { return log(LogLevel::ERR, context); } LogStream fatal(EntryContext context = EntryContext()) { return log(LogLevel::FATAL, context); }
static void initialize(); static void deinitialize();
static LogPtr getRootLogger();
static LogPtr getLogger(LogPtr logger) { return logger; }
static LogPtr getLogger(std::string name); }; typedef std::shared_ptr<Logger> LogPtr;
}
|