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