Browse Source

- Integrated the logging API into the server project - Simplified CBasicLogConfigurator usage(exception handling, logging, log file appending)

beegee1 12 years ago
parent
commit
6827fcdb53

+ 2 - 10
client/CMT.cpp

@@ -260,7 +260,7 @@ int main(int argc, char** argv)
 	atexit(dispose);
 
     CBasicLogConfigurator logConfig(VCMIDirs::get().localPath() + "/VCMI_Client_log2.txt", console);
-    logConfig.configureDefault(false);
+    logConfig.configureDefault();
     logGlobal->infoStream() <<"Creating console and logfile: "<<pomtime.getDiff();
 
     // Init filesystem and settings
@@ -268,15 +268,7 @@ int main(int argc, char** argv)
     settings.init();
 
     // Initialize logging based on settings
-    try
-    {
-        logConfig.configure();
-        logGlobal->infoStream() << "Initialized logging system successfully.";
-    }
-    catch(const std::exception & e)
-    {
-        std::cout << "Could not initialize the logging system due to configuration error/s. " << e.what() << std::endl;
-    }
+    logConfig.configure();
 
 	// Some basic data validation to produce better error messages in cases of incorrect install
 	auto testFile = [](std::string filename, std::string message) -> bool

+ 58 - 47
lib/logging/CBasicLogConfigurator.cpp

@@ -3,75 +3,86 @@
 
 #include "../CConfigHandler.h"
 
-CBasicLogConfigurator::CBasicLogConfigurator(const std::string & filePath, CConsoleHandler * console) : filePath(filePath), console(console)
+CBasicLogConfigurator::CBasicLogConfigurator(const std::string & filePath, CConsoleHandler * console) : filePath(filePath), console(console), appendToLogFile(false)
 {
 
 }
 
-void CBasicLogConfigurator::configureDefault(bool appendToLogFile /*= true*/)
+void CBasicLogConfigurator::configureDefault()
 {
     CGLogger::getGlobalLogger()->addTarget(make_unique<CLogConsoleTarget>(console));
     CGLogger::getGlobalLogger()->addTarget(make_unique<CLogFileTarget>(filePath, appendToLogFile));
+    appendToLogFile = true;
 }
 
-void CBasicLogConfigurator::configure(bool appendToLogFile /*= true*/)
+void CBasicLogConfigurator::configure()
 {
-    const JsonNode & loggingNode = settings["logging"];
-    if(loggingNode.isNull()) throw std::runtime_error("Settings haven't been loaded.");
-
-    // Configure loggers
-    const JsonNode & loggers = loggingNode["loggers"];
-    if(!loggers.isNull())
+    try
     {
-        BOOST_FOREACH(auto & loggerNode, loggers.Vector())
+        const JsonNode & loggingNode = settings["logging"];
+        if(loggingNode.isNull()) throw std::runtime_error("Settings haven't been loaded.");
+
+        // Configure loggers
+        const JsonNode & loggers = loggingNode["loggers"];
+        if(!loggers.isNull())
         {
-            // Get logger
-            std::string name = loggerNode["domain"].String();
-            CGLogger * logger = CGLogger::getLogger(CLoggerDomain(name));
+            BOOST_FOREACH(auto & loggerNode, loggers.Vector())
+            {
+                // Get logger
+                std::string name = loggerNode["domain"].String();
+                CGLogger * logger = CGLogger::getLogger(CLoggerDomain(name));
 
-            // Set log level
-            logger->setLevel(getLogLevel(loggerNode["level"].String()));
+                // Set log level
+                logger->setLevel(getLogLevel(loggerNode["level"].String()));
+            }
         }
-    }
-    CGLogger::getGlobalLogger()->clearTargets();
-
-    // Add console target
-    auto consoleTarget = make_unique<CLogConsoleTarget>(console);
-    const JsonNode & consoleNode = loggingNode["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());
+        CGLogger::getGlobalLogger()->clearTargets();
 
-        CColorMapping colorMapping;
-        const JsonNode & colorMappingNode = consoleNode["colorMapping"];
-        if(!colorMappingNode.isNull())
+        // Add console target
+        auto consoleTarget = make_unique<CLogConsoleTarget>(console);
+        const JsonNode & consoleNode = loggingNode["console"];
+        if(!consoleNode.isNull())
         {
-            BOOST_FOREACH(const JsonNode & mappingNode, colorMappingNode.Vector())
+            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())
             {
-                std::string domain = mappingNode["domain"].String();
-                std::string level = mappingNode["level"].String();
-                std::string color = mappingNode["color"].String();
-                colorMapping.setColorFor(CLoggerDomain(domain), getLogLevel(level), getConsoleColor(color));
+                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(CLoggerDomain(domain), getLogLevel(level), getConsoleColor(color));
+                }
             }
+            consoleTarget->setColorMapping(colorMapping);
         }
