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