Browse Source

Show human-readable thread name in log

Ivan Savenko 1 year ago
parent
commit
cded8b1999
6 changed files with 44 additions and 13 deletions
  1. 4 0
      client/CMT.cpp
  2. 1 1
      config/schemas/settings.json
  3. 18 3
      lib/CThreadHelper.cpp
  4. 8 1
      lib/CThreadHelper.h
  5. 12 2
      lib/logging/CLogger.cpp
  6. 1 6
      lib/logging/CLogger.h

+ 4 - 0
client/CMT.cpp

@@ -189,6 +189,7 @@ int main(int argc, char * argv[])
 	console->start();
 #endif
 
+	setThreadNameLoggingOnly("MainGUI");
 	const boost::filesystem::path logPath = VCMIDirs::get().userLogsPath() / "VCMI_Client_log.txt";
 	logConfig = new CBasicLogConfigurator(logPath, console);
 	logConfig->configureDefault();
@@ -397,7 +398,10 @@ void playIntro()
 
 static void mainLoop()
 {
+#ifndef VCMI_UNIX
+	// on Linux, name of main thread is also name of our process. Which we don't want to change
 	setThreadName("MainGUI");
+#endif
 
 	while(1) //main SDL events loop
 	{

+ 1 - 1
config/schemas/settings.json

@@ -463,7 +463,7 @@
 					"properties" : {
 						"format" : {
 							"type" : "string",
-							"default" : "[%c] %l %n - %m"
+							"default" : "[%c] %l [%t] %n - %m"
 						}
 					}
 				},

+ 18 - 3
lib/CThreadHelper.cpp

@@ -55,10 +55,25 @@ void CThreadHelper::processTasks()
 	}
 }
 
-// set name for this thread.
-// NOTE: on *nix string will be trimmed to 16 symbols
+static thread_local std::string threadNameForLogging;
+
+std::string getThreadName()
+{
+	if (!threadNameForLogging.empty())
+		return threadNameForLogging;
+
+	return boost::lexical_cast<std::string>(boost::this_thread::get_id());
+}
+
+void setThreadNameLoggingOnly(const std::string &name)
+{
+	threadNameForLogging = name;
+}
+
 void setThreadName(const std::string &name)
 {
+	threadNameForLogging = name;
+
 #ifdef VCMI_WINDOWS
 #ifndef __GNUC__
 	//follows http://msdn.microsoft.com/en-us/library/xcb2z8hs.aspx
@@ -90,7 +105,7 @@ void setThreadName(const std::string &name)
 //not supported
 #endif
 
-#elif defined(__linux__)
+#elif defined(VCMI_UNIX)
 	prctl(PR_SET_NAME, name.c_str(), 0, 0, 0);
 #elif defined(VCMI_APPLE)
 	pthread_setname_np(name.c_str());

+ 8 - 1
lib/CThreadHelper.h

@@ -85,7 +85,14 @@ private:
 	}
 };
 
-
+/// Sets thread name that will be used for both logs and debugger (if supported)
+/// WARNING: on Unix-like systems this method should not be used for main thread since it will also change name of the process
 void DLL_LINKAGE setThreadName(const std::string &name);
 
+/// Sets thread name for use in logging only
+void DLL_LINKAGE setThreadNameLoggingOnly(const std::string &name);
+
+/// Returns human-readable thread name that was set before, or string form of system-provided thread ID if no human-readable name was set
+std::string DLL_LINKAGE getThreadName();
+
 VCMI_LIB_NAMESPACE_END

+ 12 - 2
lib/logging/CLogger.cpp

@@ -9,6 +9,7 @@
  */
 #include "StdInc.h"
 #include "CLogger.h"
+#include "../CThreadHelper.h"
 
 #ifdef VCMI_ANDROID
 #include <android/log.h>
@@ -427,8 +428,7 @@ void CLogConsoleTarget::setColorMapping(const CColorMapping & colorMapping) { th
 CLogFileTarget::CLogFileTarget(const boost::filesystem::path & filePath, bool append):
 	file(filePath.c_str(), append ? std::ios_base::app : std::ios_base::out)
 {
-//	formatter.setPattern("%d %l %n [%t] - %m");
-	formatter.setPattern("%l %n [%t] - %m");
+	formatter.setPattern("[%c] %l %n [%t] - %m");
 }
 
 void CLogFileTarget::write(const LogRecord & record)
@@ -446,4 +446,14 @@ CLogFileTarget::~CLogFileTarget()
 	file.close();
 }
 
+LogRecord::LogRecord(const CLoggerDomain & domain, ELogLevel::ELogLevel level, const std::string & message)
+	: domain(domain),
+	level(level),
+	message(message),
+	timeStamp(boost::posix_time::microsec_clock::local_time()),
+	threadId(getThreadName())
+{
+
+}
+
 VCMI_LIB_NAMESPACE_END

+ 1 - 6
lib/logging/CLogger.h

@@ -107,12 +107,7 @@ private:
 /// The struct LogRecord holds the log message and additional logging information.
 struct DLL_LINKAGE LogRecord
 {
-	LogRecord(const CLoggerDomain & domain, ELogLevel::ELogLevel level, const std::string & message)
-		: domain(domain),
-		level(level),
-		message(message),
-		timeStamp(boost::posix_time::microsec_clock::local_time()),
-		threadId(boost::lexical_cast<std::string>(boost::this_thread::get_id())) { }
+	LogRecord(const CLoggerDomain & domain, ELogLevel::ELogLevel level, const std::string & message);
 
 	CLoggerDomain domain;
 	ELogLevel::ELogLevel level;