mirror of
				https://github.com/vcmi/vcmi.git
				synced 2025-10-31 00:07:39 +02:00 
			
		
		
		
	- Implemented the new logging API(not used currently) - Added lock typedefs to Global.h - Some layout updates to Global.h
This commit is contained in:
		
							
								
								
									
										198
									
								
								Global.h
									
									
									
									
									
								
							
							
						
						
									
										198
									
								
								Global.h
									
									
									
									
									
								
							| @@ -1,14 +1,3 @@ | ||||
| #pragma once | ||||
|  | ||||
| // Standard include file | ||||
| // Contents: | ||||
| // Includes C/C++ libraries, STL libraries, IOStream and String libraries | ||||
| // Includes the most important boost headers | ||||
| // Defines the import + export, override and exception handling macros | ||||
| // Defines the vstd library | ||||
| // Includes the logger | ||||
|  | ||||
| // This file shouldn't be changed, except if there is a important header file missing which is shared among several projects. | ||||
|  | ||||
| /* | ||||
|  * Global.h, part of VCMI engine | ||||
| @@ -20,11 +9,59 @@ | ||||
|  * | ||||
|  */ | ||||
|  | ||||
| #pragma once | ||||
|  | ||||
| /* ---------------------------------------------------------------------------- */ | ||||
| /* Compiler detection */ | ||||
| /* ---------------------------------------------------------------------------- */ | ||||
| // Fixed width bool data type is important for serialization | ||||
| static_assert(sizeof(bool) == 1, "Bool needs to be 1 byte in size."); | ||||
|  | ||||
| #if defined _M_X64 && defined _WIN32 //Win64 -> cannot load 32-bit DLLs for video handling | ||||
|     #define DISABLE_VIDEO | ||||
| #endif | ||||
|  | ||||
| #ifdef __GNUC__ | ||||
| #define GCC_VERSION (__GNUC__ * 100 + __GNUC_MINOR__ * 10 + __GNUC_PATCHLEVEL__) | ||||
| #endif | ||||
|  | ||||
| #if defined(__GNUC__) && (GCC_VERSION == 470 || GCC_VERSION == 471) | ||||
| #error This GCC version has buggy std::array::at version and should not be used. Please update to 4.7.2 or use 4.6.x. | ||||
| #endif | ||||
|  | ||||
| /* ---------------------------------------------------------------------------- */ | ||||
| /* Guarantee compiler features */ | ||||
| /* ---------------------------------------------------------------------------- */ | ||||
| //defining available c++11 features | ||||
|  | ||||
| //initialization lists - only gcc-4.4 or later | ||||
| #if defined(__clang__) || (defined(__GNUC__) && (GCC_VERSION >= 440)) | ||||
| #define CPP11_USE_INITIALIZERS_LIST | ||||
| #endif | ||||
|  | ||||
| //nullptr -  only msvc and gcc-4.6 or later, othervice define it  as NULL | ||||
| #if !defined(_MSC_VER) && !(defined(__GNUC__) && (GCC_VERSION >= 460)) | ||||
| #define nullptr NULL | ||||
| #endif | ||||
|  | ||||
| //override keyword - only msvc and gcc-4.7 or later. | ||||
| #if !defined(_MSC_VER) && !(defined(__GNUC__) && (GCC_VERSION >= 470)) | ||||
| #define override | ||||
| #endif | ||||
|  | ||||
| //workaround to support existing code | ||||
| #define OVERRIDE override | ||||
|  | ||||
| /* ---------------------------------------------------------------------------- */ | ||||
| /* Suppress some compiler warnings */ | ||||
| /* ---------------------------------------------------------------------------- */ | ||||
| #ifdef _MSC_VER | ||||
| #pragma warning (disable : 4800 ) /* disable conversion to bool warning -- I think it's intended in all places */ | ||||
| #endif //_MSC_VER | ||||
|  | ||||
| #endif | ||||
|  | ||||
| /* ---------------------------------------------------------------------------- */ | ||||
| /* Commonly used C++, Boost headers */ | ||||
| /* ---------------------------------------------------------------------------- */ | ||||
| #define WIN32_LEAN_AND_MEAN		// Exclude rarely-used stuff from Windows headers | ||||
| #include <cstdio> | ||||
| #include <stdio.h> | ||||
| @@ -50,7 +87,6 @@ | ||||
| #include <set> | ||||
| #include <sstream> | ||||
| #include <string> | ||||
| //#include <unordered_map> | ||||
| #include <utility> | ||||
| #include <vector> | ||||
|  | ||||
| @@ -70,6 +106,7 @@ | ||||
| #include <boost/bind.hpp> | ||||
| #include <boost/cstdint.hpp> | ||||
| #include <boost/date_time/posix_time/posix_time.hpp> | ||||
| #include <boost/date_time/posix_time/posix_time_io.hpp> | ||||
| #include <boost/filesystem.hpp> | ||||
| #include <boost/foreach.hpp> | ||||
| #include <boost/format.hpp> | ||||
| @@ -90,6 +127,17 @@ | ||||
| #include <android/log.h> | ||||
| #endif | ||||
|  | ||||
| /* ---------------------------------------------------------------------------- */ | ||||
| /* Usings */ | ||||
| /* ---------------------------------------------------------------------------- */ | ||||
| using std::shared_ptr; | ||||
| using std::unique_ptr; | ||||
| using std::make_shared; | ||||
| namespace range = boost::range; | ||||
|  | ||||
| /* ---------------------------------------------------------------------------- */ | ||||
| /* Typedefs */ | ||||
| /* ---------------------------------------------------------------------------- */ | ||||
| // Integral data types | ||||
| typedef boost::uint64_t ui64; //unsigned int 64 bits (8 bytes) | ||||
| typedef boost::uint32_t ui32;  //unsigned int 32 bits (4 bytes) | ||||
| @@ -100,21 +148,14 @@ typedef boost::int32_t si32; //signed int 32 bits (4 bytes) | ||||
| typedef boost::int16_t si16; //signed int 16 bits (2 bytes) | ||||
| typedef boost::int8_t si8; //signed int 8 bits (1 byte) | ||||
|  | ||||
| // Fixed width bool data type is important for serialization | ||||
| static_assert(sizeof(bool) == 1, "Bool needs to be 1 byte in size."); | ||||
|  | ||||
| #if defined _M_X64 && defined _WIN32 //Win64 -> cannot load 32-bit DLLs for video handling | ||||
| 	#define DISABLE_VIDEO | ||||
| #endif | ||||
|  | ||||
| #ifdef __GNUC__ | ||||
| #define GCC_VERSION (__GNUC__ * 100 + __GNUC_MINOR__ * 10 + __GNUC_PATCHLEVEL__) | ||||
| #endif | ||||
|  | ||||
| #if defined(__GNUC__) && (GCC_VERSION == 470 || GCC_VERSION == 471) | ||||
| #error This GCC version has buggy std::array::at version and should not be used. Please update to 4.7.2 or use 4.6.x. | ||||
| #endif | ||||
| // Lock typedefs | ||||
| typedef boost::unique_lock<boost::shared_mutex> TWriteLock; | ||||
| typedef boost::shared_lock<boost::shared_mutex> TReadLock; | ||||
| typedef boost::lock_guard<boost::mutex> TLockGuard; | ||||
|  | ||||
| /* ---------------------------------------------------------------------------- */ | ||||
| /* Macros */ | ||||
| /* ---------------------------------------------------------------------------- */ | ||||
| // Import + Export macro declarations | ||||
| #ifdef _WIN32 | ||||
| #ifdef __GNUC__ | ||||
| @@ -150,26 +191,46 @@ static_assert(sizeof(bool) == 1, "Bool needs to be 1 byte in size."); | ||||
| #define DLL_LINKAGE DLL_IMPORT | ||||
| #endif | ||||
|  | ||||
| //defining available c++11 features | ||||
| #define THROW_FORMAT(message, formatting_elems)  throw std::runtime_error(boost::str(boost::format(message) % formatting_elems)) | ||||
|  | ||||
| //initialization lists - only gcc-4.4 or later | ||||
| #if defined(__clang__) || (defined(__GNUC__) && (GCC_VERSION >= 440)) | ||||
| #define CPP11_USE_INITIALIZERS_LIST | ||||
| #endif | ||||
| #define ASSERT_IF_CALLED_WITH_PLAYER if(!player) {tlog1 << __FUNCTION__ << "\n"; assert(0);} | ||||
|  | ||||
| //nullptr -  only msvc and gcc-4.6 or later, othervice define it  as NULL | ||||
| #if !defined(_MSC_VER) && !(defined(__GNUC__) && (GCC_VERSION >= 460)) | ||||
| #define nullptr NULL | ||||
| #endif | ||||
| //XXX pls dont - 'debug macros' are usually more trouble than it's worth | ||||
| #define HANDLE_EXCEPTION  \ | ||||
|     catch (const std::exception& e) {	\ | ||||
|     tlog1 << e.what() << std::endl;		\ | ||||
|     throw;								\ | ||||
| }									\ | ||||
|     catch (const std::exception * e)	\ | ||||
| {									\ | ||||
|     tlog1 << e->what()<< std::endl;	\ | ||||
|     throw;							\ | ||||
| }									\ | ||||
|     catch (const std::string& e) {		\ | ||||
|     tlog1 << e << std::endl;		\ | ||||
|     throw;							\ | ||||
| } | ||||
|  | ||||
| //override keyword - only msvc and gcc-4.7 or later. | ||||
| #if !defined(_MSC_VER) && !(defined(__GNUC__) && (GCC_VERSION >= 470)) | ||||
| #define override | ||||
| #endif | ||||
| #define HANDLE_EXCEPTIONC(COMMAND)  \ | ||||
|     catch (const std::exception& e) {	\ | ||||
|     COMMAND;						\ | ||||
|     tlog1 << e.what() << std::endl;	\ | ||||
|     throw;							\ | ||||
| }									\ | ||||
|     catch (const std::string &e)	\ | ||||
| {									\ | ||||
|     COMMAND;						\ | ||||
|     tlog1 << e << std::endl;	\ | ||||
|     throw;							\ | ||||
| } | ||||
|  | ||||
| //workaround to support existing code | ||||
| #define OVERRIDE override | ||||
| // can be used for counting arrays | ||||
| template<typename T, size_t N> char (&_ArrayCountObj(const T (&)[N]))[N]; | ||||
| #define ARRAY_COUNT(arr)    (sizeof(_ArrayCountObj(arr))) | ||||
|  | ||||
| /* ---------------------------------------------------------------------------- */ | ||||
| /* VCMI standard library */ | ||||
| /* ---------------------------------------------------------------------------- */ | ||||
| //a normal std::map with a const operator[] for sanity | ||||
| template<typename KeyT, typename ValT> | ||||
| class bmap : public std::map<KeyT, ValT> | ||||
| @@ -508,53 +569,10 @@ namespace vstd | ||||
| 		obj = (T)(((int)obj) + change); | ||||
| 	} | ||||
| } | ||||
|  | ||||
| using std::shared_ptr; | ||||
| using std::unique_ptr; | ||||
| using std::make_shared; | ||||
| using vstd::operator-=; | ||||
| using vstd::make_unique; | ||||
|  | ||||
| using vstd::operator-=; | ||||
|  | ||||
| namespace range = boost::range; | ||||
|  | ||||
| // can be used for counting arrays | ||||
| template<typename T, size_t N> char (&_ArrayCountObj(const T (&)[N]))[N]; | ||||
| #define ARRAY_COUNT(arr)    (sizeof(_ArrayCountObj(arr))) | ||||
|  | ||||
|  | ||||
| #define THROW_FORMAT(message, formatting_elems)  throw std::runtime_error(boost::str(boost::format(message) % formatting_elems)) | ||||
|  | ||||
| #define ASSERT_IF_CALLED_WITH_PLAYER if(!player) {tlog1 << __FUNCTION__ << "\n"; assert(0);} | ||||
|  | ||||
| //XXX pls dont - 'debug macros' are usually more trouble than it's worth | ||||
| #define HANDLE_EXCEPTION  \ | ||||
| 	catch (const std::exception& e) {	\ | ||||
| 	tlog1 << e.what() << std::endl;		\ | ||||
| 	throw;								\ | ||||
| }									\ | ||||
| 	catch (const std::exception * e)	\ | ||||
| {									\ | ||||
| 	tlog1 << e->what()<< std::endl;	\ | ||||
| 	throw;							\ | ||||
| }									\ | ||||
| 	catch (const std::string& e) {		\ | ||||
| 	tlog1 << e << std::endl;		\ | ||||
| 	throw;							\ | ||||
| } | ||||
|  | ||||
| #define HANDLE_EXCEPTIONC(COMMAND)  \ | ||||
| 	catch (const std::exception& e) {	\ | ||||
| 	COMMAND;						\ | ||||
| 	tlog1 << e.what() << std::endl;	\ | ||||
| 	throw;							\ | ||||
| }									\ | ||||
| 	catch (const std::string &e)	\ | ||||
| {									\ | ||||
| 	COMMAND;						\ | ||||
| 	tlog1 << e << std::endl;	\ | ||||
| 	throw;							\ | ||||
| } | ||||
|  | ||||
|  | ||||
| /* ---------------------------------------------------------------------------- */ | ||||
| /* VCMI headers */ | ||||
| /* ---------------------------------------------------------------------------- */ | ||||
| #include "lib/CLogger.h" | ||||
|   | ||||
| @@ -3,7 +3,7 @@ | ||||
| { | ||||
| 	"type" : "object", | ||||
| 	"$schema": "http://json-schema.org/draft-04/schema", | ||||
| 	"required" : [ "general", "video", "adventure", "battle", "server" ], | ||||
| 	"required" : [ "general", "video", "adventure", "battle", "server", "logging" ], | ||||
| 	"properties": | ||||
| 	{ | ||||
| 		"general" : { | ||||
| @@ -133,6 +133,72 @@ | ||||
| 					"default" : "StupidAI" | ||||
| 				} | ||||
| 			} | ||||
| 		}, | ||||
| 		"logging" : { | ||||
| 			"type" : "object", | ||||
| 			"default" : {}, | ||||
| 			"properties" : { | ||||
| 				"console" : { | ||||
| 					"type" : "object", | ||||
| 					"properties" : { | ||||
| 						"format" : { | ||||
| 							"type" : "string", | ||||
| 							"default" : "%l %n [%t] - %m" | ||||
| 						}, | ||||
| 						"threshold" : { | ||||
| 							"type" : "string", | ||||
| 							"default" : "info", | ||||
| 							"enum" : [ "trace", "debug", "info", "warn", "error" ] | ||||
| 						}, | ||||
| 						"coloredOutputEnabled" : { | ||||
| 							"type" : "boolean", | ||||
| 							"default" : true | ||||
| 						}, | ||||
| 						"colorMapping" : { | ||||
| 							"type" : "array", | ||||
| 							"default" : [ | ||||
| 								{ "domain" : "global", "level" : "trace", "color" : "gray"}, | ||||
| 								{ "domain" : "global", "level" : "debug", "color" : "white"}, | ||||
| 								{ "domain" : "global", "level" : "info", "color" : "green"}, | ||||
| 								{ "domain" : "global", "level" : "warn", "color" : "yellow"}, | ||||
| 								{ "domain" : "global", "level" : "error", "color" : "red"} | ||||
| 							], | ||||
| 							"items" : { | ||||
| 								"type" : "object", | ||||
| 								"required" : [ "domain", "level", "color" ], | ||||
| 								"properties" : { | ||||
| 									"domain" : { "type" : "string" }, | ||||
| 									"level" : { "type" : "string", "enum" : [ "trace", "debug", "info", "warn", "error" ] }, | ||||
| 									"color" : { "type" : "string", "enum" : [ "default", "green", "red", "magenta", "yellow", "white", "gray", "teal" ] } | ||||
| 								} | ||||
| 							} | ||||
| 						} | ||||
| 					} | ||||
| 				}, | ||||
| 				"file" : { | ||||
| 					"type" : "object", | ||||
| 					"properties" : { | ||||
| 						"format" : { | ||||
| 							"type" : "string", | ||||
| 							"default" : "%d %l %n [%t] - %m" | ||||
| 						} | ||||
| 					} | ||||
| 				}, | ||||
| 				"loggers" : { | ||||
| 					"type" : "object", | ||||
| 					"additionalProperties" : { | ||||
| 						"type":"object", | ||||
| 						"required" : [ "level" ], | ||||
| 						"properties" : { | ||||
| 							"level" : { | ||||
| 								"type" : "string", | ||||
| 								"enum" : [ "trace", "debug", "info", "warn", "error" ] | ||||
| 							} | ||||
| 						} | ||||
|  | ||||
| 					} | ||||
| 				} | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
|   | ||||
| @@ -141,43 +141,43 @@ LONG WINAPI onUnhandledException(EXCEPTION_POINTERS* exception) | ||||
| #endif | ||||
|  | ||||
|  | ||||
| void CConsoleHandler::setColor(int level) | ||||
| void CConsoleHandler::setColor(EConsoleTextColor::EConsoleTextColor color) | ||||
| { | ||||
| 	TColor color; | ||||
| 	switch(level) | ||||
|     TColor colorCode; | ||||
|     switch(color) | ||||
| 	{ | ||||
| 	case -1: | ||||
| 		color = defColor; | ||||
|     case EConsoleTextColor::DEFAULT: | ||||
|         colorCode = defColor; | ||||
| 		break; | ||||
| 	case 0: | ||||
| 		color = CONSOLE_GREEN; | ||||
|     case EConsoleTextColor::GREEN: | ||||
|         colorCode = CONSOLE_GREEN; | ||||
| 		break; | ||||
| 	case 1: | ||||
| 		color = CONSOLE_RED; | ||||
|     case EConsoleTextColor::RED: | ||||
|         colorCode = CONSOLE_RED; | ||||
| 		break; | ||||
| 	case 2: | ||||
| 		color = CONSOLE_MAGENTA; | ||||
|     case EConsoleTextColor::MAGENTA: | ||||
|         colorCode = CONSOLE_MAGENTA; | ||||
| 		break; | ||||
| 	case 3: | ||||
| 		color = CONSOLE_YELLOW; | ||||
|     case EConsoleTextColor::YELLOW: | ||||
|         colorCode = CONSOLE_YELLOW; | ||||
| 		break; | ||||
| 	case 4: | ||||
| 		color = CONSOLE_WHITE; | ||||
|     case EConsoleTextColor::WHITE: | ||||
|         colorCode = CONSOLE_WHITE; | ||||
| 		break; | ||||
| 	case 5: | ||||
| 		color = CONSOLE_GRAY; | ||||
|     case EConsoleTextColor::GRAY: | ||||
|         colorCode = CONSOLE_GRAY; | ||||
| 		break; | ||||
| 	case -2: | ||||
| 		color = CONSOLE_TEAL; | ||||
|     case EConsoleTextColor::TEAL: | ||||
|         colorCode = CONSOLE_TEAL; | ||||
| 		break; | ||||
| 	default: | ||||
| 		color = defColor; | ||||
|         colorCode = defColor; | ||||
| 		break; | ||||
| 	} | ||||
| #ifdef _WIN32 | ||||
| 	SetConsoleTextAttribute(handleOut,color); | ||||
|     SetConsoleTextAttribute(handleOut, colorCode); | ||||
| #else | ||||
| 	std::cout << color; | ||||
|     std::cout << colorCode; | ||||
| #endif | ||||
| } | ||||
|  | ||||
| @@ -210,7 +210,7 @@ int CConsoleHandler::run() | ||||
| 	} | ||||
| 	return -1; | ||||
| } | ||||
| CConsoleHandler::CConsoleHandler() | ||||
| CConsoleHandler::CConsoleHandler() : thread(nullptr) | ||||
| { | ||||
| #ifdef _WIN32 | ||||
| 	handleIn = GetStdHandle(STD_INPUT_HANDLE); | ||||
| @@ -225,7 +225,6 @@ CConsoleHandler::CConsoleHandler() | ||||
| 	defColor = "\x1b[0m"; | ||||
| #endif | ||||
|     cb = new boost::function<void(const std::string &)>; | ||||
| 	thread = NULL; | ||||
| } | ||||
| CConsoleHandler::~CConsoleHandler() | ||||
| { | ||||
|   | ||||
| @@ -10,36 +10,64 @@ | ||||
|  * | ||||
|  */ | ||||
|  | ||||
| namespace EConsoleTextColor | ||||
| { | ||||
| /** The color enum is used for colored text console output. */ | ||||
| enum EConsoleTextColor | ||||
| { | ||||
|     DEFAULT = -1, | ||||
|     GREEN, | ||||
|     RED, | ||||
|     MAGENTA, | ||||
|     YELLOW, | ||||
|     WHITE, | ||||
|     GRAY, | ||||
|     TEAL = -2 | ||||
| }; | ||||
| } | ||||
|  | ||||
| /// Class which wraps the native console. It can print text based on | ||||
| /// the chosen color | ||||
| class DLL_LINKAGE CConsoleHandler | ||||
| { | ||||
| public: | ||||
| 	boost::function<void(const std::string &)> *cb; //function to be called when message is received | ||||
| 	int curLvl; //logging level | ||||
| 	boost::thread *thread; | ||||
|  | ||||
| 	int run(); | ||||
| 	void setColor(int level); //sets color of text appropriate for given logging level | ||||
|  | ||||
|     CConsoleHandler(); //c-tor | ||||
|     ~CConsoleHandler(); //d-tor | ||||
|     void start(); //starts listening thread | ||||
| 	void end(); //kills listening thread | ||||
|  | ||||
| 	template<typename T> void print(const T &data, int lvl) | ||||
|     template<typename T> void print(const T &data, EConsoleTextColor::EConsoleTextColor color = EConsoleTextColor::DEFAULT, bool printToStdErr = false) | ||||
| 	{ | ||||
|         TLockGuard _(mx); | ||||
| #ifndef _WIN32 | ||||
| 		// with love from ffmpeg - library is trying to print some warnings from separate thread | ||||
| 		// this results in broken console on Linux. Lock stdout to print all our data at once | ||||
| 		flockfile(stdout); | ||||
| #endif | ||||
| 		setColor(lvl); | ||||
|         if(color != EConsoleTextColor::DEFAULT) setColor(color); | ||||
|         if(printToStdErr) | ||||
|         { | ||||
|             std::cerr << data << std::flush; | ||||
|         } | ||||
|         else | ||||
|         { | ||||
|             std::cout << data << std::flush; | ||||
| 		setColor(-1); | ||||
|         } | ||||
|         if(color != EConsoleTextColor::DEFAULT) setColor(EConsoleTextColor::DEFAULT); | ||||
| #ifndef _WIN32 | ||||
| 		funlockfile(stdout); | ||||
| #endif | ||||
| 	} | ||||
|  | ||||
|     boost::function<void(const std::string &)> *cb; //function to be called when message is received | ||||
|  | ||||
| private: | ||||
|     int run(); | ||||
|  | ||||
|     void end(); //kills listening thread | ||||
|  | ||||
|     void setColor(EConsoleTextColor::EConsoleTextColor color); //sets color of text appropriate for given logging level | ||||
|  | ||||
|     mutable boost::mutex mx; | ||||
|  | ||||
|     boost::thread * thread; | ||||
| }; | ||||
|   | ||||
| @@ -41,7 +41,7 @@ public: | ||||
| 		if(lvl < CLogger::CONSOLE_LOGGING_LEVEL) | ||||
| 		{ | ||||
| 			if(console) | ||||
| 				console->print(data, lvl); | ||||
|                 console->print(data, static_cast<EConsoleTextColor::EConsoleTextColor>(lvl)); | ||||
| 			else | ||||
| 				std::cout << data << std::flush; | ||||
| 		} | ||||
|   | ||||
| @@ -13,6 +13,12 @@ set(lib_SRCS | ||||
| 		Filesystem/CResourceLoader.cpp | ||||
| 		Filesystem/CFileInputStream.cpp | ||||
| 		Filesystem/CCompressedStream.cpp | ||||
| 		Logging/CBasicLogConfigurator.cpp | ||||
| 		Logging/CLogConsoleTarget.cpp | ||||
| 		Logging/CLogFileTarget.cpp | ||||
| 		Logging/CLogFormatter.cpp | ||||
| 		Logging/CLogger.cpp | ||||
| 		Logging/CLogManager.cpp | ||||
| 		Mapping/CCampaignHandler.cpp | ||||
| 		Mapping/CMap.cpp | ||||
| 		Mapping/CMapEditManager.cpp | ||||
| @@ -59,6 +65,14 @@ set(lib_SRCS | ||||
| set(lib_HEADERS | ||||
| 		Filesystem/CInputStream.h | ||||
| 		Filesystem/ISimpleResourceLoader.h | ||||
| 		Logging/CBasicLogConfigurator.h | ||||
| 		Logging/CLogConsoleTarget.h | ||||
| 		Logging/CLogFileTarget.h | ||||
| 		Logging/CLogFormatter.h | ||||
| 		Logging/CLogger.h | ||||
| 		Logging/CLogManager.h | ||||
| 		Logging/ILogTarget.h | ||||
| 		Logging/LogRecord.h | ||||
| 		Mapping/CCampaignHandler.h | ||||
| 		Mapping/CMap.h | ||||
| 		Mapping/CMapEditManager.h | ||||
|   | ||||
							
								
								
									
										113
									
								
								lib/Logging/CBasicLogConfigurator.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										113
									
								
								lib/Logging/CBasicLogConfigurator.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,113 @@ | ||||
| #include "StdInc.h" | ||||
| #include "CBasicLogConfigurator.h" | ||||
|  | ||||
| #include "../CConfigHandler.h" | ||||
| #include "CLogConsoleTarget.h" | ||||
| #include "CLogFileTarget.h" | ||||
|  | ||||
| CBasicLogConfigurator::CBasicLogConfigurator(const std::string & filePath, CConsoleHandler * console) | ||||
| { | ||||
|     const JsonNode & logging = settings["logging"]; | ||||
|  | ||||
|     // Configure loggers | ||||
|     const JsonNode & loggers = logging["loggers"]; | ||||
|     if(!loggers.isNull()) | ||||
|     { | ||||
|         BOOST_FOREACH(auto & loggerPair, loggers.Struct()) | ||||
|         { | ||||
|             // Get logger | ||||
|             std::string name = loggerPair.first; | ||||
|             CGLogger * logger = CGLogger::getLogger(name); | ||||
|  | ||||
|             // Set log level | ||||
|             const JsonNode & loggerNode = loggerPair.second; | ||||
|             const JsonNode & levelNode = loggerNode["level"]; | ||||
|             if(!levelNode.isNull()) | ||||
|             { | ||||
|                 logger->setLevel(getLogLevel(levelNode.String())); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     // Add console target | ||||
|     CLogConsoleTarget * consoleTarget = new CLogConsoleTarget(console); | ||||
|     const JsonNode & consoleNode = logging["console"]; | ||||
|     if(!consoleNode.isNull()) | ||||
|     { | ||||
|         const JsonNode & consoleFormatNode = consoleNode["format"]; | ||||
|         if(!consoleFormatNode.isNull()) consoleTarget->setFormatter(CLogFormatter(consoleFormatNode.String())); | ||||
|         const JsonNode & consoleThresholdNode = consoleNode["threshold"]; | ||||
|         if(!consoleThresholdNode.isNull()) consoleTarget->setThreshold(getLogLevel(consoleThresholdNode.String())); | ||||
|         const JsonNode & coloredConsoleEnabledNode = consoleNode["coloredOutputEnabled"]; | ||||
|         consoleTarget->setColoredOutputEnabled(coloredConsoleEnabledNode.Bool()); | ||||
|  | ||||
|         CColorMapping colorMapping; | ||||
|         const JsonNode & colorMappingNode = consoleNode["colorMapping"]; | ||||
|         if(!colorMappingNode.isNull()) | ||||
|         { | ||||
|             BOOST_FOREACH(const JsonNode & mappingNode, colorMappingNode.Vector()) | ||||
|             { | ||||
|                 std::string domain = mappingNode["domain"].String(); | ||||
|                 std::string level = mappingNode["level"].String(); | ||||
|                 std::string color = mappingNode["color"].String(); | ||||
|                 colorMapping.setColorFor(domain, getLogLevel(level), getConsoleColor(color)); | ||||
|             } | ||||
|         } | ||||
|         consoleTarget->setColorMapping(colorMapping); | ||||
|     } | ||||
|     CGLogger::getGlobalLogger()->addTarget(consoleTarget); | ||||
|  | ||||
|     // Add file target | ||||
|     CLogFileTarget * fileTarget = new CLogFileTarget(filePath); | ||||
|     const JsonNode & fileNode = logging["file"]; | ||||
|     if(!fileNode.isNull()) | ||||
|     { | ||||
|         const JsonNode & fileFormatNode = fileNode["format"]; | ||||
|         if(!fileFormatNode.isNull()) fileTarget->setFormatter(CLogFormatter(fileFormatNode.String())); | ||||
|     } | ||||
|  | ||||
|     // Add targets to the root logger by default | ||||
|     CGLogger::getGlobalLogger()->addTarget(consoleTarget); | ||||
|     CGLogger::getGlobalLogger()->addTarget(fileTarget); | ||||
| } | ||||
|  | ||||
| ELogLevel::ELogLevel CBasicLogConfigurator::getLogLevel(const std::string & level) const | ||||
| { | ||||
|     static const std::map<std::string, ELogLevel::ELogLevel> levelMap = boost::assign::map_list_of | ||||
|             ("trace", ELogLevel::TRACE) | ||||
|             ("debug", ELogLevel::DEBUG) | ||||
|             ("info", ELogLevel::INFO) | ||||
|             ("warn", ELogLevel::WARN) | ||||
|             ("error", ELogLevel::ERROR); | ||||
|     const auto & levelPair = levelMap.find(level); | ||||
|     if(levelPair != levelMap.end()) | ||||
|     { | ||||
|         return levelPair->second; | ||||
|     } | ||||
|     else | ||||
|     { | ||||
|         throw std::runtime_error("Log level " + level + " unknown."); | ||||
|     } | ||||
| } | ||||
|  | ||||
| EConsoleTextColor::EConsoleTextColor CBasicLogConfigurator::getConsoleColor(const std::string & colorName) const | ||||
| { | ||||
|     static const std::map<std::string, EConsoleTextColor::EConsoleTextColor> colorMap = boost::assign::map_list_of | ||||
|             ("default", EConsoleTextColor::DEFAULT) | ||||
|             ("green", EConsoleTextColor::GREEN) | ||||
|             ("red", EConsoleTextColor::RED) | ||||
|             ("magenta", EConsoleTextColor::MAGENTA) | ||||
|             ("yellow", EConsoleTextColor::YELLOW) | ||||
|             ("white", EConsoleTextColor::WHITE) | ||||
|             ("gray", EConsoleTextColor::GRAY) | ||||
|             ("teal", EConsoleTextColor::TEAL); | ||||
|     const auto & colorPair = colorMap.find(colorName); | ||||
|     if(colorPair != colorMap.end()) | ||||
|     { | ||||
|         return colorPair->second; | ||||
|     } | ||||
|     else | ||||
|     { | ||||
|         throw std::runtime_error("Color " + colorName + " unknown."); | ||||
|     } | ||||
| } | ||||
							
								
								
									
										55
									
								
								lib/Logging/CBasicLogConfigurator.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										55
									
								
								lib/Logging/CBasicLogConfigurator.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,55 @@ | ||||
|  | ||||
| /* | ||||
|  * CBasicLogConfigurator.h, part of VCMI engine | ||||
|  * | ||||
|  * Authors: listed in file AUTHORS in main folder | ||||
|  * | ||||
|  * License: GNU General Public License v2.0 or later | ||||
|  * Full text of license available in license.txt file, in main folder | ||||
|  * | ||||
|  */ | ||||
|  | ||||
| #pragma once | ||||
|  | ||||
| #include "CLogger.h" | ||||
|  | ||||
| class CConsoleHandler; | ||||
|  | ||||
| /** | ||||
|  * The basic log configurator reads log properties from the settings.json and | ||||
|  * sets up the logging system. The file path of the log file can be specified | ||||
|  * via the constructor. | ||||
|  */ | ||||
| class DLL_LINKAGE CBasicLogConfigurator | ||||
| { | ||||
| public: | ||||
|     /** | ||||
|      * Constructor. | ||||
|      * | ||||
|      * @param fileName The file path of the log file. | ||||
|      * | ||||
|      * @throws std::runtime_error if the configuration has errors | ||||
|      */ | ||||
|     CBasicLogConfigurator(const std::string & filePath, CConsoleHandler * console); | ||||
|  | ||||
| private: | ||||
|     /** | ||||
|      * Gets the log level enum from a string. | ||||
|      * | ||||
|      * @param level The log level string to parse. | ||||
|      * @return the corresponding log level enum value | ||||
|      * | ||||
|      * @throws std::runtime_error if the log level is unknown | ||||
|      */ | ||||
|     ELogLevel::ELogLevel getLogLevel(const std::string & level) const; | ||||
|  | ||||
|     /** | ||||
|      * Gets the console text color enum from a string. | ||||
|      * | ||||
|      * @param colorName The color string to parse. | ||||
|      * @return the corresponding console text color enum value | ||||
|      * | ||||
|      * @throws std::runtime_error if the log level is unknown | ||||
|      */ | ||||
|     EConsoleTextColor::EConsoleTextColor getConsoleColor(const std::string & colorName) const; | ||||
| }; | ||||
							
								
								
									
										126
									
								
								lib/Logging/CLogConsoleTarget.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										126
									
								
								lib/Logging/CLogConsoleTarget.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,126 @@ | ||||
| #include "StdInc.h" | ||||
| #include "CLogConsoleTarget.h" | ||||
|  | ||||
| #include "LogRecord.h" | ||||
|  | ||||
| CColorMapping::CColorMapping() | ||||
| { | ||||
|     // Set default mappings | ||||
|     auto & levelMap = map[""]; | ||||
|     levelMap[ELogLevel::TRACE] = EConsoleTextColor::GRAY; | ||||
|     levelMap[ELogLevel::DEBUG] = EConsoleTextColor::WHITE; | ||||
|     levelMap[ELogLevel::INFO] = EConsoleTextColor::GREEN; | ||||
|     levelMap[ELogLevel::WARN] = EConsoleTextColor::YELLOW; | ||||
|     levelMap[ELogLevel::ERROR] = EConsoleTextColor::RED; | ||||
| } | ||||
|  | ||||
| void CColorMapping::setColorFor(const CLoggerDomain & domain, ELogLevel::ELogLevel level, EConsoleTextColor::EConsoleTextColor color) | ||||
| { | ||||
|     if(level == ELogLevel::NOT_SET) throw std::runtime_error("Log level NOT_SET not allowed for configuring the color mapping."); | ||||
|     map[domain.getName()][level] = color; | ||||
| } | ||||
|  | ||||
| EConsoleTextColor::EConsoleTextColor CColorMapping::getColorFor(const CLoggerDomain & domain, ELogLevel::ELogLevel level) const | ||||
| { | ||||
|     std::string name = domain.getName(); | ||||
|     while(true) | ||||
|     { | ||||
|         const auto & loggerPair = map.find(name); | ||||
|         if(loggerPair != map.end()) | ||||
|         { | ||||
|             const auto & levelMap = loggerPair->second; | ||||
|             const auto & levelPair = levelMap.find(level); | ||||
|             if(levelPair != levelMap.end()) | ||||
|             { | ||||
|                 return levelPair->second; | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         CLoggerDomain currentDomain(name); | ||||
|         if(!currentDomain.isGlobalDomain()) | ||||
|         { | ||||
|             name = currentDomain.getParent().getName(); | ||||
|         } | ||||
|         else | ||||
|         { | ||||
|             break; | ||||
|         } | ||||
|     } | ||||
|     throw std::runtime_error("No color mapping found. Should not happen."); | ||||
| } | ||||
|  | ||||
| CLogConsoleTarget::CLogConsoleTarget(CConsoleHandler * console) : console(console), threshold(ELogLevel::INFO), coloredOutputEnabled(true) | ||||
| { | ||||
|  | ||||
| } | ||||
|  | ||||
| void CLogConsoleTarget::write(const LogRecord & record) | ||||
| { | ||||
|     if(threshold > record.level) return; | ||||
|  | ||||
|     std::string message = formatter.format(record); | ||||
|     bool printToStdErr = record.level >= ELogLevel::WARN; | ||||
|     if(console) | ||||
|     { | ||||
|         if(coloredOutputEnabled) | ||||
|         { | ||||
|             console->print(message, colorMapping.getColorFor(record.domain, record.level)); | ||||
|         } | ||||
|         else | ||||
|         { | ||||
|             console->print(message, EConsoleTextColor::DEFAULT, printToStdErr); | ||||
|         } | ||||
|     } | ||||
|     else | ||||
|     { | ||||
|         TLockGuard _(mx); | ||||
|         if(printToStdErr) | ||||
|         { | ||||
|             std::cerr << message << std::flush; | ||||
|         } | ||||
|         else | ||||
|         { | ||||
|             std::cout << message << std::flush; | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
| bool CLogConsoleTarget::isColoredOutputEnabled() const | ||||
| { | ||||
|     return coloredOutputEnabled; | ||||
| } | ||||
|  | ||||
| void CLogConsoleTarget::setColoredOutputEnabled(bool coloredOutputEnabled) | ||||
| { | ||||
|     this->coloredOutputEnabled = coloredOutputEnabled; | ||||
| } | ||||
|  | ||||
| ELogLevel::ELogLevel CLogConsoleTarget::getThreshold() const | ||||
| { | ||||
|     return threshold; | ||||
| } | ||||
|  | ||||
| void CLogConsoleTarget::setThreshold(ELogLevel::ELogLevel threshold) | ||||
| { | ||||
|     this->threshold = threshold; | ||||
| } | ||||
|  | ||||
| const CLogFormatter & CLogConsoleTarget::getFormatter() const | ||||
| { | ||||
|     return formatter; | ||||
| } | ||||
|  | ||||
| void CLogConsoleTarget::setFormatter(const CLogFormatter & formatter) | ||||
| { | ||||
|     this->formatter = formatter; | ||||
| } | ||||
|  | ||||
| const CColorMapping & CLogConsoleTarget::getColorMapping() const | ||||
| { | ||||
|     return colorMapping; | ||||
| } | ||||
|  | ||||
| void CLogConsoleTarget::setColorMapping(const CColorMapping & colorMapping) | ||||
| { | ||||
|     this->colorMapping = colorMapping; | ||||
| } | ||||
							
								
								
									
										147
									
								
								lib/Logging/CLogConsoleTarget.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										147
									
								
								lib/Logging/CLogConsoleTarget.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,147 @@ | ||||
|  | ||||
| /* | ||||
|  * CLogConsoleTarget.h, part of VCMI engine | ||||
|  * | ||||
|  * Authors: listed in file AUTHORS in main folder | ||||
|  * | ||||
|  * License: GNU General Public License v2.0 or later | ||||
|  * Full text of license available in license.txt file, in main folder | ||||
|  * | ||||
|  */ | ||||
|  | ||||
| #pragma once | ||||
|  | ||||
| #include "ILogTarget.h" | ||||
| #include "CLogger.h" | ||||
| #include "CLogFormatter.h" | ||||
| #include "CConsoleHandler.h" | ||||
|  | ||||
| class LogRecord; | ||||
|  | ||||
| /** | ||||
|  * The color mapping maps a logger name and a level to a specific color. | ||||
|  */ | ||||
| class DLL_LINKAGE CColorMapping | ||||
| { | ||||
| public: | ||||
|     /** | ||||
|      * Constructor. There are default color mappings for the root logger, which child loggers inherit if not overriden. | ||||
|      */ | ||||
|     CColorMapping(); | ||||
|  | ||||
|     /** | ||||
|      * Sets a console text color for a logger name and a level. | ||||
|      * | ||||
|      * @param domain The domain of the logger. | ||||
|      * @param level The logger level. | ||||
|      * @param color The console text color to use as the mapping. | ||||
|      */ | ||||
|     void setColorFor(const CLoggerDomain & domain, ELogLevel::ELogLevel level, EConsoleTextColor::EConsoleTextColor color); | ||||
|  | ||||
|     /** | ||||
|      * Gets a console text color for a logger name and a level. | ||||
|      * | ||||
|      * @param domain The domain of the logger. | ||||
|      * @param level The logger level. | ||||
|      * @return the console text color which has been applied for the mapping | ||||
|      */ | ||||
|     EConsoleTextColor::EConsoleTextColor getColorFor(const CLoggerDomain & domain, ELogLevel::ELogLevel level) const; | ||||
|  | ||||
| private: | ||||
|     /** The color mapping, 1. Key: Logger domain, 2. Key: Level, Value: Color. */ | ||||
|     std::map<std::string, std::map<ELogLevel::ELogLevel, EConsoleTextColor::EConsoleTextColor> > map; | ||||
| }; | ||||
|  | ||||
| /** | ||||
|  * The console target is a logging target which writes message to the console. | ||||
|  */ | ||||
| class DLL_LINKAGE CLogConsoleTarget : public ILogTarget | ||||
| { | ||||
| public: | ||||
|     /** | ||||
|      * Constructor. | ||||
|      * | ||||
|      * @param console Optional. The console handler which is used to output messages to the console. | ||||
|      */ | ||||
|     explicit CLogConsoleTarget(CConsoleHandler * console); | ||||
|  | ||||
|     /** | ||||
|      * Writes a log record. | ||||
|      * | ||||
|      * @param record The log record to write. | ||||
|      */ | ||||
|     void write(const LogRecord & record); | ||||
|  | ||||
|     /** | ||||
|      * True if colored output is enabled. | ||||
|      * | ||||
|      * @return true if colored output is enabled, false if not | ||||
|      */ | ||||
|     bool isColoredOutputEnabled() const; | ||||
|  | ||||
|     /** | ||||
|      * Sets the colored output flag. | ||||
|      * | ||||
|      * @param coloredOutput True if the log target should write colored messages to the console, false if not. | ||||
|      */ | ||||
|     void setColoredOutputEnabled(bool coloredOutputEnabled); | ||||
|  | ||||
|     /** | ||||
|      * Gets the threshold log level. | ||||
|      * | ||||
|      * @return the threshold log level | ||||
|      */ | ||||
|     ELogLevel::ELogLevel getThreshold() const; | ||||
|  | ||||
|     /** | ||||
|      * Sets the threshold log level. | ||||
|      * | ||||
|      * @param threshold The threshold log level. | ||||
|      */ | ||||
|     void setThreshold(ELogLevel::ELogLevel threshold); | ||||
|  | ||||
|     /** | ||||
|      * Gets the log formatter. | ||||
|      * | ||||
|      * @return The log formatter. | ||||
|      */ | ||||
|     const CLogFormatter & getFormatter() const; | ||||
|  | ||||
|     /** | ||||
|      * Sets the log formatter. | ||||
|      * | ||||
|      * @param formatter The log formatter. | ||||
|      */ | ||||
|     void setFormatter(const CLogFormatter & formatter); | ||||
|  | ||||
|     /** | ||||
|      * Gets the color mapping. | ||||
|      */ | ||||
|     const CColorMapping & getColorMapping() const; | ||||
|  | ||||
|     /** | ||||
|      * Sets the color mapping. | ||||
|      * | ||||
|      * @param colorMapping The color mapping. | ||||
|      */ | ||||
|     void setColorMapping(const CColorMapping & colorMapping); | ||||
|  | ||||
| private: | ||||
|     /** The console handler which is used to output messages to the console. */ | ||||
|     CConsoleHandler * console; | ||||
|  | ||||
|     /** The threshold log level. */ | ||||
|     ELogLevel::ELogLevel threshold; | ||||
|  | ||||
|     /** Flag whether colored console output is enabled. */ | ||||
|     bool coloredOutputEnabled; | ||||
|  | ||||
|     /** The log formatter to log messages. */ | ||||
|     CLogFormatter formatter; | ||||
|  | ||||
|     /** The color mapping which maps a logger and a log level to a color. */ | ||||
|     CColorMapping colorMapping; | ||||
|  | ||||
|     /** The shared mutex for providing synchronous thread-safe access to the log console target. */ | ||||
|     mutable boost::mutex mx; | ||||
| }; | ||||
							
								
								
									
										28
									
								
								lib/Logging/CLogFileTarget.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										28
									
								
								lib/Logging/CLogFileTarget.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,28 @@ | ||||
| #include "StdInc.h" | ||||
| #include "CLogFileTarget.h" | ||||
|  | ||||
| CLogFileTarget::CLogFileTarget(const std::string & filePath) : file(filePath) | ||||
| { | ||||
|  | ||||
| } | ||||
|  | ||||
| CLogFileTarget::~CLogFileTarget() | ||||
| { | ||||
|     file.close(); | ||||
| } | ||||
|  | ||||
| void CLogFileTarget::write(const LogRecord & record) | ||||
| { | ||||
|     TLockGuard _(mx); | ||||
|     file << formatter.format(record) << std::endl; | ||||
| } | ||||
|  | ||||
| const CLogFormatter & CLogFileTarget::getFormatter() const | ||||
| { | ||||
|     return formatter; | ||||
| } | ||||
|  | ||||
| void CLogFileTarget::setFormatter(const CLogFormatter & formatter) | ||||
| { | ||||
|     this->formatter = formatter; | ||||
| } | ||||
							
								
								
									
										66
									
								
								lib/Logging/CLogFileTarget.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										66
									
								
								lib/Logging/CLogFileTarget.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,66 @@ | ||||
|  | ||||
| /* | ||||
|  * CLogFileTarget.h, part of VCMI engine | ||||
|  * | ||||
|  * Authors: listed in file AUTHORS in main folder | ||||
|  * | ||||
|  * License: GNU General Public License v2.0 or later | ||||
|  * Full text of license available in license.txt file, in main folder | ||||
|  * | ||||
|  */ | ||||
|  | ||||
| #pragma once | ||||
|  | ||||
| #include "ILogTarget.h" | ||||
| #include "CLogFormatter.h" | ||||
|  | ||||
| /** | ||||
|  * The log file target is a logging target which writes messages to a log file. | ||||
|  */ | ||||
| class DLL_LINKAGE CLogFileTarget : public ILogTarget | ||||
| { | ||||
| public: | ||||
|     /** | ||||
|      * Constructor. | ||||
|      * | ||||
|      * @param filePath The file path of the log file. | ||||
|      */ | ||||
|     explicit CLogFileTarget(const std::string & filePath); | ||||
|  | ||||
|     /** | ||||
|      * Destructor. | ||||
|      */ | ||||
|     ~CLogFileTarget(); | ||||
|  | ||||
|     /** | ||||
|      * Writes a log record. | ||||
|      * | ||||
|      * @param record The log record to write. | ||||
|      */ | ||||
|     void write(const LogRecord & record); | ||||
|  | ||||
|     /** | ||||
|      * Gets the log formatter. | ||||
|      * | ||||
|      * @return The log formatter. | ||||
|      */ | ||||
|     const CLogFormatter & getFormatter() const; | ||||
|  | ||||
|     /** | ||||
|      * Sets the log formatter. | ||||
|      * | ||||
|      * @param formatter The log formatter. | ||||
|      */ | ||||
|     void setFormatter(const CLogFormatter & formatter); | ||||
|  | ||||
| private: | ||||
|     /** The output file stream. */ | ||||
|     std::ofstream file; | ||||
|  | ||||
|     /** The log formatter to log messages. */ | ||||
|     CLogFormatter formatter; | ||||
|  | ||||
|     /** The shared mutex for providing synchronous thread-safe access to the log file target. */ | ||||
|     mutable boost::mutex mx; | ||||
| }; | ||||
|  | ||||
							
								
								
									
										65
									
								
								lib/Logging/CLogFormatter.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										65
									
								
								lib/Logging/CLogFormatter.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,65 @@ | ||||
| #include "StdInc.h" | ||||
| #include "CLogFormatter.h" | ||||
|  | ||||
| #include "LogRecord.h" | ||||
|  | ||||
| CLogFormatter::CLogFormatter() : pattern("%m") | ||||
| { | ||||
|  | ||||
| } | ||||
|  | ||||
| CLogFormatter::CLogFormatter(const std::string & pattern) : pattern(pattern) | ||||
| { | ||||
|  | ||||
| } | ||||
|  | ||||
| std::string CLogFormatter::format(const LogRecord & record) const | ||||
| { | ||||
|     std::string message = pattern; | ||||
|  | ||||
|     // Format date | ||||
|     std::stringstream dateStream; | ||||
|     boost::posix_time::time_facet * facet = new boost::posix_time::time_facet("%d-%b-%Y %H:%M:%S"); | ||||
|     dateStream.imbue(std::locale(dateStream.getloc(), facet)); | ||||
|     dateStream << record.timeStamp; | ||||
|     boost::algorithm::replace_all(message, "%d", dateStream.str()); | ||||
|  | ||||
|     // Format log level | ||||
|     std::string level; | ||||
|     switch(record.level) | ||||
|     { | ||||
|     case ELogLevel::TRACE: | ||||
|         level = "TRACE"; | ||||
|         break; | ||||
|     case ELogLevel::DEBUG: | ||||
|         level = "DEBUG"; | ||||
|         break; | ||||
|     case ELogLevel::INFO: | ||||
|         level = "INFO"; | ||||
|         break; | ||||
|     case ELogLevel::WARN: | ||||
|         level = "WARN"; | ||||
|         break; | ||||
|     case ELogLevel::ERROR: | ||||
|         level = "ERROR"; | ||||
|         break; | ||||
|     } | ||||
|     boost::algorithm::replace_all(message, "%l", level); | ||||
|  | ||||
|     // Format name, thread id and message | ||||
|     boost::algorithm::replace_all(message, "%n", record.domain.getName()); | ||||
|     boost::algorithm::replace_all(message, "%t", boost::lexical_cast<std::string>(record.threadId)); | ||||
|     boost::algorithm::replace_all(message, "%m", record.message); | ||||
|  | ||||
|     return message; | ||||
| } | ||||
|  | ||||
| void CLogFormatter::setPattern(const std::string & pattern) | ||||
| { | ||||
|     this->pattern = pattern; | ||||
| } | ||||
|  | ||||
| const std::string & CLogFormatter::getPattern() const | ||||
| { | ||||
|     return pattern; | ||||
| } | ||||
							
								
								
									
										66
									
								
								lib/Logging/CLogFormatter.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										66
									
								
								lib/Logging/CLogFormatter.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,66 @@ | ||||
|  | ||||
| /* | ||||
|  * CLogFormatter.h, part of VCMI engine | ||||
|  * | ||||
|  * Authors: listed in file AUTHORS in main folder | ||||
|  * | ||||
|  * License: GNU General Public License v2.0 or later | ||||
|  * Full text of license available in license.txt file, in main folder | ||||
|  * | ||||
|  */ | ||||
|  | ||||
| #pragma once | ||||
|  | ||||
| class LogRecord; | ||||
|  | ||||
| /** | ||||
|  * The log formatter formats log records. | ||||
|  * | ||||
|  * There are several pattern characters which can be used to format a log record: | ||||
|  * %d = Date/Time | ||||
|  * %l = Log level | ||||
|  * %n = Logger name | ||||
|  * %t = Thread ID | ||||
|  * %m = Message | ||||
|  */ | ||||
| class DLL_LINKAGE CLogFormatter | ||||
| { | ||||
| public: | ||||
|     /** | ||||
|      * Default constructor. | ||||
|      */ | ||||
|     CLogFormatter(); | ||||
|  | ||||
|     /** | ||||
|      * Constructor. | ||||
|      * | ||||
|      * @param pattern The pattern to format the log record with. | ||||
|      */ | ||||
|     CLogFormatter(const std::string & pattern); | ||||
|  | ||||
|     /** | ||||
|      * Formats a log record. | ||||
|      * | ||||
|      * @param record The log record to format. | ||||
|      * @return the formatted log record as a string | ||||
|      */ | ||||
|     std::string format(const LogRecord & record) const; | ||||
|  | ||||
|     /** | ||||
|      * Sets the pattern. | ||||
|      * | ||||
|      * @param pattern The pattern string which describes how to format the log record. | ||||
|      */ | ||||
|     void setPattern(const std::string & pattern); | ||||
|  | ||||
|     /** | ||||
|      * Gets the pattern. | ||||
|      * | ||||
|      * @return the pattern string which describes how to format the log record | ||||
|      */ | ||||
|     const std::string & getPattern() const; | ||||
|  | ||||
| private: | ||||
|     /** The pattern string which describes how to format the log record. */ | ||||
|     std::string pattern; | ||||
| }; | ||||
							
								
								
									
										51
									
								
								lib/Logging/CLogManager.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										51
									
								
								lib/Logging/CLogManager.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,51 @@ | ||||
| #include "StdInc.h" | ||||
| #include "CLogManager.h" | ||||
|  | ||||
| #include "CLogger.h" | ||||
|  | ||||
| CLogManager * CLogManager::instance = nullptr; | ||||
|  | ||||
| boost::mutex CLogManager::smx; | ||||
|  | ||||
| CLogManager * CLogManager::get() | ||||
| { | ||||
|     TLockGuard _(smx); | ||||
|     if(!instance) | ||||
|     { | ||||
|         instance = new CLogManager(); | ||||
|     } | ||||
|     return instance; | ||||
| } | ||||
|  | ||||
| CLogManager::CLogManager() | ||||
| { | ||||
|  | ||||
| } | ||||
|  | ||||
| CLogManager::~CLogManager() | ||||
| { | ||||
|     BOOST_FOREACH(auto & i, loggers) | ||||
|     { | ||||
|         delete i.second; | ||||
|     } | ||||
| } | ||||
|  | ||||
| void CLogManager::addLogger(CGLogger * logger) | ||||
| { | ||||
|     TWriteLock _(mx); | ||||
|     loggers[logger->getDomain().getName()] = logger; | ||||
| } | ||||
|  | ||||
| CGLogger * CLogManager::getLogger(const CLoggerDomain & domain) | ||||
| { | ||||
|     TReadLock _(mx); | ||||
|     auto it = loggers.find(domain.getName()); | ||||
|     if(it != loggers.end()) | ||||
|     { | ||||
|         return it->second; | ||||
|     } | ||||
|     else | ||||
|     { | ||||
|         return nullptr; | ||||
|     } | ||||
| } | ||||
							
								
								
									
										67
									
								
								lib/Logging/CLogManager.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										67
									
								
								lib/Logging/CLogManager.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,67 @@ | ||||
|  | ||||
| /* | ||||
|  * CLogManager.h, part of VCMI engine | ||||
|  * | ||||
|  * Authors: listed in file AUTHORS in main folder | ||||
|  * | ||||
|  * License: GNU General Public License v2.0 or later | ||||
|  * Full text of license available in license.txt file, in main folder | ||||
|  * | ||||
|  */ | ||||
|  | ||||
| #pragma once | ||||
|  | ||||
| class CGLogger; | ||||
| class CLoggerDomain; | ||||
|  | ||||
| /** | ||||
|  * The log manager is a global storage of all logger objects. | ||||
|  */ | ||||
| class DLL_LINKAGE CLogManager : public boost::noncopyable | ||||
| { | ||||
| public: | ||||
|     /** | ||||
|      * Gets an instance of the log manager. | ||||
|      * | ||||
|      * @return an instance of the log manager | ||||
|      */ | ||||
|     static CLogManager * get(); | ||||
|  | ||||
|     /** | ||||
|      * Adds a logger. The log manager holds strong ownership of the logger object. | ||||
|      * | ||||
|      * @param logger The logger to add. | ||||
|      */ | ||||
|     void addLogger(CGLogger * logger); | ||||
|  | ||||
|     /** | ||||
|      * Gets a logger by domain. | ||||
|      * | ||||
|      * @param domain The domain of the logger. | ||||
|      * @return a logger by domain or nullptr if the logger was not found | ||||
|      */ | ||||
|     CGLogger * getLogger(const CLoggerDomain & domain); | ||||
|  | ||||
|     /** | ||||
|      * Destructor. | ||||
|      */ | ||||
|     ~CLogManager(); | ||||
|  | ||||
| private: | ||||
|     /** | ||||
|      * Constructor. | ||||
|      */ | ||||
|     CLogManager(); | ||||
|  | ||||
|     /** The instance of the log manager. */ | ||||
|     static CLogManager * instance; | ||||
|  | ||||
|     /** The loggers map where the key is the logger name and the value the corresponding logger. */ | ||||
|     std::map<std::string, CGLogger *> loggers; | ||||
|  | ||||
|     /** The shared mutex for providing synchronous thread-safe access to the log manager. */ | ||||
|     mutable boost::shared_mutex mx; | ||||
|  | ||||
|     /** The unique mutex for providing thread-safe singleton access. */ | ||||
|     static boost::mutex smx; | ||||
| }; | ||||
							
								
								
									
										165
									
								
								lib/Logging/CLogger.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										165
									
								
								lib/Logging/CLogger.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,165 @@ | ||||
| #include "StdInc.h" | ||||
| #include "CLogger.h" | ||||
| #include "LogRecord.h" | ||||
| #include "ILogTarget.h" | ||||
| #include "CLogManager.h" | ||||
|  | ||||
| boost::mutex CGLogger::smx; | ||||
|  | ||||
| const std::string CLoggerDomain::DOMAIN_GLOBAL = "global"; | ||||
|  | ||||
| CLoggerDomain::CLoggerDomain(const std::string & name) : name(name) | ||||
| { | ||||
|     if(name.empty()) throw std::runtime_error("Logger domain cannot be empty."); | ||||
| } | ||||
|  | ||||
| CLoggerDomain CLoggerDomain::getParent() const | ||||
| { | ||||
|     if(isGlobalDomain()) return *this; | ||||
|  | ||||
|     size_t pos = name.find_last_of("."); | ||||
|     if(pos != std::string::npos) | ||||
|     { | ||||
|         return CLoggerDomain(name.substr(0, pos)); | ||||
|     } | ||||
|     else | ||||
|     { | ||||
|         return CLoggerDomain(DOMAIN_GLOBAL); | ||||
|     } | ||||
| } | ||||
|  | ||||
| bool CLoggerDomain::isGlobalDomain() const | ||||
| { | ||||
|     return name == DOMAIN_GLOBAL; | ||||
| } | ||||
|  | ||||
| std::string CLoggerDomain::getName() const | ||||
| { | ||||
|     return name; | ||||
| } | ||||
|  | ||||
| CGLogger * CGLogger::getLogger(const CLoggerDomain & domain) | ||||
| { | ||||
|     TLockGuard _(smx); | ||||
|     CGLogger * logger = CLogManager::get()->getLogger(domain); | ||||
|     if(logger) | ||||
|     { | ||||
|         return logger; | ||||
|     } | ||||
|     else | ||||
|     { | ||||
|         logger = new CGLogger(domain); | ||||
|         if(domain.isGlobalDomain()) | ||||
|         { | ||||
|             logger->setLevel(ELogLevel::INFO); | ||||
|         } | ||||
|         CLogManager::get()->addLogger(logger); | ||||
|         return logger; | ||||
|     } | ||||
| } | ||||
|  | ||||
| CGLogger * CGLogger::getGlobalLogger() | ||||
| { | ||||
|     return getLogger(CLoggerDomain::DOMAIN_GLOBAL); | ||||
| } | ||||
|  | ||||
| CGLogger::CGLogger(const CLoggerDomain & domain) : domain(domain), level(ELogLevel::INFO) | ||||
| { | ||||
|     if(!domain.isGlobalDomain()) | ||||
|     { | ||||
|         parent = getLogger(domain.getParent()); | ||||
|     } | ||||
| } | ||||
|  | ||||
| CGLogger::~CGLogger() | ||||
| { | ||||
|     BOOST_FOREACH(ILogTarget * target, targets) | ||||
|     { | ||||
|         delete target; | ||||
|     } | ||||
| } | ||||
|  | ||||
| void CGLogger::trace(const std::string & message) const | ||||
| { | ||||
|     log(ELogLevel::TRACE, message); | ||||
| } | ||||
|  | ||||
| void CGLogger::debug(const std::string & message) const | ||||
| { | ||||
|     log(ELogLevel::DEBUG, message); | ||||
| } | ||||
|  | ||||
| void CGLogger::info(const std::string & message) const | ||||
| { | ||||
|     log(ELogLevel::INFO, message); | ||||
| } | ||||
|  | ||||
| void CGLogger::warn(const std::string & message) const | ||||
| { | ||||
|     log(ELogLevel::WARN, message); | ||||
| } | ||||
|  | ||||
| void CGLogger::error(const std::string & message) const | ||||
| { | ||||
|     log(ELogLevel::ERROR, message); | ||||
| } | ||||
|  | ||||
| void CGLogger::log(ELogLevel::ELogLevel level, const std::string & message) const | ||||
| { | ||||
|     if(getEffectiveLevel() <= level) | ||||
|     { | ||||
|         callTargets(LogRecord(domain, level, message)); | ||||
|     } | ||||
| } | ||||
|  | ||||
| ELogLevel::ELogLevel CGLogger::getLevel() const | ||||
| { | ||||
|     TReadLock _(mx); | ||||
|     return level; | ||||
| } | ||||
|  | ||||
| void CGLogger::setLevel(ELogLevel::ELogLevel level) | ||||
| { | ||||
|     TWriteLock _(mx); | ||||
|     if(domain.isGlobalDomain() && level == ELogLevel::NOT_SET) return; | ||||
|     this->level = level; | ||||
| } | ||||
|  | ||||
| const CLoggerDomain & CGLogger::getDomain() const | ||||
| { | ||||
|     return domain; | ||||
| } | ||||
|  | ||||
| void CGLogger::addTarget(ILogTarget * target) | ||||
| { | ||||
|     TWriteLock _(mx); | ||||
|     targets.push_back(target); | ||||
| } | ||||
|  | ||||
| std::list<ILogTarget *> CGLogger::getTargets() const | ||||
| { | ||||
|     TReadLock _(mx); | ||||
|     return targets; | ||||
| } | ||||
|  | ||||
| ELogLevel::ELogLevel CGLogger::getEffectiveLevel() const | ||||
| { | ||||
|     for(const CGLogger * logger = this; logger != nullptr; logger = logger->parent) | ||||
|     { | ||||
|         if(logger->getLevel() != ELogLevel::NOT_SET) return logger->getLevel(); | ||||
|     } | ||||
|  | ||||
|     // This shouldn't be reached, as the root logger must have set a log level | ||||
|     return ELogLevel::INFO; | ||||
| } | ||||
|  | ||||
| void CGLogger::callTargets(const LogRecord & record) const | ||||
| { | ||||
|     for(const CGLogger * logger = this; logger != nullptr; logger = logger->parent) | ||||
|     { | ||||
|         BOOST_FOREACH(ILogTarget * target, logger->getTargets()) | ||||
|         { | ||||
|             target->write(record); | ||||
|         } | ||||
|     } | ||||
| } | ||||
							
								
								
									
										230
									
								
								lib/Logging/CLogger.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										230
									
								
								lib/Logging/CLogger.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,230 @@ | ||||
|  | ||||
| /* | ||||
|  * CLogger.h, part of VCMI engine | ||||
|  * | ||||
|  * Authors: listed in file AUTHORS in main folder | ||||
|  * | ||||
|  * License: GNU General Public License v2.0 or later | ||||
|  * Full text of license available in license.txt file, in main folder | ||||
|  * | ||||
|  */ | ||||
|  | ||||
| #pragma once | ||||
|  | ||||
| class CGLogger; | ||||
| class LogRecord; | ||||
| class ILogTarget; | ||||
|  | ||||
| namespace ELogLevel | ||||
| { | ||||
|     /** | ||||
|      * The log level enum holds various log level definitions. | ||||
|      */ | ||||
|     enum ELogLevel | ||||
|     { | ||||
|         NOT_SET = 0, | ||||
|         TRACE, | ||||
|         DEBUG, | ||||
|         INFO, | ||||
|         WARN, | ||||
|         ERROR | ||||
|     }; | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * The logger domain provides convenient access to super domains from a sub domain. | ||||
|  */ | ||||
| class DLL_LINKAGE CLoggerDomain | ||||
| { | ||||
| public: | ||||
|     /** | ||||
|      * Constructor. | ||||
|      * | ||||
|      * @param domain The domain name. Sub-domains can be specified by separating domains by a dot, e.g. "ai.battle". The global domain is named "global". | ||||
|      */ | ||||
|     CLoggerDomain(const std::string & name); | ||||
|  | ||||
|     /** | ||||
|      * Gets the parent logger domain. | ||||
|      * | ||||
|      * @return the parent logger domain or the same domain logger if this method has been called on the global domain | ||||
|      */ | ||||
|     CLoggerDomain getParent() const; | ||||
|  | ||||
|     /** | ||||
|      * Returns true if this domain is the global domain. | ||||
|      * | ||||
|      * @return true if this is the global domain or false if not | ||||
|      */ | ||||
|     bool isGlobalDomain() const; | ||||
|  | ||||
|     /** | ||||
|      * Gets the name of the domain. | ||||
|      * | ||||
|      * @return the name of the domain | ||||
|      */ | ||||
|     std::string getName() const; | ||||
|  | ||||
|     /** Constant to the global domain name. */ | ||||
|     static const std::string DOMAIN_GLOBAL; | ||||
|  | ||||
| private: | ||||
|     /** The domain name. */ | ||||
|     std::string name; | ||||
| }; | ||||
|  | ||||
| /** | ||||
|  * The logger is used to log messages to certain targets of a specific domain/name. Temporary name is | ||||
|  * CGLogger, should be renamed to CLogger after refactoring. | ||||
|  */ | ||||
| class DLL_LINKAGE CGLogger : public boost::noncopyable | ||||
| { | ||||
| public: | ||||
|     /** | ||||
|      * Gets a logger by domain. | ||||
|      * | ||||
|      * @param domain The logger domain. | ||||
|      * @return the logger object | ||||
|      */ | ||||
|     static CGLogger * getLogger(const CLoggerDomain & domain); | ||||
|  | ||||
|     /** | ||||
|      * Gets the global logger which is the parent of all domain-specific loggers. | ||||
|      * | ||||
|      * @return the global logger object | ||||
|      */ | ||||
|     static CGLogger * getGlobalLogger(); | ||||
|  | ||||
|     /** | ||||
|      * Logs a message with the trace level. | ||||
|      * | ||||
|      * @param message The message to log. | ||||
|      */ | ||||
|     void trace(const std::string & message) const; | ||||
|  | ||||
|     /** | ||||
|      * Logs a message with the debug level. | ||||
|      * | ||||
|      * @param message The message to log. | ||||
|      */ | ||||
|     void debug(const std::string & message) const; | ||||
|  | ||||
|     /** | ||||
|      * Logs a message with the info level. | ||||
|      * | ||||
|      * @param message The message to log. | ||||
|      */ | ||||
|     void info(const std::string & message) const; | ||||
|  | ||||
|     /** | ||||
|      * Logs a message with the warn level. | ||||
|      * | ||||
|      * @param message The message to log. | ||||
|      */ | ||||
|     void warn(const std::string & message) const; | ||||
|  | ||||
|     /** | ||||
|      * Logs a message with the error level. | ||||
|      * | ||||
|      * @param message The message to log. | ||||
|      */ | ||||
|     void error(const std::string & message) const; | ||||
|  | ||||
|     /** | ||||
|      * Gets the log level applied for this logger. The default level for the root logger is INFO. | ||||
|      * | ||||
|      * @return the log level | ||||
|      */ | ||||
|     inline ELogLevel::ELogLevel getLevel() const; | ||||
|  | ||||
|     /** | ||||
|      * Sets the log level. | ||||
|      * | ||||
|      * @param level The log level. | ||||
|      */ | ||||
|     void setLevel(ELogLevel::ELogLevel level); | ||||
|  | ||||
|     /** | ||||
|      * Gets the logger domain. | ||||
|      * | ||||
|      * @return the domain of the logger | ||||
|      */ | ||||
|     const CLoggerDomain & getDomain() const; | ||||
|  | ||||
|     /** | ||||
|      * Adds a target to this logger and indirectly to all loggers which derive from this logger. | ||||
|      * The logger holds strong-ownership of the target object. | ||||
|      * | ||||
|      * @param target The log target to add. | ||||
|      */ | ||||
|     void addTarget(ILogTarget * target); | ||||
|  | ||||
|     /** | ||||
|      * Destructor. | ||||
|      */ | ||||
|     ~CGLogger(); | ||||
|  | ||||
| private: | ||||
|     /** | ||||
|      * Constructor. | ||||
|      * | ||||
|      * @param domain The domain of the logger. | ||||
|      */ | ||||
|     explicit CGLogger(const CLoggerDomain & domain); | ||||
|  | ||||
|     /** | ||||
|      * Gets the parent logger. | ||||
|      * | ||||
|      * @return the parent logger or nullptr if this is the root logger | ||||
|      */ | ||||
|     CGLogger * getParent() const; | ||||
|  | ||||
|     /** | ||||
|      * Logs a message of the given log level. | ||||
|      * | ||||
|      * @param level The log level of the message to log. | ||||
|      * @param message The message to log. | ||||
|      */ | ||||
|     inline void log(ELogLevel::ELogLevel level, const std::string & message) const; | ||||
|  | ||||
|     /** | ||||
|      * Gets the effective log level. | ||||
|      * | ||||
|      * @return the effective log level with respect to parent log levels | ||||
|      */ | ||||
|     inline ELogLevel::ELogLevel getEffectiveLevel() const; | ||||
|  | ||||
|     /** | ||||
|      * Calls all targets in the hierarchy to write the message. | ||||
|      * | ||||
|      * @param record The log record to write. | ||||
|      */ | ||||
|     inline void callTargets(const LogRecord & record) const; | ||||
|  | ||||
|     /** | ||||
|      * Gets all log targets attached to this logger. | ||||
|      * | ||||
|      * @return all log targets as a list | ||||
|      */ | ||||
|     inline std::list<ILogTarget *> getTargets() const; | ||||
|  | ||||
|     /** The domain of the logger. */ | ||||
|     CLoggerDomain domain; | ||||
|  | ||||
|     /** A reference to the parent logger. */ | ||||
|     CGLogger * parent; | ||||
|  | ||||
|     /** The log level of the logger. */ | ||||
|     ELogLevel::ELogLevel level; | ||||
|  | ||||
|     /** A list of log targets. */ | ||||
|     std::list<ILogTarget *> targets; | ||||
|  | ||||
|     /** The shared mutex for providing synchronous thread-safe access to the logger. */ | ||||
|     mutable boost::shared_mutex mx; | ||||
|  | ||||
|     /** The unique mutex for providing thread-safe get logger access. */ | ||||
|     static boost::mutex smx; | ||||
| }; | ||||
|  | ||||
| //extern CLogger * logGlobal; | ||||
							
								
								
									
										31
									
								
								lib/Logging/ILogTarget.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										31
									
								
								lib/Logging/ILogTarget.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,31 @@ | ||||
|  | ||||
| /* | ||||
|  * LogRecord.h, part of VCMI engine | ||||
|  * | ||||
|  * Authors: listed in file AUTHORS in main folder | ||||
|  * | ||||
|  * License: GNU General Public License v2.0 or later | ||||
|  * Full text of license available in license.txt file, in main folder | ||||
|  * | ||||
|  */ | ||||
|  | ||||
| #pragma once | ||||
|  | ||||
| class LogRecord; | ||||
|  | ||||
| /** | ||||
|  * The interface log target is used by all log target implementations. It holds | ||||
|  * the abstract method write which sub-classes should implement. | ||||
|  */ | ||||
| class DLL_LINKAGE ILogTarget : public boost::noncopyable | ||||
| { | ||||
| public: | ||||
|     /** | ||||
|      * Writes a log record. | ||||
|      * | ||||
|      * @param record The log record to write. | ||||
|      */ | ||||
|     virtual void write(const LogRecord & record) = 0; | ||||
|  | ||||
|     virtual ~ILogTarget() { }; | ||||
| }; | ||||
							
								
								
									
										44
									
								
								lib/Logging/LogRecord.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										44
									
								
								lib/Logging/LogRecord.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,44 @@ | ||||
|  | ||||
| /* | ||||
|  * LogRecord.h, part of VCMI engine | ||||
|  * | ||||
|  * Authors: listed in file AUTHORS in main folder | ||||
|  * | ||||
|  * License: GNU General Public License v2.0 or later | ||||
|  * Full text of license available in license.txt file, in main folder | ||||
|  * | ||||
|  */ | ||||
|  | ||||
| #pragma once | ||||
|  | ||||
| #include "CLogger.h" | ||||
|  | ||||
| /** | ||||
|  * The log records holds the log message and additional logging information. | ||||
|  */ | ||||
| struct DLL_LINKAGE LogRecord | ||||
| { | ||||
|     /** | ||||
|      * Constructor. | ||||
|      */ | ||||
|     LogRecord(const CLoggerDomain & domain, ELogLevel::ELogLevel level, const std::string & message) | ||||
|         : domain(domain), level(level), message(message), timeStamp(boost::posix_time::second_clock::local_time()), threadId(boost::this_thread::get_id()) | ||||
|     { | ||||
|  | ||||
|     } | ||||
|  | ||||
|     /** The logger domain. */ | ||||
|     CLoggerDomain domain; | ||||
|  | ||||
|     /** The log level. */ | ||||
|     ELogLevel::ELogLevel level; | ||||
|  | ||||
|     /** The message. */ | ||||
|     std::string message; | ||||
|  | ||||
|     /** The time when the message was created. */ | ||||
|     boost::posix_time::ptime timeStamp; | ||||
|  | ||||
|     /** The thread id. */ | ||||
|     boost::thread::id threadId; | ||||
| }; | ||||
		Reference in New Issue
	
	Block a user