BellLogger.h 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148
  1. #ifndef BELL_LOGGER_H
  2. #define BELL_LOGGER_H
  3. #include <stdarg.h> // for va_end, va_list, va_start
  4. #include <stdio.h> // for printf, vprintf
  5. #include <chrono>
  6. #include <iomanip>
  7. #include <iostream>
  8. #include <string> // for string, basic_string
  9. namespace bell {
  10. class AbstractLogger {
  11. public:
  12. bool enableSubmodule = false;
  13. bool enableTimestamp = false;
  14. bool shortTime = false;
  15. virtual void debug(std::string filename, int line, std::string submodule,
  16. const char* format, ...) = 0;
  17. virtual void error(std::string filename, int line, std::string submodule,
  18. const char* format, ...) = 0;
  19. virtual void info(std::string filename, int line, std::string submodule,
  20. const char* format, ...) = 0;
  21. };
  22. extern bell::AbstractLogger* bellGlobalLogger;
  23. class BellLogger : public bell::AbstractLogger {
  24. public:
  25. // static bool enableColors = true;
  26. void debug(std::string filename, int line, std::string submodule,
  27. const char* format, ...) {
  28. printTimestamp();
  29. printf(colorRed);
  30. printf("D ");
  31. if (enableSubmodule) {
  32. printf(colorReset);
  33. printf("[%s] ", submodule.c_str());
  34. }
  35. printFilename(filename);
  36. printf(":%d: ", line);
  37. va_list args;
  38. va_start(args, format);
  39. vprintf(format, args);
  40. va_end(args);
  41. printf("\n");
  42. };
  43. void error(std::string filename, int line, std::string submodule,
  44. const char* format, ...) {
  45. printTimestamp();
  46. printf(colorRed);
  47. printf("E ");
  48. if (enableSubmodule) {
  49. printf(colorReset);
  50. printf("[%s] ", submodule.c_str());
  51. }
  52. printFilename(filename);
  53. printf(":%d: ", line);
  54. printf(colorRed);
  55. va_list args;
  56. va_start(args, format);
  57. vprintf(format, args);
  58. va_end(args);
  59. printf("\n");
  60. };
  61. void info(std::string filename, int line, std::string submodule,
  62. const char* format, ...) {
  63. printTimestamp();
  64. printf(colorBlue);
  65. printf("I ");
  66. if (enableSubmodule) {
  67. printf(colorReset);
  68. printf("[%s] ", submodule.c_str());
  69. }
  70. printFilename(filename);
  71. printf(":%d: ", line);
  72. printf(colorReset);
  73. va_list args;
  74. va_start(args, format);
  75. vprintf(format, args);
  76. va_end(args);
  77. printf("\n");
  78. };
  79. void printTimestamp() {
  80. if (enableTimestamp) {
  81. auto now = std::chrono::system_clock::now();
  82. time_t now_time = std::chrono::system_clock::to_time_t(now);
  83. const auto nowMs = std::chrono::duration_cast<std::chrono::milliseconds>(
  84. now.time_since_epoch()) %
  85. 1000;
  86. printf(colorReset);
  87. struct tm* gmt_time;
  88. if (shortTime) {
  89. gmt_time = localtime(&now_time);
  90. std::cout << std::put_time(gmt_time, "[%H:%M:%S") << '.'
  91. << std::setfill('0') << std::setw(3) << nowMs.count() << "] ";
  92. } else {
  93. gmt_time = gmtime(&now_time);
  94. std::cout << std::put_time(gmt_time, "[%Y-%m-%d %H:%M:%S") << '.'
  95. << std::setfill('0') << std::setw(3) << nowMs.count() << "] ";
  96. }
  97. }
  98. }
  99. void printFilename(std::string filename) {
  100. #ifdef _WIN32
  101. std::string basenameStr(filename.substr(filename.rfind("\\") + 1));
  102. #else
  103. std::string basenameStr(filename.substr(filename.rfind("/") + 1));
  104. #endif
  105. unsigned long hash = 5381;
  106. for (char const& c : basenameStr) {
  107. hash = ((hash << 5) + hash) + c; /* hash * 33 + c */
  108. }
  109. printf("\033[0;%dm", allColors[hash % NColors]);
  110. printf("%s", basenameStr.c_str());
  111. printf(colorReset);
  112. }
  113. private:
  114. static constexpr const char* colorReset = "\033[0m";
  115. static constexpr const char* colorRed = "\033[0;31m";
  116. static constexpr const char* colorBlue = "\033[0;34m";
  117. static constexpr const int NColors = 15;
  118. static constexpr int allColors[NColors] = {31, 32, 33, 34, 35, 36, 37, 90,
  119. 91, 92, 93, 94, 95, 96, 97};
  120. };
  121. void setDefaultLogger();
  122. void enableSubmoduleLogging();
  123. void enableTimestampLogging(bool local = false);
  124. } // namespace bell
  125. #define BELL_LOG(type, ...) \
  126. do { \
  127. bell::bellGlobalLogger->type(__FILE__, __LINE__, __VA_ARGS__); \
  128. } while (0)
  129. #endif