NetworkLogging.cpp 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151
  1. /* Copyright The kNet Project.
  2. Licensed under the Apache License, Version 2.0 (the "License");
  3. you may not use this file except in compliance with the License.
  4. You may obtain a copy of the License at
  5. http://www.apache.org/licenses/LICENSE-2.0
  6. Unless required by applicable law or agreed to in writing, software
  7. distributed under the License is distributed on an "AS IS" BASIS,
  8. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  9. See the License for the specific language governing permissions and
  10. limitations under the License. */
  11. /** @file NetworkLogging.cpp
  12. @brief Implements logging functionalities to stdout/file for different log channels. */
  13. #include <sstream>
  14. #include <iostream>
  15. #include <fstream>
  16. #include <cstdarg>
  17. #include <cstdio>
  18. #include <string>
  19. #include <cstring>
  20. #ifdef KNET_USE_BOOST
  21. #include <boost/thread/thread.hpp>
  22. #endif
  23. #include "kNet/DebugMemoryLeakCheck.h"
  24. #include "kNet/NetworkLogging.h"
  25. #include "kNet/Lockable.h"
  26. #include "kNet/Clock.h"
  27. #if defined(KNET_UNIX) || defined(ANDROID)
  28. #define _snprintf snprintf
  29. #endif
  30. using namespace std;
  31. namespace kNet
  32. {
  33. namespace
  34. {
  35. /// Specifies which kNet Log Channels are enabled. Log messages printed in other channels are muted.
  36. LogChannel kNetActiveLogChannels = LogUser;
  37. /// Specifies the file in which all logging is printed to. If this file is not open, logging goes to std::cout.
  38. ofstream kNetLogFile;
  39. Lockable<int> logWriteMutex;
  40. string Time()
  41. {
  42. static tick_t firstTick;
  43. static bool firstCall = true;
  44. if (firstCall)
  45. {
  46. firstCall = false;
  47. firstTick = Clock::Tick();
  48. return "0.000";
  49. }
  50. double t = Clock::SecondsSinceD(firstTick);
  51. std::stringstream ss;
  52. ss << t;
  53. #ifdef KNET_USE_BOOST
  54. ss << ", " << boost::this_thread::get_id();
  55. #endif
  56. return ss.str();
  57. }
  58. } // ~unnamed namespace
  59. void TimeOutputDebugStringVariadic(LogChannel logChannel, const char * /*filename*/, int /*lineNumber*/, const char *msg, ...)
  60. {
  61. if (!IsLogChannelActive(logChannel))
  62. return;
  63. Lockable<int>::LockType lock = logWriteMutex.Acquire();
  64. char errorStr[1024];
  65. va_list args;
  66. va_start(args, msg);
  67. vsnprintf(errorStr, 1023, msg, args);
  68. if (kNetLogFile.is_open())
  69. kNetLogFile << Time() << ": " << errorStr << std::endl;
  70. else
  71. std::cout << Time() << ": " << errorStr << std::endl;
  72. va_end(args);
  73. }
  74. void TimeOutputDebugString(LogChannel logChannel, const char * /*filename*/, int /*lineNumber*/, const char *msg)
  75. {
  76. if ((logChannel & kNetActiveLogChannels) == 0)
  77. return;
  78. Lockable<int>::LockType lock = logWriteMutex.Acquire();
  79. char errorStr[1024];
  80. _snprintf(errorStr, 1023, "%s", msg);
  81. if (kNetLogFile.is_open())
  82. kNetLogFile << Time() << ": " << errorStr << std::endl;
  83. else
  84. std::cout << Time() << ": " << errorStr << std::endl;
  85. }
  86. void SetLogChannels(LogChannel logChannels)
  87. {
  88. kNetActiveLogChannels = logChannels;
  89. }
  90. LogChannel GetLogChannels()
  91. {
  92. return kNetActiveLogChannels;
  93. }
  94. bool IsLogChannelActive(LogChannel channel)
  95. {
  96. return (channel & kNetActiveLogChannels) != 0;
  97. }
  98. void SetLogFile(const char *filename)
  99. {
  100. Lockable<int>::LockType lock = logWriteMutex.Acquire();
  101. kNetLogFile.close();
  102. if (filename && strlen(filename) > 0)
  103. kNetLogFile.open(filename, ios::app);
  104. }
  105. void EnableMemoryLeakLoggingAtExit()
  106. {
  107. #ifdef _MSC_VER
  108. _CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
  109. _CrtSetReportMode(_CRT_ASSERT, _CRTDBG_MODE_FILE);
  110. _CrtSetReportFile(_CRT_ASSERT, _CRTDBG_FILE_STDERR);
  111. _CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_FILE);
  112. _CrtSetReportFile(_CRT_WARN, _CRTDBG_FILE_STDERR);
  113. _CrtSetReportMode(_CRT_ERROR, _CRTDBG_MODE_FILE);
  114. _CrtSetReportFile(_CRT_ERROR, _CRTDBG_FILE_STDERR);
  115. #endif
  116. }
  117. } // ~kNet