backend.h 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147
  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. std::string filename;
  23. unsigned int line_num;
  24. std::string function;
  25. std::string message;
  26. Entry() = default;
  27. Entry(Entry&& o) = default;
  28. Entry& operator=(Entry&& o) = default;
  29. Entry& operator=(const Entry& o) = default;
  30. };
  31. /**
  32. * Interface for logging backends. As loggers can be created and removed at runtime, this can be
  33. * used by a frontend for adding a custom logging backend as needed
  34. */
  35. class Backend {
  36. public:
  37. virtual ~Backend() = default;
  38. virtual void SetFilter(const Filter& new_filter) {
  39. filter = new_filter;
  40. }
  41. virtual const char* GetName() const = 0;
  42. virtual void Write(const Entry& entry) = 0;
  43. private:
  44. Filter filter;
  45. };
  46. /**
  47. * Backend that writes to stderr without any color commands
  48. */
  49. class ConsoleBackend : public Backend {
  50. public:
  51. static const char* Name() {
  52. return "console";
  53. }
  54. const char* GetName() const override {
  55. return Name();
  56. }
  57. void Write(const Entry& entry) override;
  58. };
  59. /**
  60. * Backend that writes to stderr and with color
  61. */
  62. class ColorConsoleBackend : public Backend {
  63. public:
  64. static const char* Name() {
  65. return "color_console";
  66. }
  67. const char* GetName() const override {
  68. return Name();
  69. }
  70. void Write(const Entry& entry) override;
  71. };
  72. /**
  73. * Backend that writes to a file passed into the constructor
  74. */
  75. class FileBackend : public Backend {
  76. public:
  77. explicit FileBackend(const std::string& filename);
  78. static const char* Name() {
  79. return "file";
  80. }
  81. const char* GetName() const override {
  82. return Name();
  83. }
  84. void Write(const Entry& entry) override;
  85. private:
  86. FileUtil::IOFile file;
  87. std::size_t bytes_written;
  88. };
  89. /**
  90. * Backend that writes to Visual Studio's output window
  91. */
  92. class DebuggerBackend : public Backend {
  93. public:
  94. static const char* Name() {
  95. return "debugger";
  96. }
  97. const char* GetName() const override {
  98. return Name();
  99. }
  100. void Write(const Entry& entry) override;
  101. };
  102. void AddBackend(std::unique_ptr<Backend> backend);
  103. void RemoveBackend(std::string_view backend_name);
  104. Backend* GetBackend(std::string_view backend_name);
  105. /**
  106. * Returns the name of the passed log class as a C-string. Subclasses are separated by periods
  107. * instead of underscores as in the enumeration.
  108. */
  109. const char* GetLogClassName(Class log_class);
  110. /**
  111. * Returns the name of the passed log level as a C-string.
  112. */
  113. const char* GetLevelName(Level log_level);
  114. /// Creates a log entry by formatting the given source location, and message.
  115. Entry CreateEntry(Class log_class, Level log_level, const char* filename, unsigned int line_nr,
  116. const char* function, std::string message);
  117. /**
  118. * The global filter will prevent any messages from even being processed if they are filtered. Each
  119. * backend can have a filter, but if the level is lower than the global filter, the backend will
  120. * never get the message
  121. */
  122. void SetGlobalFilter(const Filter& filter);
  123. } // namespace Log