BellLogger.h 3.9 KB

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