You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
179 lines
4.8 KiB
179 lines
4.8 KiB
/**
|
|
* @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;
|
|
|
|
}
|