Log.h 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216
  1. /*
  2. * Copyright (c) Contributors to the Open 3D Engine Project.
  3. * For complete copyright and license terms please see the LICENSE at the root of this distribution.
  4. *
  5. * SPDX-License-Identifier: Apache-2.0 OR MIT
  6. *
  7. */
  8. #pragma once
  9. #include <ILog.h>
  10. #include <MultiThread_Containers.h>
  11. #include <list>
  12. #include <AzCore/std/string/fixed_string.h>
  13. #include <AzCore/IO/FileIO.h>
  14. struct IConsole;
  15. struct ICVar;
  16. struct ISystem;
  17. //////////////////////////////////////////////////////////////////////
  18. #if defined(ANDROID) || defined(AZ_PLATFORM_MAC)
  19. #define MAX_TEMP_LENGTH_SIZE 4098
  20. #define AZ_RESTRICTED_SECTION_IMPLEMENTED
  21. #elif defined(AZ_RESTRICTED_PLATFORM)
  22. #include AZ_RESTRICTED_FILE(Log_h)
  23. #endif
  24. #if defined(AZ_RESTRICTED_SECTION_IMPLEMENTED)
  25. #undef AZ_RESTRICTED_SECTION_IMPLEMENTED
  26. #else
  27. #define MAX_TEMP_LENGTH_SIZE 8196
  28. #endif
  29. #define MAX_FILENAME_SIZE 256
  30. #define KEEP_LOG_FILE_OPEN
  31. //////////////////////////////////////////////////////////////////////
  32. class CLog
  33. : public ILog
  34. {
  35. public:
  36. typedef std::list<ILogCallback*> Callbacks;
  37. typedef AZStd::fixed_string<MAX_TEMP_LENGTH_SIZE> LogStringType;
  38. // constructor
  39. CLog(ISystem* pSystem);
  40. // destructor
  41. ~CLog();
  42. // interface ILog, IMiniLog -------------------------------------------------
  43. virtual void Release() { delete this; };
  44. virtual bool SetFileName(const char* fileNameOrAbsolutePath, bool backupLogs);
  45. virtual const char* GetFileName();
  46. virtual const char* GetBackupFileName();
  47. #if !defined(EXCLUDE_NORMAL_LOG)
  48. virtual void Log(const char* command, ...) PRINTF_PARAMS(2, 3);
  49. virtual void LogAlways(const char* command, ...) PRINTF_PARAMS(2, 3);
  50. virtual void LogWarning(const char* command, ...) PRINTF_PARAMS(2, 3);
  51. virtual void LogError(const char* command, ...) PRINTF_PARAMS(2, 3);
  52. // Append the log output with the previous logged line
  53. void LogAppendWithPrevLine(const char* command, ...) override PRINTF_PARAMS(2, 3);
  54. virtual void LogToFile (const char* command, ...) PRINTF_PARAMS(2, 3);
  55. // Append the log output to the file with the previous logged line
  56. void LogToFileAppendWithPrevLine(const char* command, ...) override PRINTF_PARAMS(2, 3);
  57. virtual void LogToConsole(const char* command, ...) PRINTF_PARAMS(2, 3);
  58. // Append the log output to the console with the previous logged line
  59. void LogToConsoleAppendWithPrevLine(const char* command, ...) override PRINTF_PARAMS(2, 3);
  60. #else
  61. virtual void Log(const char* command, ...) PRINTF_PARAMS(2, 3) {}
  62. virtual void LogAlways(const char* command, ...) PRINTF_PARAMS(2, 3) {}
  63. virtual void LogWarning(const char* command, ...) PRINTF_PARAMS(2, 3) {}
  64. virtual void LogError(const char* command, ...) PRINTF_PARAMS(2, 3) {}
  65. void LogAppendWithPrevLine(const char* command, ...) override PRINTF_PARAMS(2, 3) {}
  66. virtual void LogToFile (const char* command, ...) PRINTF_PARAMS(2, 3) {}
  67. void LogToFileAppendWithPrevLine(const char* command, ...) override PRINTF_PARAMS(2, 3) {}
  68. virtual void LogToConsole(const char* command, ...) PRINTF_PARAMS(2, 3) {}
  69. void LogToConsoleAppendWithPrevLine(const char* command, ...) override PRINTF_PARAMS(2, 3) {}
  70. #endif // !defined(EXCLUDE_NORMAL_LOG)
  71. virtual void UpdateLoadingScreen(const char* command, ...) PRINTF_PARAMS(2, 3);
  72. virtual void SetVerbosity(int verbosity);
  73. virtual int GetVerbosityLevel();
  74. virtual void RegisterConsoleVariables();
  75. virtual void UnregisterConsoleVariables();
  76. virtual void AddCallback(ILogCallback* pCallback);
  77. virtual void RemoveCallback(ILogCallback* pCallback);
  78. virtual void LogV(ELogType ineType, int flags, const char* szFormat, va_list args);
  79. virtual void LogV(ELogType ineType, const char* szFormat, va_list args);
  80. void LogWithCallback(ELogType logType, const LogWriteCallback& messageCallback) override;
  81. virtual void Update();
  82. virtual const char* GetModuleFilter();
  83. virtual void FlushAndClose();
  84. virtual void Flush();
  85. private: // -------------------------------------------------------------------
  86. struct SLogMsg
  87. {
  88. enum class Destination
  89. {
  90. Default, //LogString, sends OnWrite to anycallback registered with AddCallback
  91. Console,
  92. File
  93. };
  94. // Use a fixed_string buffer that can hold 512 characters + NUL terminating character
  95. // If a string is greater than the fixed string size, then the message is stored
  96. // in AZStd::string allocated from the heap
  97. using MessageString = AZStd::variant<AZStd::fixed_string<512>, AZStd::string>;
  98. MessageString msg;
  99. ELogType logType;
  100. bool m_appendToPreviousLine;
  101. Destination destination;
  102. };
  103. void CheckAndPruneBackupLogs() const;
  104. bool IsError(ELogType logType) const { return logType == ELogType::eError || logType == ELogType::eErrorAlways || logType == ELogType::eWarning || logType == ELogType::eWarningAlways; }
  105. //helper function to pass calls to LogString... to the main thread, returns false if you are on the main thread already, in which case just process the work.
  106. bool LogToMainThread(AZStd::string_view szString, ELogType logType, bool m_appendToPreviousLine, SLogMsg::Destination destination);
  107. enum class MessageQueueState
  108. {
  109. NotQueued,
  110. Queued
  111. };
  112. #if !defined(EXCLUDE_NORMAL_LOG)
  113. void LogString(AZStd::string_view szString, ELogType logType);
  114. void LogStringToFile(AZStd::string_view szString, ELogType logType, bool m_appendToPreviousLine, MessageQueueState queueState);
  115. void LogStringToConsole(AZStd::string_view szString, ELogType logType, bool m_appendToPreviousLine);
  116. #else
  117. void LogString(AZStd::string_view szString, ELogType logType) {}
  118. void LogStringToFile(AZStd::string_view szString, ELogType logType, bool m_appendToPreviousLine, MessageQueueState queueState) {}
  119. void LogStringToConsole(AZStd::string_view szString, ELogType logType, bool m_appendToPreviousLine) {}
  120. #endif // !defined(EXCLUDE_NORMAL_LOG)
  121. bool OpenLogFile(const char* filename, AZ::IO::OpenMode mode);
  122. void CloseLogFile();
  123. // will format the message into m_szTemp
  124. void FormatMessage(const char* szCommand, ...) PRINTF_PARAMS(2, 3);
  125. #if defined(SUPPORT_LOG_IDENTER)
  126. void Indent(CLogIndenter* indenter);
  127. void Unindent(CLogIndenter* indenter);
  128. void BuildIndentString();
  129. virtual void PushAssetScopeName(const char* sAssetType, const char* sName);
  130. virtual void PopAssetScopeName();
  131. virtual const char* GetAssetScopeString();
  132. #endif
  133. ISystem* m_pSystem; //
  134. float m_fLastLoadingUpdateTime; // for non-frequent streamingEngine update
  135. char m_szFilename[MAX_FILENAME_SIZE]; // can be with path
  136. mutable char m_sBackupFilename[MAX_FILENAME_SIZE]; // can be with path
  137. AZ::IO::FileIOStream m_logFileHandle;
  138. bool m_backupLogs;
  139. #if defined(SUPPORT_LOG_IDENTER)
  140. uint8 m_indentation;
  141. LogStringType m_indentWithString;
  142. class CLogIndenter* m_topIndenter;
  143. struct SAssetScopeInfo
  144. {
  145. string sType;
  146. string sName;
  147. };
  148. std::vector<SAssetScopeInfo> m_assetScopeQueue;
  149. AZStd::mutex m_assetScopeQueueLock;
  150. string m_assetScopeString;
  151. #endif
  152. IConsole* m_pConsole; //
  153. struct SLogHistoryItem
  154. {
  155. char str[MAX_WARNING_LENGTH];
  156. const char* ptr;
  157. ELogType type;
  158. float time;
  159. };
  160. SLogHistoryItem m_history[16];
  161. int m_iLastHistoryItem;
  162. static bool CheckLogFormatter(const char* formatter);
  163. #if defined(KEEP_LOG_FILE_OPEN)
  164. static void LogFlushFile(IConsoleCmdArgs* pArgs);
  165. #endif
  166. public: // -------------------------------------------------------------------
  167. // checks the verbosity of the message and returns NULL if the message must NOT be
  168. // logged, or the pointer to the part of the message that should be logged
  169. const char* CheckAgainstVerbosity(const char* pText, bool& logtofile, bool& logtoconsole, const uint8 DefaultVerbosity = 2);
  170. // create backup of log file, useful behavior - only on development platform
  171. void CreateBackupFile() const;
  172. ICVar* m_pLogVerbosity; //
  173. ICVar* m_pLogWriteToFile; //
  174. ICVar* m_pLogWriteToFileVerbosity; //
  175. ICVar* m_pLogVerbosityOverridesWriteToFile; //
  176. ICVar* m_pLogSpamDelay; //
  177. ICVar* m_pLogModule; // Module filter for log
  178. Callbacks m_callbacks; //
  179. threadID m_nMainThreadId;
  180. CryMT::queue<SLogMsg> m_threadSafeMsgQueue;
  181. };