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;
							 | 
						|
								
							 | 
						|
								}
							 |