-        consoleTarget->setColorMapping(colorMapping);
-    }
-    CGLogger::getGlobalLogger()->addTarget(std::move(consoleTarget));
+        CGLogger::getGlobalLogger()->addTarget(std::move(consoleTarget));
 
-    // Add file target
-    auto fileTarget = make_unique<CLogFileTarget>(filePath, appendToLogFile);
-    const JsonNode & fileNode = loggingNode["file"];
-    if(!fileNode.isNull())
+        // Add file target
+        auto fileTarget = make_unique<CLogFileTarget>(filePath, appendToLogFile);
+        const JsonNode & fileNode = loggingNode["file"];
+        if(!fileNode.isNull())
+        {
+            const JsonNode & fileFormatNode = fileNode["format"];
+            if(!fileFormatNode.isNull()) fileTarget->setFormatter(CLogFormatter(fileFormatNode.String()));
+        }
+        CGLogger::getGlobalLogger()->addTarget(std::move(fileTarget));
+        appendToLogFile = true;
+    }
+    catch(const std::exception & e)
     {
-        const JsonNode & fileFormatNode = fileNode["format"];
-        if(!fileFormatNode.isNull()) fileTarget->setFormatter(CLogFormatter(fileFormatNode.String()));
+        logGlobal->errorStream() << "Could not initialize the logging system due to configuration error/s. The logging system can be in a corrupted state. " << e.what();
     }
-    CGLogger::getGlobalLogger()->addTarget(std::move(fileTarget));
+
+    logGlobal->infoStream() << "Initialized logging system based on settings successfully.";
 }
 
 ELogLevel::ELogLevel CBasicLogConfigurator::getLogLevel(const std::string & level) const

+ 6 - 6
lib/logging/CBasicLogConfigurator.h

@@ -17,20 +17,19 @@ class CConsoleHandler;
 class JsonNode;
 
 /// The class CBasicLogConfigurator reads log properties from settings.json and
-/// sets up the logging system.
+/// sets up the logging system. Make sure that you use the same configurator object to
+/// initialize the whole logging system. If you don't do so, the log file will be overwritten/truncated.
 class DLL_LINKAGE CBasicLogConfigurator
 {
 public:
     CBasicLogConfigurator(const std::string & filePath, CConsoleHandler * console);
 
     /// Configures the logging system by parsing the logging settings. It adds the console target and the file target to the global logger.
-    /// If the append parameter is true, the log file will be appended to. Otherwise the log file will be truncated.
-    /// Throws std::runtime_error if the configuration has errors.
-    void configure(bool appendToLogFile = true);
+    /// Doesn't throw, but logs on success or fault.
+    void configure();
 
     /// Configures a default logging system by adding the console target and the file target to the global logger.
-    /// If the append parameter is true, the log file will be appended to. Otherwise the log file will be truncated.
-    void configureDefault(bool appendToLogFile = true);
+    void configureDefault();
 
 private:
     ELogLevel::ELogLevel getLogLevel(const std::string & level) const;
@@ -38,4 +37,5 @@ private:
 
     std::string filePath;
     CConsoleHandler * console;
+    bool appendToLogFile;
 };

+ 45 - 44
server/CGameHandler.cpp

@@ -211,7 +211,7 @@ void CGameHandler::levelUpHero(const CGHeroInstance * hero)
 	}
 
 	//give prim skill
-	tlog5 << hero->name <<" got level "<<hero->level<<std::endl;
+    logGlobal->traceStream() << hero->name <<" got level "<<hero->level;
 	int r = rand()%100, pom=0, x=0;
 
 	auto & skillChances = (hero->level>9) ? hero->type->heroClass->primarySkillLowLevel : hero->type->heroClass->primarySkillHighLevel;
@@ -222,7 +222,7 @@ void CGameHandler::levelUpHero(const CGHeroInstance * hero)
 		if(r<pom)
 			break;
 	}
-	tlog5 << "The hero gets the primary skill with the no. " << x << " with a probability of " << r << "%." <<  std::endl;
+    logGlobal->traceStream() << "The hero gets the primary skill with the no. " << x << " with a probability of " << r << "%.";
 	SetPrimSkill sps;
 	sps.id = hero->id;
 	sps.which = static_cast<PrimarySkill::PrimarySkill>(x);
