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