backend.h 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144
  1. // Copyright 2014 Citra Emulator Project
  2. // Licensed under GPLv2 or any later version
  3. // Refer to the license.txt file included.
  4. #pragma once
  5. #include <chrono>
  6. #include <memory>
  7. #include <string>
  8. #include <string_view>
  9. #include "common/file_util.h"
  10. #include "common/logging/filter.h"
  11. #include "common/logging/log.h"
  12. namespace Log {
  13. class Filter;
  14. /**
  15. * A log entry. Log entries are store in a structured format to permit more varied output
  16. * formatting on different frontends, as well as facilitating filtering and aggregation.
  17. */
  18. struct Entry {
  19. std::chrono::microseconds timestamp;
  20. Class log_class;
  21. Level log_level;
  22. const char* filename;
  23. unsigned int line_num;
  24. std::string function;
  25. std::string message;
  26. bool final_entry = false;
  27. Entry() = default;
  28. Entry(Entry&& o) = default;
  29. Entry& operator=(Entry&& o) = default;
  30. Entry& operator=(const Entry& o) = default;
  31. };
  32. /**
  33. * Interface for logging backends. As loggers can be created and removed at runtime, this can be
  34. * used by a frontend for adding a custom logging backend as needed
  35. */
  36. class Backend {
  37. public:
  38. virtual ~Backend() = default;
  39. virtual void SetFilter(const Filter& new_filter) {
  40. filter = new_filter;
  41. }
  42. virtual const char* GetName() const = 0;
  43. virtual void Write(const Entry& entry) = 0;
  44. private:
  45. Filter filter;
  46. };
  47. /**
  48. * Backend that writes to stderr without any color commands
  49. */
  50. class ConsoleBackend : public Backend {
  51. public:
  52. static const char* Name() {
  53. return "console";
  54. }
  55. const char* GetName() const override {
  56. return Name();
  57. }
  58. void Write(const Entry& entry) override;
  59. };
  60. /**
  61. * Backend that writes to stderr and with color
  62. */
  63. class ColorConsoleBackend : public Backend {
  64. public:
  65. static const char* Name() {
  66. return "color_console";
  67. }
  68. const char* GetName() const override {
  69. return Name();
  70. }
  71. void Write(const Entry& entry) override;
  72. };
  73. /**
  74. * Backend that writes to a file passed into the constructor
  75. */
  76. class FileBackend : public Backend {
  77. public:
  78. explicit FileBackend(const std::string& filename);
  79. static const char* Name() {
  80. return "file";
  81. }
  82. const char* GetName() const override {
  83. return Name();
  84. }
  85. void Write(const Entry& entry) override;
  86. private:
  87. FileUtil::IOFile file;
  88. std::size_t bytes_written;
  89. };
  90. /**
  91. * Backend that writes to Visual Studio's output window
  92. */
  93. class DebuggerBackend : public Backend {
  94. public:
  95. static const char* Name() {
  96. return "debugger";
  97. }
  98. const char* GetName() const override {
  99. return Name();
  100. }
  101. void Write(const Entry& entry) override;
  102. };
  103. void AddBackend(std::unique_ptr<Backend> backend);
  104. void RemoveBackend(std::string_view backend_name);
  105. Backend* GetBackend(std::string_view backend_name);
  106. /**
  107. * Returns the name of the passed log class as a C-string. Subclasses are separated by periods
  108. * instead of underscores as in the enumeration.
  109. */
  110. const char* GetLogClassName(Class log_class);
  111. /**
  112. * Returns the name of the passed log level as a C-string.
  113. */
  114. const char* GetLevelName(Level log_level);
  115. /**
  116. * The global filter will prevent any messages from even being processed if they are filtered. Each
  117. * backend can have a filter, but if the level is lower than the global filter, the backend will
  118. * never get the message
  119. */
  120. void SetGlobalFilter(const Filter& filter);
  121. } // namespace Log