text_formatter.cpp 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. // Copyright 2014 Citra Emulator Project
  2. // Licensed under GPLv2 or any later version
  3. // Refer to the license.txt file included.
  4. #include <array>
  5. #include <cstdio>
  6. #ifdef _WIN32
  7. #include <windows.h>
  8. #endif
  9. #include "common/assert.h"
  10. #include "common/common_funcs.h"
  11. #include "common/logging/backend.h"
  12. #include "common/logging/log.h"
  13. #include "common/logging/text_formatter.h"
  14. #include "common/string_util.h"
  15. namespace Log {
  16. std::string FormatLogMessage(const Entry& entry) {
  17. unsigned int time_seconds = static_cast<unsigned int>(entry.timestamp.count() / 1000000);
  18. unsigned int time_fractional = static_cast<unsigned int>(entry.timestamp.count() % 1000000);
  19. const char* class_name = GetLogClassName(entry.log_class);
  20. const char* level_name = GetLevelName(entry.log_level);
  21. return fmt::format("[{:4d}.{:06d}] {} <{}> {}:{}:{}: {}", time_seconds, time_fractional,
  22. class_name, level_name, entry.filename, entry.function, entry.line_num,
  23. entry.message);
  24. }
  25. void PrintMessage(const Entry& entry) {
  26. auto str = FormatLogMessage(entry) + '\n';
  27. fputs(str.c_str(), stderr);
  28. }
  29. void PrintColoredMessage(const Entry& entry) {
  30. #ifdef _WIN32
  31. HANDLE console_handle = GetStdHandle(STD_ERROR_HANDLE);
  32. if (console_handle == INVALID_HANDLE_VALUE) {
  33. return;
  34. }
  35. CONSOLE_SCREEN_BUFFER_INFO original_info = {};
  36. GetConsoleScreenBufferInfo(console_handle, &original_info);
  37. WORD color = 0;
  38. switch (entry.log_level) {
  39. case Level::Trace: // Grey
  40. color = FOREGROUND_INTENSITY;
  41. break;
  42. case Level::Debug: // Cyan
  43. color = FOREGROUND_GREEN | FOREGROUND_BLUE;
  44. break;
  45. case Level::Info: // Bright gray
  46. color = FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE;
  47. break;
  48. case Level::Warning: // Bright yellow
  49. color = FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_INTENSITY;
  50. break;
  51. case Level::Error: // Bright red
  52. color = FOREGROUND_RED | FOREGROUND_INTENSITY;
  53. break;
  54. case Level::Critical: // Bright magenta
  55. color = FOREGROUND_RED | FOREGROUND_BLUE | FOREGROUND_INTENSITY;
  56. break;
  57. case Level::Count:
  58. UNREACHABLE();
  59. }
  60. SetConsoleTextAttribute(console_handle, color);
  61. #else
  62. #define ESC "\x1b"
  63. const char* color = "";
  64. switch (entry.log_level) {
  65. case Level::Trace: // Grey
  66. color = ESC "[1;30m";
  67. break;
  68. case Level::Debug: // Cyan
  69. color = ESC "[0;36m";
  70. break;
  71. case Level::Info: // Bright gray
  72. color = ESC "[0;37m";
  73. break;
  74. case Level::Warning: // Bright yellow
  75. color = ESC "[1;33m";
  76. break;
  77. case Level::Error: // Bright red
  78. color = ESC "[1;31m";
  79. break;
  80. case Level::Critical: // Bright magenta
  81. color = ESC "[1;35m";
  82. break;
  83. case Level::Count:
  84. UNREACHABLE();
  85. }
  86. fputs(color, stderr);
  87. #endif
  88. PrintMessage(entry);
  89. #ifdef _WIN32
  90. SetConsoleTextAttribute(console_handle, original_info.wAttributes);
  91. #else
  92. fputs(ESC "[0m", stderr);
  93. #undef ESC
  94. #endif
  95. }
  96. } // namespace Log