backend.cpp 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142
  1. // Copyright 2014 Citra Emulator Project
  2. // Licensed under GPLv2 or any later version
  3. // Refer to the license.txt file included.
  4. #include <algorithm>
  5. #include <array>
  6. #include <cstdio>
  7. #include "common/assert.h"
  8. #include "common/common_funcs.h" // snprintf compatibility define
  9. #include "common/logging/backend.h"
  10. #include "common/logging/filter.h"
  11. #include "common/logging/log.h"
  12. #include "common/logging/text_formatter.h"
  13. namespace Log {
  14. /// Macro listing all log classes. Code should define CLS and SUB as desired before invoking this.
  15. #define ALL_LOG_CLASSES() \
  16. CLS(Log) \
  17. CLS(Common) \
  18. SUB(Common, Filesystem) \
  19. SUB(Common, Memory) \
  20. CLS(Core) \
  21. SUB(Core, ARM11) \
  22. SUB(Core, Timing) \
  23. CLS(Config) \
  24. CLS(Debug) \
  25. SUB(Debug, Emulated) \
  26. SUB(Debug, GPU) \
  27. SUB(Debug, Breakpoint) \
  28. SUB(Debug, GDBStub) \
  29. CLS(Kernel) \
  30. SUB(Kernel, SVC) \
  31. CLS(Service) \
  32. SUB(Service, SRV) \
  33. SUB(Service, FS) \
  34. SUB(Service, ERR) \
  35. SUB(Service, APT) \
  36. SUB(Service, GSP) \
  37. SUB(Service, AC) \
  38. SUB(Service, AM) \
  39. SUB(Service, PTM) \
  40. SUB(Service, LDR) \
  41. SUB(Service, NDM) \
  42. SUB(Service, NIM) \
  43. SUB(Service, NWM) \
  44. SUB(Service, CAM) \
  45. SUB(Service, CECD) \
  46. SUB(Service, CFG) \
  47. SUB(Service, DSP) \
  48. SUB(Service, DLP) \
  49. SUB(Service, HID) \
  50. SUB(Service, SOC) \
  51. SUB(Service, IR) \
  52. SUB(Service, Y2R) \
  53. CLS(HW) \
  54. SUB(HW, Memory) \
  55. SUB(HW, LCD) \
  56. SUB(HW, GPU) \
  57. CLS(Frontend) \
  58. CLS(Render) \
  59. SUB(Render, Software) \
  60. SUB(Render, OpenGL) \
  61. CLS(Audio) \
  62. SUB(Audio, DSP) \
  63. CLS(Loader)
  64. // GetClassName is a macro defined by Windows.h, grrr...
  65. const char* GetLogClassName(Class log_class) {
  66. switch (log_class) {
  67. #define CLS(x) case Class::x: return #x;
  68. #define SUB(x, y) case Class::x##_##y: return #x "." #y;
  69. ALL_LOG_CLASSES()
  70. #undef CLS
  71. #undef SUB
  72. case Class::Count:
  73. UNREACHABLE();
  74. }
  75. }
  76. const char* GetLevelName(Level log_level) {
  77. #define LVL(x) case Level::x: return #x
  78. switch (log_level) {
  79. LVL(Trace);
  80. LVL(Debug);
  81. LVL(Info);
  82. LVL(Warning);
  83. LVL(Error);
  84. LVL(Critical);
  85. case Level::Count:
  86. UNREACHABLE();
  87. }
  88. #undef LVL
  89. }
  90. Entry CreateEntry(Class log_class, Level log_level,
  91. const char* filename, unsigned int line_nr, const char* function,
  92. const char* format, va_list args) {
  93. using std::chrono::steady_clock;
  94. using std::chrono::duration_cast;
  95. static steady_clock::time_point time_origin = steady_clock::now();
  96. std::array<char, 4 * 1024> formatting_buffer;
  97. Entry entry;
  98. entry.timestamp = duration_cast<std::chrono::microseconds>(steady_clock::now() - time_origin);
  99. entry.log_class = log_class;
  100. entry.log_level = log_level;
  101. snprintf(formatting_buffer.data(), formatting_buffer.size(), "%s:%s:%u", filename, function, line_nr);
  102. entry.location = std::string(formatting_buffer.data());
  103. vsnprintf(formatting_buffer.data(), formatting_buffer.size(), format, args);
  104. entry.message = std::string(formatting_buffer.data());
  105. return std::move(entry);
  106. }
  107. static Filter* filter = nullptr;
  108. void SetFilter(Filter* new_filter) {
  109. filter = new_filter;
  110. }
  111. void LogMessage(Class log_class, Level log_level,
  112. const char* filename, unsigned int line_nr, const char* function,
  113. const char* format, ...) {
  114. if (filter != nullptr && !filter->CheckMessage(log_class, log_level))
  115. return;
  116. va_list args;
  117. va_start(args, format);
  118. Entry entry = CreateEntry(log_class, log_level,
  119. filename, line_nr, function, format, args);
  120. va_end(args);
  121. PrintColoredMessage(entry);
  122. }
  123. }