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