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.
 
 
 
 
 
 

123 lines
2.6 KiB

/**
* @file logger.h
*
* Defines the base Logger class
*/
#pragma once
#include <vector>
#include <algorithm>
#include <map>
#include <sstream>
namespace l3pp {
namespace detail {
/**
* Internal function to get all configured loggers. Should not be used
* directly, see Logger::getLogger()
*/
static inline std::map<std::string, LogPtr>& GetLoggers() {
static std::map<std::string, LogPtr> 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<SinkPtr>::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<typename T>
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;
}
}