@@ -904,7 +904,7 @@ void CGameHandler::handleConnection(std::set<PlayerColor> players, CConnection &
 				c >> player >> requestID >> pack; //get the package
 				packType = typeList.getTypeID(pack); //get the id of type
 
-				tlog5 << boost::format("Received client message (request %d by player %d) of type with ID=%d (%s).\n")
+                logGlobal->traceStream() << boost::format("Received client message (request %d by player %d) of type with ID=%d (%s).\n")
 					% requestID % player.getNum() % packType % typeid(*pack).name();
 			}
 
@@ -927,7 +927,7 @@ void CGameHandler::handleConnection(std::set<PlayerColor> players, CConnection &
 			else if(apply)
 			{
 				bool result = apply->applyOnGH(this,&c,pack, player);
-				tlog5 << "Message successfully applied (result=" << result << ")!\n";
+                logGlobal->traceStream() << "Message successfully applied (result=" << result << ")!";
 
 				//send confirmation that we've applied the package
 				applied.result = result;
@@ -938,7 +938,7 @@ void CGameHandler::handleConnection(std::set<PlayerColor> players, CConnection &
 			}
 			else
 			{
-				tlog1 << "Message cannot be applied, cannot find applier (unregistered type)!\n";
+                logGlobal->errorStream() << "Message cannot be applied, cannot find applier (unregistered type)!";
 			}
 
 			vstd::clear_pointer(pack);
@@ -947,12 +947,12 @@ void CGameHandler::handleConnection(std::set<PlayerColor> players, CConnection &
 	catch(boost::system::system_error &e) //for boost errors just log, not crash - probably client shut down connection
 	{
 		assert(!c.connected); //make sure that connection has been marked as broken
-		tlog1 << e.what() << std::endl;
+        logGlobal->errorStream() << e.what();
 		end2 = true;
 	}
 	HANDLE_EXCEPTION(end2 = true);
 
-	tlog1 << "Ended handling connection\n";
+    logGlobal->errorStream() << "Ended handling connection";
 }
 
 int CGameHandler::moveStack(int stack, BattleHex dest)
@@ -1103,9 +1103,9 @@ void CGameHandler::init(StartInfo *si)
 		si->seedToBeUsed = std::time(NULL);
 
 	gs = new CGameState();
-	tlog0 << "Gamestate created!" << std::endl;
+    logGlobal->infoStream() << "Gamestate created!";
 	gs->init(si);
-	tlog0 << "Gamestate initialized!" << std::endl;
+    logGlobal->infoStream() << "Gamestate initialized!";
 
 	for(auto i = gs->players.begin(); i != gs->players.end(); i++)
 		states.addPlayer(i->first);
@@ -1121,7 +1121,7 @@ void CGameHandler::setPortalDwelling(const CGTownInstance * town, bool forced=fa
 	const PlayerState *p = gs->getPlayer(town->tempOwner);
 	if(!p)
 	{
-		tlog3 << "There is no player owner of town " << town->name << " at " << town->pos << std::endl;
+        logGlobal->warnStream() << "There is no player owner of town " << town->name << " at " << town->pos;
 		return;
 	}
 
@@ -1154,7 +1154,7 @@ void CGameHandler::setPortalDwelling(const CGTownInstance * town, bool forced=fa
 
 void CGameHandler::newTurn()
 {
-	tlog5 << "Turn " << gs->day+1 << std::endl;
+    logGlobal->traceStream() << "Turn " << gs->day+1;
 	NewTurn n;
 	n.specialWeek = NewTurn::NO_ACTION;
 	n.creatureid = CreatureID::NONE;
@@ -1459,7 +1459,7 @@ void CGameHandler::newTurn()
 		}
 	}
 
-	tlog5 << "Info about turn " << n.day << "has been sent!" << std::endl;
+    logGlobal->traceStream() << "Info about turn " << n.day << "has been sent!";
 	handleTimeEvents();
 	//call objects
 	for(size_t i = 0; i<gs->map->objects.size(); i++)
@@ -1517,16 +1517,17 @@ void CGameHandler::run(bool resume)
 		std::set<PlayerColor> players;
 		(*cc) >> players; //how many players will be handled at that client
 
-		tlog0 << "Connection " << cc->connectionID << " will handle " << players.size() << " player: ";
+        std::stringstream sbuffer;
+        sbuffer << "Connection " << cc->connectionID << " will handle " << players.size() << " player: ";
 		BOOST_FOREACH(PlayerColor color, players)
 		{
-			tlog0 << color << " ";
+            sbuffer << color << " ";
 			{
 				boost::unique_lock<boost::recursive_mutex> lock(gsm);
 				connections[color] = cc;
 			}
 		}
-		tlog0 << std::endl;
+        logGlobal->infoStream() << sbuffer.str();
 
 		cc->addStdVecItems(gs);
 		cc->enableStackSendingByID();
@@ -1660,7 +1661,7 @@ bool CGameHandler::removeObject( const CGObjectInstance * obj )
 {
 	if(!obj || !getObj(obj->id))
 	{
-		tlog1 << "Something wrong, that object already has been removed or hasn't existed!\n";
+        logGlobal->errorStream() << "Something wrong, that object already has been removed or hasn't existed!";
 		return false;
 	}
 
@@ -1685,16 +1686,16 @@ bool CGameHandler::moveHero( ObjectInstanceID hid, int3 dst, ui8 instant, Player
 	if(!h  || (asker != PlayerColor::NEUTRAL && (instant  ||   h->getOwner() != gs->currentPlayer)) //not turn of that hero or player can't simply teleport hero (at least not with this function)
 	  )
 	{
-		tlog1 << "Illegal call to move hero!\n";
+        logGlobal->errorStream() << "Illegal call to move hero!";
 		return false;
 	}
 
-	tlog5 << "Player " << asker << " wants to move hero "<< hid.getNum() << " from "<< h->pos << " to " << dst << std::endl;
+    logGlobal->traceStream() << "Player " << asker << " wants to move hero "<< hid.getNum() << " from "<< h->pos << " to " << dst;
 	int3 hmpos = dst + int3(-1,0,0);
 
 	if(!gs->map->isInTheMap(hmpos))
 	{
-		tlog1 << "Destination tile is outside the map!\n";
+        logGlobal->errorStream() << "Destination tile is outside the map!";
 		return false;
 	}
 
@@ -1766,7 +1767,7 @@ bool CGameHandler::moveHero( ObjectInstanceID hid, int3 dst, ui8 instant, Player
 				//can't move to that tile but we visit object
 				objectVisited(t.visitableObjects.back(), h);
 
-				tlog5 << "Blocking visit at " << hmpos << std::endl;
+                logGlobal->traceStream() << "Blocking visit at " << hmpos;
 				return true;
 			}
 		}
@@ -1810,12 +1811,12 @@ bool CGameHandler::moveHero( ObjectInstanceID hid, int3 dst, ui8 instant, Player
 		tmh.attackedFrom = guardPos;
 		applyWithResult(TryMoveHero::SUCCESS);
 
-		tlog5 << "Moved to " <<tmh.end<<std::endl;
+        logGlobal->traceStream() << "Moved to " <<tmh.end;
 
 		if (!tryAttackingGuard(guardPos, h)) // If a creature guards the tile, block visit.
 			visitObjectOnTile(t, h);
 
-		tlog5 << "Movement end!\n";
+        logGlobal->traceStream() << "Movement end!";
 		return true;
 	}
 	else //instant move - teleportation
@@ -1845,7 +1846,7 @@ bool CGameHandler::teleportHero(ObjectInstanceID hid, ObjectInstanceID dstid, ui
 	const CGTownInstance *t = getTown(dstid);
 
 	if ( !h || !t || h->getOwner() != gs->currentPlayer )
-		tlog1<<"Invalid call to teleportHero!";
+        logGlobal->errorStream()<<"Invalid call to teleportHero!";
 
 	const CGTownInstance *from = h->visitedTown;
 	if(((h->getOwner() != t->getOwner())
@@ -2216,7 +2217,7 @@ void CGameHandler::heroExchange(ObjectInstanceID hero1, ObjectInstanceID hero2)
 void CGameHandler::prepareNewQuery(Query * queryPack, PlayerColor player, const boost::function<void(ui32)> &callback)
 {
 	boost::unique_lock<boost::recursive_mutex> lock(gsm);
-	tlog4 << "Creating a query for player " << player << " with ID=" << QID << std::endl;
+    logGlobal->debugStream() << "Creating a query for player " << player << " with ID=" << QID;
 	callbacks[QID] = callback;
 	states.addQuery(player, QID);
 	queryPack->queryID = QID;
@@ -2239,7 +2240,7 @@ void CGameHandler::ask( Query * sel, PlayerColor player, const CFunctionList<voi
 
 void CGameHandler::sendToAllClients( CPackForClient * info )
 {
-	tlog5 << "Sending to all clients a package of type " << typeid(*info).name() << std::endl;
+    logGlobal->traceStream() << "Sending to all clients a package of type " << typeid(*info).name();
 	for(std::set<CConnection*>::iterator i=conns.begin(); i!=conns.end();i++)
 	{
 		boost::unique_lock<boost::mutex> lock(*(*i)->wmx);
@@ -2297,13 +2298,13 @@ void CGameHandler::sendAndApply( NewStructures * info )
 
 void CGameHandler::save(const std::string & filename )
 {
-	tlog1 << "Saving to " << filename << "\n";
+    logGlobal->errorStream() << "Saving to " << filename;
 	CFileInfo info(filename);
 	CResourceHandler::get()->createResource(info.getStem() + ".vlgm1");
 	CResourceHandler::get()->createResource(info.getStem() + ".vsgm1");
 
 	{
-		tlog0 << "Ordering clients to serialize...\n";
+        logGlobal->infoStream() << "Ordering clients to serialize...";
 		SaveGame sg(info.getStem() + ".vcgm1");
 		sendToAllClients(&sg);
 	}
@@ -2311,7 +2312,7 @@ void CGameHandler::save(const std::string & filename )
 	try
 	{
 // 		{
-// 			tlog0 << "Serializing game info...\n";
+// 			logGlobal->infoStream() << "Serializing game info...";
 // 			CSaveFile save(CResourceHandler::get()->getResourceName(ResourceID(info.getStem(), EResType::LIB_SAVEGAME)));
 // // 			char hlp[8] = "VCMISVG";
 // // 			save << hlp;
@@ -2321,20 +2322,20 @@ void CGameHandler::save(const std::string & filename )
 		{
 			CSaveFile save(CResourceHandler::get()->getResourceName(ResourceID(info.getStem(), EResType::SERVER_SAVEGAME)));
 			saveCommonState(save);
-			tlog0 << "Saving server state\n";
+            logGlobal->infoStream() << "Saving server state";
 			save << *this;
 		}
-		tlog0 << "Game has been successfully saved!\n";
+        logGlobal->infoStream() << "Game has been successfully saved!";
 	}
 	catch(std::exception &e)
 	{
-		tlog1 << "Failed to save game: " << e.what() << std::endl;
+        logGlobal->errorStream() << "Failed to save game: " << e.what();
 	}
 }
 
 void CGameHandler::close()
 {
-	tlog0 << "We have been requested to close.\n";
+    logGlobal->infoStream() << "We have been requested to close.";
 
 	if(gs->initialOpts->mode == StartInfo::DUEL)
 	{
@@ -3294,7 +3295,7 @@ static EndAction end_action;
 
 bool CGameHandler::makeBattleAction( BattleAction &ba )
 {
-	tlog1 << "\tMaking action of type " << ba.actionType << std::endl;
+    logGlobal->errorStream() << "\tMaking action of type " << ba.actionType;
 	bool ok = true;
 
 
@@ -3421,7 +3422,7 @@ bool CGameHandler::makeBattleAction( BattleAction &ba )
 			BattleHex startingPos = stack->position;
 			int distance = moveStack(ba.stackNumber, ba.destinationTile);
 
-			tlog5 << stack->nodeName() << " will attack " << stackAtEnd->nodeName() << std::endl;
+            logGlobal->traceStream() << stack->nodeName() << " will attack " << stackAtEnd->nodeName();
 
 			if(stack->position != ba.destinationTile //we wasn't able to reach destination tile
 				&& !(stack->doubleWide()
@@ -3430,7 +3431,7 @@ bool CGameHandler::makeBattleAction( BattleAction &ba )
 				)
 			{
 				std::string problem = "We cannot move this stack to its destination " + stack->getCreature()->namePl;
-				tlog3 << problem << std::endl;
+                logGlobal->warnStream() << problem;
 				complain(problem);
 				ok = false;
 				sendAndApply(&end_action);
@@ -4437,12 +4438,12 @@ bool CGameHandler::makeCustomAction( BattleAction &ba )
 			const CGHeroInstance *secondHero = gs->curB->heroes[!ba.side];
 			if(!h)
 			{
-				tlog2 << "Wrong caster!\n";
+                logGlobal->warnStream() << "Wrong caster!";
 				return false;
 			}
 			if(ba.additionalInfo >= VLC->spellh->spells.size())
 			{
-				tlog2 << "Wrong spell id (" << ba.additionalInfo << ")!\n";
+                logGlobal->warnStream() << "Wrong spell id (" << ba.additionalInfo << ")!";
 				return false;
 			}
 
@@ -4455,8 +4456,8 @@ bool CGameHandler::makeCustomAction( BattleAction &ba )
 				ESpellCastProblem::ESpellCastProblem escp = gs->curB->battleCanCastThisSpell(h->tempOwner, s, ECastingMode::HERO_CASTING);
 				if(escp != ESpellCastProblem::OK)
 				{
-					tlog2 << "Spell cannot be cast!\n";
-					tlog2 << "Problem : " << escp << std::endl;
+                    logGlobal->warnStream() << "Spell cannot be cast!";
+                    logGlobal->warnStream() << "Problem : " << escp;
 					return false;
 				}
 
@@ -4484,7 +4485,7 @@ bool CGameHandler::makeCustomAction( BattleAction &ba )
 			}
 			else
 			{
-				tlog2 << "Spell " << s->name << " is not yet supported!\n";
+                logGlobal->warnStream() << "Spell " << s->name << " is not yet supported!";
 				return false;
 			}
 		}
@@ -4847,7 +4848,7 @@ void CGameHandler::handleTownEvents(CGTownInstance * town, NewTurn &n)
 bool CGameHandler::complain( const std::string &problem )
 {
 	sendMessageToAll("Server encountered a problem: " + problem);
-	tlog1 << problem << std::endl;
+    logGlobal->errorStream() << problem;
 	return true;
 }
 
@@ -6018,7 +6019,7 @@ void CGameHandler::runBattle()
 					}
 					else
 					{
-						tlog5 << "Activating " << next->nodeName() << std::endl;
+                        logGlobal->traceStream() << "Activating " << next->nodeName();
 						BattleSetActiveStack sas;
 						sas.stack = next->ID;
 						sendAndApply(&sas);
@@ -6173,12 +6174,12 @@ void CGameHandler::spawnWanderingMonsters(CreatureID creatureID)
 	getFreeTiles(tiles);
 	ui32 amount = tiles.size() / 200; //Chance is 0.5% for each tile
 	std::random_shuffle(tiles.begin(), tiles.end());
-	tlog5 << "Spawning wandering monsters. Found " << tiles.size() << " free tiles. Creature type: " << creatureID << std::endl;
+    logGlobal->traceStream() << "Spawning wandering monsters. Found " << tiles.size() << " free tiles. Creature type: " << creatureID;
 	const CCreature *cre = VLC->creh->creatures[creatureID];
 	for (int i = 0; i < amount; ++i)
 	{
 		tile = tiles.begin();
-		tlog5 << "\tSpawning monster at " << *tile << std::endl;
+        logGlobal->traceStream() << "\tSpawning monster at " << *tile;
 		putNewMonster(creatureID, cre->getRandomAmount(std::rand), *tile);
 		tiles.erase(tile); //not use it again
 	}

+ 32 - 25
server/CVCMIServer.cpp

@@ -28,6 +28,8 @@
 #include "../lib/mapping/CMapInfo.h"
 #include "../lib/CObjectHandler.h"
 #include "../lib/GameConstants.h"
+#include "../lib/logging/CBasicLogConfigurator.h"
+#include "../lib/CConfigHandler.h"
 
 #include "../lib/UnlockGuard.h"
 
@@ -74,7 +76,7 @@ void CPregameServer::handleConnection(CConnection *cpc)
 			CPackForSelectionScreen *cpfs = NULL;
 			*cpc >> cpfs;
 
-			tlog0 << "Got package to announce " << typeid(*cpfs).name() << " from " << *cpc << std::endl; 
+            logNetwork->infoStream() << "Got package to announce " << typeid(*cpfs).name() << " from " << *cpc;
 
 			boost::unique_lock<boost::recursive_mutex> queueLock(mx);
 			bool quitting = dynamic_cast<QuitMenuWithoutStarting*>(cpfs), 
@@ -102,7 +104,7 @@ void CPregameServer::handleConnection(CConnection *cpc)
 	catch (const std::exception& e)
 	{
 		boost::unique_lock<boost::recursive_mutex> queueLock(mx);
-		tlog0 << *cpc << " dies... \nWhat happened: " << e.what() << std::endl;
+        logNetwork->errorStream() << *cpc << " dies... \nWhat happened: " << e.what();
 	}
 
 	boost::unique_lock<boost::recursive_mutex> queueLock(mx);
@@ -118,13 +120,13 @@ void CPregameServer::handleConnection(CConnection *cpc)
 
 		if(!connections.size())
 		{
-			tlog0 << "Last connection lost, server will close itself...\n";
+            logNetwork->errorStream() << "Last connection lost, server will close itself...";
 			boost::this_thread::sleep(boost::posix_time::seconds(2)); //we should never be hasty when networking
 			state = ENDING_WITHOUT_START;
 		}
 	}
 
-	tlog0 << "Thread listening for " << *cpc << " ended\n";
+    logNetwork->infoStream() << "Thread listening for " << *cpc << " ended";
 	listeningThreads--;
 	vstd::clear_pointer(cpc->handler);
 }
@@ -152,7 +154,7 @@ void CPregameServer::run()
 
 			if(state != RUNNING)
 			{
-				tlog0 << "Stopping listening for connections...\n";
+                logNetwork->infoStream() << "Stopping listening for connections...";
 				acceptor->close();
 			}
 
@@ -166,13 +168,13 @@ void CPregameServer::run()
 		boost::this_thread::sleep(boost::posix_time::milliseconds(50));
 	}
 
-	tlog0 << "Thread handling connections ended\n";
+    logNetwork->infoStream() << "Thread handling connections ended";
 
 	if(state == ENDING_AND_STARTING_GAME)
 	{
-		tlog0 << "Waiting for listening thread to finish...\n";
+        logNetwork->infoStream() << "Waiting for listening thread to finish...";
 		while(listeningThreads) boost::this_thread::sleep(boost::posix_time::milliseconds(50));
-		tlog0 << "Preparing new game\n";
+        logNetwork->infoStream() << "Preparing new game";
 	}
 }
 
@@ -193,11 +195,11 @@ void CPregameServer::connectionAccepted(const boost::system::error_code& ec)
 {
 	if(ec)
 	{
-		tlog0 << "Something wrong during accepting: " << ec.message() << std::endl;
+        logNetwork->infoStream() << "Something wrong during accepting: " << ec.message();
 		return;
 	}
 
-	tlog0 << "We got a new connection! :)\n";
+    logNetwork->infoStream() << "We got a new connection! :)";
 	CConnection *pc = new CConnection(upcomingConnection, NAME);
 	initConnection(pc);
 	upcomingConnection = NULL;
@@ -226,7 +228,7 @@ void CPregameServer::start_async_accept()
 
 void CPregameServer::announceTxt(const std::string &txt, const std::string &playerName /*= "system"*/)
 {
-	tlog0 << playerName << " says: " << txt << std::endl;
+    logNetwork->infoStream() << playerName << " says: " << txt;
 	ChatMessage cm;
 	cm.playerName = playerName;
 	cm.message = txt;
@@ -245,7 +247,7 @@ void CPregameServer::sendPack(CConnection * pc, const CPackForSelectionScreen &
 {
 	if(!pc->sendStop)
 	{
-		tlog0 << "\tSending pack of type " << typeid(pack).name() << " to " << *pc << std::endl;
+        logNetwork->infoStream() << "\tSending pack of type " << typeid(pack).name() << " to " << *pc;
 		*pc << &pack;
 	}
 
@@ -294,7 +296,7 @@ void CPregameServer::initConnection(CConnection *c)
 {
 	*c >> c->name;
 	connections.insert(c);
-	tlog0 << "Pregame connection with player " << c->name << " established!" << std::endl;
+    logNetwork->infoStream() << "Pregame connection with player " << c->name << " established!";
 }
 
 void CPregameServer::startListeningThread(CConnection * pc)
@@ -307,7 +309,7 @@ void CPregameServer::startListeningThread(CConnection * pc)
 CVCMIServer::CVCMIServer()
 : io(new boost::asio::io_service()), acceptor(new TAcceptor(*io, tcp::endpoint(tcp::v4(), port))), firstConnection(NULL)
 {
-	tlog4 << "CVCMIServer created!" <<std::endl;
+    logNetwork->debugStream() << "CVCMIServer created!";
 }
 CVCMIServer::~CVCMIServer()
 {
@@ -396,7 +398,7 @@ void CVCMIServer::start()
 	}
 
 	boost::system::error_code error;
-	tlog0<<"Listening for connections at port " << acceptor->local_endpoint().port() << std::endl;
+    logNetwork->infoStream()<<"Listening for connections at port " << acceptor->local_endpoint().port();
 	tcp::socket * s = new tcp::socket(acceptor->get_io_service());
 	boost::thread acc(boost::bind(vaccept,acceptor,s,&error));
 	sr->setToTrueAndNotify();
@@ -405,12 +407,12 @@ void CVCMIServer::start()
 	acc.join();
 	if (error)
 	{
-		tlog2<<"Got connection but there is an error " << std::endl << error;
+        logNetwork->warnStream()<<"Got connection but there is an error " << error;
 		return;
 	}
-	tlog0<<"We've accepted someone... " << std::endl;
+    logNetwork->infoStream()<<"We've accepted someone... ";
 	firstConnection = new CConnection(s,NAME);
-	tlog0<<"Got connection!" << std::endl;
+    logNetwork->infoStream()<<"Got connection!";
 	while(!end2)
 	{
 		ui8 mode;
@@ -455,14 +457,14 @@ void CVCMIServer::loadGame()
 // 
 // 		CLoadFile lf(CResourceHandler::get()->getResourceName(ResourceID(fname, EResType::LIB_SAVEGAME)));
 // 		lf >> sig >> dum >> si;
-// 		tlog0 <<"Reading save signature"<<std::endl;
+// 		logNetwork->infoStream() <<"Reading save signature";
 // 
 // 		lf >> *VLC;
-// 		tlog0 <<"Reading handlers"<<std::endl;
+// 		logNetwork->infoStream() <<"Reading handlers";
 // 
 // 		lf >> (gh.gs);
 // 		c.addStdVecItems(gh.gs);
-// 		tlog0 <<"Reading gamestate"<<std::endl;
+// 		logNetwork->infoStream() <<"Reading gamestate";
 // 	}
 
 	{
@@ -486,7 +488,7 @@ void CVCMIServer::loadGame()
 			acceptor->accept(*s,error);
 			if(error) //retry
 			{
-				tlog3<<"Cannot establish connection - retrying..." << std::endl;
+                logNetwork->warnStream()<<"Cannot establish connection - retrying...";
 				i--;
 				continue;
 			}
@@ -507,6 +509,8 @@ int main(int argc, char** argv)
 {
 	logfile = new std::ofstream((VCMIDirs::get().localPath() + "/VCMI_Server_log.txt").c_str());
 	console = new CConsoleHandler;
+    CBasicLogConfigurator logConfig(VCMIDirs::get().localPath() + "/VCMI_Server_log2.txt", console);
+    logConfig.configureDefault();
 	//boost::thread t(boost::bind(&CConsoleHandler::run,::console));
 	if(argc > 1)
 	{
@@ -517,7 +521,10 @@ int main(int argc, char** argv)
 #endif
 	}
 	preinitDLL(console,logfile);
-	tlog0 << "Port " << port << " will be used." << std::endl;
+    settings.init();
+    logConfig.configure();
+
+    logNetwork->infoStream() << "Port " << port << " will be used.";
 	loadDLLClasses();
 	srand ( (ui32)time(NULL) );
 	try
@@ -535,13 +542,13 @@ int main(int argc, char** argv)
 		}
 		catch(boost::system::system_error &e) //for boost errors just log, not crash - probably client shut down connection
 		{
-			tlog1 << e.what() << std::endl;
+            logNetwork->errorStream() << e.what();
 			end2 = true;
 		}HANDLE_EXCEPTION
 	}
 	catch(boost::system::system_error &e)
 	{
-		tlog1 << e.what() << std::endl;
+        logNetwork->errorStream() << e.what();
 		//catch any startup errors (e.g. can't access port) errors
 		//and return non-zero status so client can detect error
 		throw;

+ 3 - 3
server/NetPacksServer.cpp

@@ -17,12 +17,12 @@
 			boost::unique_lock<boost::mutex> lock(*c->wmx);				\
 			*c << &temp_message;										\
 		}																\
-		tlog1<<"Player is not allowed to perform this action!\n";		\
+        logNetwork->errorStream()<<"Player is not allowed to perform this action!";		\
 		return false;} while(0)
 
 #define WRONG_PLAYER_MSG(expectedplayer) do {std::ostringstream oss;\
 			oss << "You were identified as player " << gh->getPlayerAt(c) << " while expecting " << expectedplayer;\
-			tlog1 << oss.str() << std::endl; \
+            logNetwork->errorStream() << oss.str(); \
 			if(c) { SystemMessage temp_message(oss.str()); boost::unique_lock<boost::mutex> lock(*c->wmx); *c << &temp_message; } } while(0)
 
 #define ERROR_IF_NOT_OWNS(id)	do{if(!PLAYER_OWNS(id)){WRONG_PLAYER_MSG(gh->getOwner(id)); ERROR_AND_RETURN; }}while(0)
@@ -295,7 +295,7 @@ bool SetSelection::applyGh( CGameHandler *gh )
 	ERROR_IF_NOT(player);
 	if(!gh->getObj(id))
 	{
-		tlog1 << "No such object...\n";
+        logNetwork->errorStream() << "No such object...";
 		ERROR_AND_RETURN;
 	}
 	gh->sendAndApply(this);