From ca6c0f72e910bf11ddb55dc4500d218515d859d2 Mon Sep 17 00:00:00 2001 From: Hirek Date: Wed, 26 Feb 2025 17:49:21 +0100 Subject: [PATCH] Logging moved to separate thread --- Logs.cpp | 118 ++++++++++++++++++++++++++++++------------------ Logs.h | 2 +- application.cpp | 7 ++- thread_list.txt | 2 + 4 files changed, 82 insertions(+), 47 deletions(-) create mode 100644 thread_list.txt diff --git a/Logs.cpp b/Logs.cpp index 61d1c5ad..c24610c6 100644 --- a/Logs.cpp +++ b/Logs.cpp @@ -14,6 +14,7 @@ http://mozilla.org/MPL/2.0/. #include "winheaders.h" #include "utilities.h" #include "uilayer.h" +#include std::ofstream output; // standardowy "log.txt", można go wyłączyć std::ofstream errors; // lista błędów "errors.txt", zawsze działa @@ -68,61 +69,88 @@ std::string filename_scenery() { } } +// log service stacks +std::deque InfoStack; +std::deque ErrorStack; + + +void LogService() +{ + while (true) + { + // loop for logging + + // write logs and log.txt + while (!InfoStack.empty()) + { + char *msg = InfoStack.front(); // get first element of stack + InfoStack.pop_front(); + if (Global.iWriteLogEnabled & 1) + { + if (!output.is_open()) + { + + std::string const filename = (Global.MultipleLogs ? "logs/log (" + filename_scenery() + ") " + filename_date() + ".txt" : "log.txt"); + output.open(filename, std::ios::trunc); + } + output << msg << "\n"; + output.flush(); + } + + log_scrollback.emplace_back(std::string(msg)); + if (log_scrollback.size() > 200) + log_scrollback.pop_front(); + + if (Global.iWriteLogEnabled & 2) + { +#ifdef _WIN32 + // hunter-271211: pisanie do konsoli tylko, gdy nie jest ukrywana + SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_GREEN | FOREGROUND_INTENSITY); + DWORD wr = 0; + WriteConsole(GetStdHandle(STD_OUTPUT_HANDLE), msg, (DWORD)strlen(msg), &wr, NULL); + WriteConsole(GetStdHandle(STD_OUTPUT_HANDLE), endstring, (DWORD)strlen(endstring), &wr, NULL); +#else + printf("%s\n", msg); +#endif + } + } + + // write to errors.txt + while (!ErrorStack.empty()) + { + char *msg = ErrorStack.front(); + ErrorStack.pop_front(); + + if (!(Global.iWriteLogEnabled & 1)) + return; + + if (!errors.is_open()) + { + + std::string const filename = (Global.MultipleLogs ? "logs/errors (" + filename_scenery() + ") " + filename_date() + ".txt" : "errors.txt"); + errors.open(filename, std::ios::trunc); + errors << "EU07.EXE " + Global.asVersion << "\n"; + } + + errors << msg << "\n"; + errors.flush(); + } + std::this_thread::sleep_for(std::chrono::milliseconds(5)); // dont burn cpu so much + } +} + void WriteLog( const char *str, logtype const Type ) { if( str == nullptr ) { return; } if( true == TestFlag( Global.DisabledLogTypes, static_cast( Type ) ) ) { return; } - - if (Global.iWriteLogEnabled & 1) { - if( !output.is_open() ) { - - std::string const filename = - ( Global.MultipleLogs ? - "logs/log (" + filename_scenery() + ") " + filename_date() + ".txt" : - "log.txt" ); - output.open( filename, std::ios::trunc ); - } - output << str << "\n"; - output.flush(); - } - - log_scrollback.emplace_back(std::string(str)); - if (log_scrollback.size() > 200) - log_scrollback.pop_front(); - - if( Global.iWriteLogEnabled & 2 ) { -#ifdef _WIN32 - // hunter-271211: pisanie do konsoli tylko, gdy nie jest ukrywana - SetConsoleTextAttribute( GetStdHandle( STD_OUTPUT_HANDLE ), FOREGROUND_GREEN | FOREGROUND_INTENSITY ); - DWORD wr = 0; - WriteConsole( GetStdHandle( STD_OUTPUT_HANDLE ), str, (DWORD)strlen( str ), &wr, NULL ); - WriteConsole( GetStdHandle( STD_OUTPUT_HANDLE ), endstring, (DWORD)strlen( endstring ), &wr, NULL ); -#else - printf("%s\n", str); -#endif - } + InfoStack.emplace_back(strdup(str)); } void ErrorLog( const char *str, logtype const Type ) { if( str == nullptr ) { return; } if( true == TestFlag( Global.DisabledLogTypes, static_cast( Type ) ) ) { return; } - - if (!(Global.iWriteLogEnabled & 1)) - return; - - if (!errors.is_open()) { - - std::string const filename = - ( Global.MultipleLogs ? - "logs/errors (" + filename_scenery() + ") " + filename_date() + ".txt" : - "errors.txt" ); - errors.open( filename, std::ios::trunc ); - errors << "EU07.EXE " + Global.asVersion << "\n"; - } - - errors << str << "\n"; - errors.flush(); + ErrorStack.emplace_back(strdup(str)); }; void Error(const std::string &asMessage, bool box) diff --git a/Logs.h b/Logs.h index ebdb5719..f7bf5795 100644 --- a/Logs.h +++ b/Logs.h @@ -23,7 +23,7 @@ enum class logtype : unsigned int { traction = ( 1 << 9 ), powergrid = ( 1 << 10 ), }; - +void LogService(); void WriteLog( const char *str, logtype const Type = logtype::generic ); void Error( const std::string &asMessage, bool box = false ); void Error( const char* &asMessage, bool box = false ); diff --git a/application.cpp b/application.cpp index 84a0bad8..6dfb5811 100644 --- a/application.cpp +++ b/application.cpp @@ -259,6 +259,10 @@ eu07_application::init( int Argc, char *Argv[] ) { return result; } + // start logging service + std::thread sLoggingService(LogService); + Global.threads.emplace("LogService", std::move(sLoggingService)); + WriteLog( "Starting MaSzyna rail vehicle simulator (release: " + Global.asVersion + ")" ); WriteLog( "For online documentation and additional files refer to: http://eu07.pl" ); WriteLog( "Authors: Marcin_EU, McZapkie, ABu, Winger, Tolaris, nbmx, OLO_EU, Bart, Quark-t, " @@ -512,7 +516,8 @@ eu07_application::run() { std::this_thread::sleep_for( Global.minframetime - frametime ); } } - + Global.threads["LogService"].~thread(); // kill log service + Global.threads["DiscordRPC"].~thread(); // kill DiscordRPC service return 0; } diff --git a/thread_list.txt b/thread_list.txt new file mode 100644 index 00000000..71388293 --- /dev/null +++ b/thread_list.txt @@ -0,0 +1,2 @@ +- DiscordRPC - Thread for refreshing discord rich presence +- LogService - Service that logs data to files and console \ No newline at end of file