/CCGOnline/CCGOnline/IPShared/Logging/LogInterface.cpp

https://github.com/bretambrose/CCGOnlinePublic · C++ · 231 lines · 146 code · 62 blank · 23 comment · 17 complexity · b58bb61db72e3ab3599a265ff2f8f56f MD5 · raw file

  1. /**********************************************************************************************************************
  2. (c) Copyright 2011, Bret Ambrose (mailto:bretambrose@gmail.com).
  3. This program is free software: you can redistribute it and/or modify
  4. it under the terms of the GNU General Public License as published by
  5. the Free Software Foundation, either version 3 of the License, or
  6. (at your option) any later version.
  7. This program is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. GNU General Public License for more details.
  11. You should have received a copy of the GNU General Public License
  12. along with this program. If not, see <http://www.gnu.org/licenses/>.
  13. **********************************************************************************************************************/
  14. #include "stdafx.h"
  15. #include "LogInterface.h"
  16. #include <sstream>
  17. #include "LoggingProcess.h"
  18. #include "IPShared/Concurrency/ConcurrencyManager.h"
  19. #include "IPShared/Concurrency/ProcessConstants.h"
  20. #include "IPShared/Concurrency/ProcessInterface.h"
  21. #include "IPShared/Concurrency/ProcessStatics.h"
  22. #include "IPShared/Concurrency/ProcessSubject.h"
  23. #include "IPPlatform/PlatformTime.h"
  24. #include "IPPlatform/PlatformFileSystem.h"
  25. #include "IPPlatform/StringUtils.h"
  26. using namespace IP::Execution;
  27. namespace IP
  28. {
  29. namespace Logging
  30. {
  31. // Static class data member definitions
  32. std::mutex CLogInterface::LogLock;
  33. std::shared_ptr< IManagedProcess > CLogInterface::LogProcess( nullptr );
  34. ELogLevel CLogInterface::LogLevel( ELogLevel::LL_LOW );
  35. std::wstring CLogInterface::ServiceName( L"" );
  36. std::wstring CLogInterface::LogPath( L"Logs\\" );
  37. std::wstring CLogInterface::LogSubdirectory( L"Logs" );
  38. std::wstring CLogInterface::ArchivePath( L"Logs\\Archives\\" );
  39. std::wstring CLogInterface::ArchiveSubdirectory( L"Logs\\Archives" );
  40. bool CLogInterface::StaticInitialized = false;
  41. bool CLogInterface::DynamicInitialized = false;
  42. void CLogInterface::Initialize_Static( const std::wstring &service_name, ELogLevel log_level )
  43. {
  44. FATAL_ASSERT( StaticInitialized == false );
  45. ServiceName = service_name;
  46. LogLevel = log_level;
  47. // Create the logging directory if it does not exist
  48. if ( !IP::File::Directory_Exists( LogSubdirectory ) )
  49. {
  50. IP::File::Create_Directory( LogSubdirectory );
  51. }
  52. // Create the log archive directory if it does not exist
  53. if ( !IP::File::Directory_Exists( ArchiveSubdirectory ) )
  54. {
  55. IP::File::Create_Directory( ArchiveSubdirectory );
  56. }
  57. StaticInitialized = true;
  58. }
  59. void CLogInterface::Shutdown_Static( void )
  60. {
  61. if ( !StaticInitialized )
  62. {
  63. return;
  64. }
  65. Shutdown_Dynamic();
  66. StaticInitialized = false;
  67. }
  68. void CLogInterface::Initialize_Dynamic( bool delete_all_logs )
  69. {
  70. static const uint64_t SECONDS_PER_HOUR = 3600;
  71. FATAL_ASSERT( StaticInitialized == true );
  72. std::lock_guard< std::mutex > lock( LogLock );
  73. FATAL_ASSERT( DynamicInitialized == false );
  74. // Remove old logs if they exist, logs that are not removable are attached to currently running processes
  75. std::basic_ostringstream< wchar_t > file_pattern_string;
  76. file_pattern_string << LogPath << ServiceName << L"*.txt";
  77. std::vector< std::wstring > matching_file_names;
  78. IP::File::Enumerate_Matching_Files( file_pattern_string.rdbuf()->str(), matching_file_names );
  79. auto current_time = IP::Time::Get_Current_System_Time();
  80. // Try to remove all matching log files that are older than an hour
  81. for ( uint32_t i = 0; i < matching_file_names.size(); ++i )
  82. {
  83. auto file_time = IP::Time::Get_File_Last_Modified_Time( LogPath + matching_file_names[ i ] );
  84. auto time_difference = current_time - file_time;
  85. if ( delete_all_logs || std::chrono::duration_cast< std::chrono::seconds >( time_difference ).count() > SECONDS_PER_HOUR )
  86. {
  87. IP::File::Delete_File( LogPath + matching_file_names[ i ] );
  88. }
  89. }
  90. LogProcess.reset( new CLoggingProcess( LOGGING_PROCESS_PROPERTIES ) );
  91. DynamicInitialized = true;
  92. }
  93. void CLogInterface::Shutdown_Dynamic( void )
  94. {
  95. FATAL_ASSERT( StaticInitialized == true );
  96. if ( DynamicInitialized )
  97. {
  98. std::lock_guard< std::mutex > lock( LogLock );
  99. LogProcess = nullptr;
  100. DynamicInitialized = false;
  101. }
  102. }
  103. void CLogInterface::Service_Logging( const IP::Execution::CProcessExecutionContext &context )
  104. {
  105. std::lock_guard< std::mutex > lock( LogLock );
  106. if ( LogProcess.get() != nullptr )
  107. {
  108. auto old_process = CProcessStatics::Get_Current_Process();
  109. CProcessStatics::Set_Current_Process( LogProcess.get() );
  110. LogProcess->Run( context );
  111. CProcessStatics::Set_Current_Process( old_process );
  112. LogProcess->Flush_System_Messages();
  113. }
  114. }
  115. void CLogInterface::Log( std::wstring &message )
  116. {
  117. Log( std::move( message ) );
  118. }
  119. void CLogInterface::Log( const std::wstring &message )
  120. {
  121. std::wstring message_copy( message );
  122. Log( std::move( message_copy ) );
  123. }
  124. void CLogInterface::Log( std::wstring &&message )
  125. {
  126. IProcess *virtual_process = CProcessStatics::Get_Current_Process();
  127. if ( virtual_process != nullptr )
  128. {
  129. virtual_process->Log( std::move( message ) );
  130. return;
  131. }
  132. CConcurrencyManager *manager = CProcessStatics::Get_Concurrency_Manager();
  133. if ( manager != nullptr )
  134. {
  135. manager->Log( std::move( message ) );
  136. }
  137. }
  138. void CLogInterface::Log( const wchar_t *message )
  139. {
  140. std::wstring wmessage( message );
  141. Log( std::move( wmessage ) );
  142. }
  143. void CLogInterface::Log( const std::basic_ostringstream< wchar_t > &message_stream )
  144. {
  145. Log( std::move( message_stream.rdbuf()->str() ) );
  146. }
  147. void CLogInterface::Log( const std::string &message )
  148. {
  149. std::wstring w_message;
  150. IP::String::String_To_WideString( message, w_message );
  151. Log( std::move( w_message ) );
  152. }
  153. void CLogInterface::Log( const char *message )
  154. {
  155. std::wstring w_message;
  156. IP::String::String_To_WideString( message, w_message );
  157. Log( std::move( w_message ) );
  158. }
  159. void CLogInterface::Log( const std::basic_ostringstream< char > &message_stream )
  160. {
  161. Log( message_stream.rdbuf()->str() );
  162. }
  163. } // namespace Logging
  164. } // namespace IP