mirror of
				https://github.com/PabloMK7/citra.git
				synced 2025-10-31 05:40:04 +00:00 
			
		
		
		
	common: logging: Restructure backend code
This commit is contained in:
		
							parent
							
								
									b559c078bc
								
							
						
					
					
						commit
						b57773b1cf
					
				
					 9 changed files with 310 additions and 285 deletions
				
			
		|  | @ -86,6 +86,7 @@ add_library(citra_common STATIC | |||
|     logging/log.h | ||||
|     logging/text_formatter.cpp | ||||
|     logging/text_formatter.h | ||||
|     logging/types.h | ||||
|     math_util.h | ||||
|     memory_detect.cpp | ||||
|     memory_detect.h | ||||
|  |  | |||
|  | @ -15,7 +15,6 @@ | |||
| #else | ||||
| #define _SH_DENYWR 0 | ||||
| #endif | ||||
| #include "common/assert.h" | ||||
| #include "common/file_util.h" | ||||
| #include "common/logging/backend.h" | ||||
| #include "common/logging/log.h" | ||||
|  | @ -25,10 +24,6 @@ | |||
| 
 | ||||
| namespace Common::Log { | ||||
| 
 | ||||
| Filter filter; | ||||
| void SetGlobalFilter(const Filter& f) { | ||||
|     filter = f; | ||||
| } | ||||
| /**
 | ||||
|  * Static state as a singleton. | ||||
|  */ | ||||
|  | @ -64,6 +59,14 @@ public: | |||
|         }); | ||||
|     } | ||||
| 
 | ||||
|     const Filter& GetGlobalFilter() const { | ||||
|         return filter; | ||||
|     } | ||||
| 
 | ||||
|     void SetGlobalFilter(const Filter& f) { | ||||
|         filter = f; | ||||
|     } | ||||
| 
 | ||||
|     Backend* GetBackend(std::string_view backend_name) { | ||||
|         const auto it = | ||||
|             std::find_if(backends.begin(), backends.end(), | ||||
|  | @ -182,119 +185,16 @@ void FileBackend::Write(const Entry& entry) { | |||
|     } | ||||
| } | ||||
| 
 | ||||
| DebuggerBackend::~DebuggerBackend() = default; | ||||
| 
 | ||||
| void DebuggerBackend::Write(const Entry& entry) { | ||||
| #ifdef _WIN32 | ||||
|     ::OutputDebugStringW(Common::UTF8ToUTF16W(FormatLogMessage(entry).append(1, '\n')).c_str()); | ||||
| #endif | ||||
| } | ||||
| 
 | ||||
| /// Macro listing all log classes. Code should define CLS and SUB as desired before invoking this.
 | ||||
| #define ALL_LOG_CLASSES()                                                                          \ | ||||
|     CLS(Log)                                                                                       \ | ||||
|     CLS(Common)                                                                                    \ | ||||
|     SUB(Common, Filesystem)                                                                        \ | ||||
|     SUB(Common, Memory)                                                                            \ | ||||
|     CLS(Core)                                                                                      \ | ||||
|     SUB(Core, ARM11)                                                                               \ | ||||
|     SUB(Core, Timing)                                                                              \ | ||||
|     SUB(Core, Cheats)                                                                              \ | ||||
|     CLS(Config)                                                                                    \ | ||||
|     CLS(Debug)                                                                                     \ | ||||
|     SUB(Debug, Emulated)                                                                           \ | ||||
|     SUB(Debug, GPU)                                                                                \ | ||||
|     SUB(Debug, Breakpoint)                                                                         \ | ||||
|     SUB(Debug, GDBStub)                                                                            \ | ||||
|     CLS(Kernel)                                                                                    \ | ||||
|     SUB(Kernel, SVC)                                                                               \ | ||||
|     CLS(Applet)                                                                                    \ | ||||
|     SUB(Applet, SWKBD)                                                                             \ | ||||
|     CLS(Service)                                                                                   \ | ||||
|     SUB(Service, SRV)                                                                              \ | ||||
|     SUB(Service, FRD)                                                                              \ | ||||
|     SUB(Service, FS)                                                                               \ | ||||
|     SUB(Service, ERR)                                                                              \ | ||||
|     SUB(Service, APT)                                                                              \ | ||||
|     SUB(Service, BOSS)                                                                             \ | ||||
|     SUB(Service, GSP)                                                                              \ | ||||
|     SUB(Service, AC)                                                                               \ | ||||
|     SUB(Service, AM)                                                                               \ | ||||
|     SUB(Service, PTM)                                                                              \ | ||||
|     SUB(Service, LDR)                                                                              \ | ||||
|     SUB(Service, MIC)                                                                              \ | ||||
|     SUB(Service, NDM)                                                                              \ | ||||
|     SUB(Service, NFC)                                                                              \ | ||||
|     SUB(Service, NIM)                                                                              \ | ||||
|     SUB(Service, NS)                                                                               \ | ||||
|     SUB(Service, NWM)                                                                              \ | ||||
|     SUB(Service, CAM)                                                                              \ | ||||
|     SUB(Service, CECD)                                                                             \ | ||||
|     SUB(Service, CFG)                                                                              \ | ||||
|     SUB(Service, CSND)                                                                             \ | ||||
|     SUB(Service, DSP)                                                                              \ | ||||
|     SUB(Service, DLP)                                                                              \ | ||||
|     SUB(Service, HID)                                                                              \ | ||||
|     SUB(Service, HTTP)                                                                             \ | ||||
|     SUB(Service, SOC)                                                                              \ | ||||
|     SUB(Service, IR)                                                                               \ | ||||
|     SUB(Service, Y2R)                                                                              \ | ||||
|     SUB(Service, PS)                                                                               \ | ||||
|     SUB(Service, PLGLDR)                                                                           \ | ||||
|     CLS(HW)                                                                                        \ | ||||
|     SUB(HW, Memory)                                                                                \ | ||||
|     SUB(HW, LCD)                                                                                   \ | ||||
|     SUB(HW, GPU)                                                                                   \ | ||||
|     SUB(HW, AES)                                                                                   \ | ||||
|     CLS(Frontend)                                                                                  \ | ||||
|     CLS(Render)                                                                                    \ | ||||
|     SUB(Render, Software)                                                                          \ | ||||
|     SUB(Render, OpenGL)                                                                            \ | ||||
|     SUB(Render, Vulkan)                                                                            \ | ||||
|     CLS(Audio)                                                                                     \ | ||||
|     SUB(Audio, DSP)                                                                                \ | ||||
|     SUB(Audio, Sink)                                                                               \ | ||||
|     CLS(Input)                                                                                     \ | ||||
|     CLS(Network)                                                                                   \ | ||||
|     CLS(Movie)                                                                                     \ | ||||
|     CLS(Loader)                                                                                    \ | ||||
|     CLS(WebService)                                                                                \ | ||||
|     CLS(RPC_Server) | ||||
| 
 | ||||
| // GetClassName is a macro defined by Windows.h, grrr...
 | ||||
| const char* GetLogClassName(Class log_class) { | ||||
|     switch (log_class) { | ||||
| #define CLS(x)                                                                                     \ | ||||
|     case Class::x:                                                                                 \ | ||||
|         return #x; | ||||
| #define SUB(x, y)                                                                                  \ | ||||
|     case Class::x##_##y:                                                                           \ | ||||
|         return #x "." #y; | ||||
|         ALL_LOG_CLASSES() | ||||
| #undef CLS | ||||
| #undef SUB | ||||
|     case Class::Count: | ||||
|     default: | ||||
|         break; | ||||
|     } | ||||
|     UNREACHABLE(); | ||||
| } | ||||
| 
 | ||||
| const char* GetLevelName(Level log_level) { | ||||
| #define LVL(x)                                                                                     \ | ||||
|     case Level::x:                                                                                 \ | ||||
|         return #x | ||||
|     switch (log_level) { | ||||
|         LVL(Trace); | ||||
|         LVL(Debug); | ||||
|         LVL(Info); | ||||
|         LVL(Warning); | ||||
|         LVL(Error); | ||||
|         LVL(Critical); | ||||
|     case Level::Count: | ||||
|     default: | ||||
|         break; | ||||
|     } | ||||
| #undef LVL | ||||
|     UNREACHABLE(); | ||||
| void SetGlobalFilter(const Filter& filter) { | ||||
|     Impl::Instance().SetGlobalFilter(filter); | ||||
| } | ||||
| 
 | ||||
| void AddBackend(std::unique_ptr<Backend> backend) { | ||||
|  | @ -313,6 +213,10 @@ void FmtLogMessageImpl(Class log_class, Level log_level, const char* filename, | |||
|                        unsigned int line_num, const char* function, const char* format, | ||||
|                        const fmt::format_args& args) { | ||||
|     auto& instance = Impl::Instance(); | ||||
|     const auto& filter = instance.GetGlobalFilter(); | ||||
|     if (!filter.CheckMessage(log_class, log_level)) | ||||
|         return; | ||||
| 
 | ||||
|     instance.PushEntry(log_class, log_level, filename, line_num, function, | ||||
|                        fmt::vformat(format, args)); | ||||
| } | ||||
|  |  | |||
|  | @ -4,7 +4,6 @@ | |||
| 
 | ||||
| #pragma once | ||||
| 
 | ||||
| #include <chrono> | ||||
| #include <memory> | ||||
| #include <string> | ||||
| #include <string_view> | ||||
|  | @ -17,21 +16,6 @@ class IOFile; | |||
| 
 | ||||
| namespace Common::Log { | ||||
| 
 | ||||
| /**
 | ||||
|  * A log entry. Log entries are store in a structured format to permit more varied output | ||||
|  * formatting on different frontends, as well as facilitating filtering and aggregation. | ||||
|  */ | ||||
| struct Entry { | ||||
|     std::chrono::microseconds timestamp; | ||||
|     Class log_class{}; | ||||
|     Level log_level{}; | ||||
|     const char* filename = nullptr; | ||||
|     unsigned int line_num = 0; | ||||
|     std::string function; | ||||
|     std::string message; | ||||
|     bool final_entry = false; | ||||
| }; | ||||
| 
 | ||||
| /**
 | ||||
|  * Interface for logging backends. As loggers can be created and removed at runtime, this can be | ||||
|  * used by a frontend for adding a custom logging backend as needed | ||||
|  | @ -147,14 +131,9 @@ void RemoveBackend(std::string_view backend_name); | |||
| Backend* GetBackend(std::string_view backend_name); | ||||
| 
 | ||||
| /**
 | ||||
|  * Returns the name of the passed log class as a C-string. Subclasses are separated by periods | ||||
|  * instead of underscores as in the enumeration. | ||||
|  * The global filter will prevent any messages from even being processed if they are filtered. Each | ||||
|  * backend can have a filter, but if the level is lower than the global filter, the backend will | ||||
|  * never get the message | ||||
|  */ | ||||
| const char* GetLogClassName(Class log_class); | ||||
| 
 | ||||
| /**
 | ||||
|  * Returns the name of the passed log level as a C-string. | ||||
|  */ | ||||
| const char* GetLevelName(Level log_level); | ||||
| 
 | ||||
| void SetGlobalFilter(const Filter& filter); | ||||
| } // namespace Common::Log
 | ||||
|  |  | |||
|  | @ -3,7 +3,6 @@ | |||
| // Refer to the license.txt file included.
 | ||||
| 
 | ||||
| #include <algorithm> | ||||
| #include "common/logging/backend.h" | ||||
| #include "common/logging/filter.h" | ||||
| #include "common/string_util.h" | ||||
| 
 | ||||
|  | @ -22,7 +21,7 @@ Level GetLevelByName(const It begin, const It end) { | |||
| 
 | ||||
| template <typename It> | ||||
| Class GetClassByName(const It begin, const It end) { | ||||
|     for (ClassType i = 0; i < static_cast<ClassType>(Class::Count); ++i) { | ||||
|     for (u8 i = 0; i < static_cast<u8>(Class::Count); ++i) { | ||||
|         const char* level_name = GetLogClassName(static_cast<Class>(i)); | ||||
|         if (Common::ComparePartialString(begin, end, level_name)) { | ||||
|             return static_cast<Class>(i); | ||||
|  | @ -62,6 +61,115 @@ bool ParseFilterRule(Filter& instance, Iterator begin, Iterator end) { | |||
| } | ||||
| } // Anonymous namespace
 | ||||
| 
 | ||||
| /// Macro listing all log classes. Code should define CLS and SUB as desired before invoking this.
 | ||||
| #define ALL_LOG_CLASSES()                                                                          \ | ||||
|     CLS(Log)                                                                                       \ | ||||
|     CLS(Common)                                                                                    \ | ||||
|     SUB(Common, Filesystem)                                                                        \ | ||||
|     SUB(Common, Memory)                                                                            \ | ||||
|     CLS(Core)                                                                                      \ | ||||
|     SUB(Core, ARM11)                                                                               \ | ||||
|     SUB(Core, Timing)                                                                              \ | ||||
|     SUB(Core, Cheats)                                                                              \ | ||||
|     CLS(Config)                                                                                    \ | ||||
|     CLS(Debug)                                                                                     \ | ||||
|     SUB(Debug, Emulated)                                                                           \ | ||||
|     SUB(Debug, GPU)                                                                                \ | ||||
|     SUB(Debug, Breakpoint)                                                                         \ | ||||
|     SUB(Debug, GDBStub)                                                                            \ | ||||
|     CLS(Kernel)                                                                                    \ | ||||
|     SUB(Kernel, SVC)                                                                               \ | ||||
|     CLS(Applet)                                                                                    \ | ||||
|     SUB(Applet, SWKBD)                                                                             \ | ||||
|     CLS(Service)                                                                                   \ | ||||
|     SUB(Service, SRV)                                                                              \ | ||||
|     SUB(Service, FRD)                                                                              \ | ||||
|     SUB(Service, FS)                                                                               \ | ||||
|     SUB(Service, ERR)                                                                              \ | ||||
|     SUB(Service, APT)                                                                              \ | ||||
|     SUB(Service, BOSS)                                                                             \ | ||||
|     SUB(Service, GSP)                                                                              \ | ||||
|     SUB(Service, AC)                                                                               \ | ||||
|     SUB(Service, AM)                                                                               \ | ||||
|     SUB(Service, PTM)                                                                              \ | ||||
|     SUB(Service, LDR)                                                                              \ | ||||
|     SUB(Service, MIC)                                                                              \ | ||||
|     SUB(Service, NDM)                                                                              \ | ||||
|     SUB(Service, NFC)                                                                              \ | ||||
|     SUB(Service, NIM)                                                                              \ | ||||
|     SUB(Service, NS)                                                                               \ | ||||
|     SUB(Service, NWM)                                                                              \ | ||||
|     SUB(Service, CAM)                                                                              \ | ||||
|     SUB(Service, CECD)                                                                             \ | ||||
|     SUB(Service, CFG)                                                                              \ | ||||
|     SUB(Service, CSND)                                                                             \ | ||||
|     SUB(Service, DSP)                                                                              \ | ||||
|     SUB(Service, DLP)                                                                              \ | ||||
|     SUB(Service, HID)                                                                              \ | ||||
|     SUB(Service, HTTP)                                                                             \ | ||||
|     SUB(Service, SOC)                                                                              \ | ||||
|     SUB(Service, IR)                                                                               \ | ||||
|     SUB(Service, Y2R)                                                                              \ | ||||
|     SUB(Service, PS)                                                                               \ | ||||
|     SUB(Service, PLGLDR)                                                                           \ | ||||
|     CLS(HW)                                                                                        \ | ||||
|     SUB(HW, Memory)                                                                                \ | ||||
|     SUB(HW, LCD)                                                                                   \ | ||||
|     SUB(HW, GPU)                                                                                   \ | ||||
|     SUB(HW, AES)                                                                                   \ | ||||
|     CLS(Frontend)                                                                                  \ | ||||
|     CLS(Render)                                                                                    \ | ||||
|     SUB(Render, Software)                                                                          \ | ||||
|     SUB(Render, OpenGL)                                                                            \ | ||||
|     SUB(Render, Vulkan)                                                                            \ | ||||
|     CLS(Audio)                                                                                     \ | ||||
|     SUB(Audio, DSP)                                                                                \ | ||||
|     SUB(Audio, Sink)                                                                               \ | ||||
|     CLS(Input)                                                                                     \ | ||||
|     CLS(Network)                                                                                   \ | ||||
|     CLS(Movie)                                                                                     \ | ||||
|     CLS(Loader)                                                                                    \ | ||||
|     CLS(WebService)                                                                                \ | ||||
|     CLS(RPC_Server) | ||||
| 
 | ||||
| // GetClassName is a macro defined by Windows.h, grrr...
 | ||||
| const char* GetLogClassName(Class log_class) { | ||||
|     switch (log_class) { | ||||
| #define CLS(x)                                                                                     \ | ||||
|     case Class::x:                                                                                 \ | ||||
|         return #x; | ||||
| #define SUB(x, y)                                                                                  \ | ||||
|     case Class::x##_##y:                                                                           \ | ||||
|         return #x "." #y; | ||||
|         ALL_LOG_CLASSES() | ||||
| #undef CLS | ||||
| #undef SUB | ||||
|     case Class::Count: | ||||
|     default: | ||||
|         break; | ||||
|     } | ||||
|     UNREACHABLE(); | ||||
| } | ||||
| 
 | ||||
| const char* GetLevelName(Level log_level) { | ||||
| #define LVL(x)                                                                                     \ | ||||
|     case Level::x:                                                                                 \ | ||||
|         return #x | ||||
|     switch (log_level) { | ||||
|         LVL(Trace); | ||||
|         LVL(Debug); | ||||
|         LVL(Info); | ||||
|         LVL(Warning); | ||||
|         LVL(Error); | ||||
|         LVL(Critical); | ||||
|     case Level::Count: | ||||
|     default: | ||||
|         break; | ||||
|     } | ||||
| #undef LVL | ||||
|     UNREACHABLE(); | ||||
| } | ||||
| 
 | ||||
| Filter::Filter(Level default_level) { | ||||
|     ResetAll(default_level); | ||||
| } | ||||
|  |  | |||
|  | @ -7,6 +7,57 @@ | |||
| #include <array> | ||||
| #include <cstddef> | ||||
| #include <string_view> | ||||
| #include "common/logging/log.h" | ||||
| #include "common/logging/types.h" | ||||
| 
 | ||||
| namespace Common::Log {} // namespace Common::Log
 | ||||
| namespace Common::Log { | ||||
| 
 | ||||
| /**
 | ||||
|  * Returns the name of the passed log class as a C-string. Subclasses are separated by periods | ||||
|  * instead of underscores as in the enumeration. | ||||
|  */ | ||||
| const char* GetLogClassName(Class log_class); | ||||
| 
 | ||||
| /**
 | ||||
|  * Returns the name of the passed log level as a C-string. | ||||
|  */ | ||||
| const char* GetLevelName(Level log_level); | ||||
| 
 | ||||
| /**
 | ||||
|  * Implements a log message filter which allows different log classes to have different minimum | ||||
|  * severity levels. The filter can be changed at runtime and can be parsed from a string to allow | ||||
|  * editing via the interface or loading from a configuration file. | ||||
|  */ | ||||
| class Filter { | ||||
| public: | ||||
|     /// Initializes the filter with all classes having `default_level` as the minimum level.
 | ||||
|     explicit Filter(Level default_level = Level::Info); | ||||
| 
 | ||||
|     /// Resets the filter so that all classes have `level` as the minimum displayed level.
 | ||||
|     void ResetAll(Level level); | ||||
|     /// Sets the minimum level of `log_class` (and not of its subclasses) to `level`.
 | ||||
|     void SetClassLevel(Class log_class, Level level); | ||||
| 
 | ||||
|     /**
 | ||||
|      * Parses a filter string and applies it to this filter. | ||||
|      * | ||||
|      * A filter string consists of a space-separated list of filter rules, each of the format | ||||
|      * `<class>:<level>`. `<class>` is a log class name, with subclasses separated using periods. | ||||
|      * `*` is allowed as a class name and will reset all filters to the specified level. `<level>` | ||||
|      * a severity level name which will be set as the minimum logging level of the matched classes. | ||||
|      * Rules are applied left to right, with each rule overriding previous ones in the sequence. | ||||
|      * | ||||
|      * A few examples of filter rules: | ||||
|      *  - `*:Info` -- Resets the level of all classes to Info. | ||||
|      *  - `Service:Info` -- Sets the level of Service to Info. | ||||
|      *  - `Service.FS:Trace` -- Sets the level of the Service.FS class to Trace. | ||||
|      */ | ||||
|     void ParseFilterString(std::string_view filter_view); | ||||
| 
 | ||||
|     /// Matches class/level combination against the filter, returning true if it passed.
 | ||||
|     bool CheckMessage(Class log_class, Level level) const; | ||||
| 
 | ||||
| private: | ||||
|     std::array<Level, static_cast<std::size_t>(Class::Count)> class_levels; | ||||
| }; | ||||
| 
 | ||||
| } // namespace Common::Log
 | ||||
|  |  | |||
|  | @ -6,8 +6,8 @@ | |||
| 
 | ||||
| #include <algorithm> | ||||
| #include <array> | ||||
| #include "common/common_types.h" | ||||
| #include "common/logging/formatter.h" | ||||
| #include "common/logging/types.h" | ||||
| 
 | ||||
| namespace Common::Log { | ||||
| 
 | ||||
|  | @ -20,144 +20,6 @@ constexpr const char* TrimSourcePath(std::string_view source) { | |||
|     return source.data() + idx; | ||||
| } | ||||
| 
 | ||||
| /// Specifies the severity or level of detail of the log message.
 | ||||
| enum class Level : u8 { | ||||
|     Trace,    ///< Extremely detailed and repetitive debugging information that is likely to
 | ||||
|               ///< pollute logs.
 | ||||
|     Debug,    ///< Less detailed debugging information.
 | ||||
|     Info,     ///< Status information from important points during execution.
 | ||||
|     Warning,  ///< Minor or potential problems found during execution of a task.
 | ||||
|     Error,    ///< Major problems found during execution of a task that prevent it from being
 | ||||
|               ///< completed.
 | ||||
|     Critical, ///< Major problems during execution that threaten the stability of the entire
 | ||||
|               ///< application.
 | ||||
| 
 | ||||
|     Count ///< Total number of logging levels
 | ||||
| }; | ||||
| 
 | ||||
| typedef u8 ClassType; | ||||
| 
 | ||||
| /**
 | ||||
|  * Specifies the sub-system that generated the log message. | ||||
|  * | ||||
|  * @note If you add a new entry here, also add a corresponding one to `ALL_LOG_CLASSES` in | ||||
|  * backend.cpp. | ||||
|  */ | ||||
| enum class Class : ClassType { | ||||
|     Log,               ///< Messages about the log system itself
 | ||||
|     Common,            ///< Library routines
 | ||||
|     Common_Filesystem, ///< Filesystem interface library
 | ||||
|     Common_Memory,     ///< Memory mapping and management functions
 | ||||
|     Core,              ///< LLE emulation core
 | ||||
|     Core_ARM11,        ///< ARM11 CPU core
 | ||||
|     Core_Timing,       ///< CoreTiming functions
 | ||||
|     Core_Cheats,       ///< Cheat functions
 | ||||
|     Config,            ///< Emulator configuration (including commandline)
 | ||||
|     Debug,             ///< Debugging tools
 | ||||
|     Debug_Emulated,    ///< Debug messages from the emulated programs
 | ||||
|     Debug_GPU,         ///< GPU debugging tools
 | ||||
|     Debug_Breakpoint,  ///< Logging breakpoints and watchpoints
 | ||||
|     Debug_GDBStub,     ///< GDB Stub
 | ||||
|     Kernel,            ///< The HLE implementation of the CTR kernel
 | ||||
|     Kernel_SVC,        ///< Kernel system calls
 | ||||
|     Applet,            ///< HLE implementation of system applets. Each applet
 | ||||
|                        ///< should have its own subclass.
 | ||||
|     Applet_SWKBD,      ///< The Software Keyboard applet
 | ||||
|     Service,           ///< HLE implementation of system services. Each major service
 | ||||
|                        ///< should have its own subclass.
 | ||||
|     Service_SRV,       ///< The SRV (Service Directory) implementation
 | ||||
|     Service_FRD,       ///< The FRD (Friends) service
 | ||||
|     Service_FS,        ///< The FS (Filesystem) service implementation
 | ||||
|     Service_ERR,       ///< The ERR (Error) port implementation
 | ||||
|     Service_APT,       ///< The APT (Applets) service
 | ||||
|     Service_BOSS,      ///< The BOSS (SpotPass) service
 | ||||
|     Service_GSP,       ///< The GSP (GPU control) service
 | ||||
|     Service_AC,        ///< The AC (WiFi status) service
 | ||||
|     Service_AM,        ///< The AM (Application manager) service
 | ||||
|     Service_PTM,       ///< The PTM (Power status & misc.) service
 | ||||
|     Service_LDR,       ///< The LDR (3ds dll loader) service
 | ||||
|     Service_MIC,       ///< The MIC (Microphone) service
 | ||||
|     Service_NDM,       ///< The NDM (Network daemon manager) service
 | ||||
|     Service_NFC,       ///< The NFC service
 | ||||
|     Service_NIM,       ///< The NIM (Network interface manager) service
 | ||||
|     Service_NS,        ///< The NS (Nintendo User Interface Shell) service
 | ||||
|     Service_NWM,       ///< The NWM (Network wlan manager) service
 | ||||
|     Service_CAM,       ///< The CAM (Camera) service
 | ||||
|     Service_CECD,      ///< The CECD (StreetPass) service
 | ||||
|     Service_CFG,       ///< The CFG (Configuration) service
 | ||||
|     Service_CSND,      ///< The CSND (CWAV format process) service
 | ||||
|     Service_DSP,       ///< The DSP (DSP control) service
 | ||||
|     Service_DLP,       ///< The DLP (Download Play) service
 | ||||
|     Service_HID,       ///< The HID (Human interface device) service
 | ||||
|     Service_HTTP,      ///< The HTTP service
 | ||||
|     Service_SOC,       ///< The SOC (Socket) service
 | ||||
|     Service_IR,        ///< The IR service
 | ||||
|     Service_Y2R,       ///< The Y2R (YUV to RGB conversion) service
 | ||||
|     Service_PS,        ///< The PS (Process) service
 | ||||
|     Service_PLGLDR,    ///< The PLGLDR (plugin loader) service
 | ||||
|     HW,                ///< Low-level hardware emulation
 | ||||
|     HW_Memory,         ///< Memory-map and address translation
 | ||||
|     HW_LCD,            ///< LCD register emulation
 | ||||
|     HW_GPU,            ///< GPU control emulation
 | ||||
|     HW_AES,            ///< AES engine emulation
 | ||||
|     Frontend,          ///< Emulator UI
 | ||||
|     Render,            ///< Emulator video output and hardware acceleration
 | ||||
|     Render_Software,   ///< Software renderer backend
 | ||||
|     Render_OpenGL,     ///< OpenGL backend
 | ||||
|     Render_Vulkan,     ///< Vulkan backend
 | ||||
|     Audio,             ///< Audio emulation
 | ||||
|     Audio_DSP,         ///< The HLE and LLE implementations of the DSP
 | ||||
|     Audio_Sink,        ///< Emulator audio output backend
 | ||||
|     Loader,            ///< ROM loader
 | ||||
|     Input,             ///< Input emulation
 | ||||
|     Network,           ///< Network emulation
 | ||||
|     Movie,             ///< Movie (Input Recording) Playback
 | ||||
|     WebService,        ///< Interface to Citra Web Services
 | ||||
|     RPC_Server,        ///< RPC server
 | ||||
|     Count              ///< Total number of logging classes
 | ||||
| }; | ||||
| 
 | ||||
| /**
 | ||||
|  * Implements a log message filter which allows different log classes to have different minimum | ||||
|  * severity levels. The filter can be changed at runtime and can be parsed from a string to allow | ||||
|  * editing via the interface or loading from a configuration file. | ||||
|  */ | ||||
| class Filter { | ||||
| public: | ||||
|     /// Initializes the filter with all classes having `default_level` as the minimum level.
 | ||||
|     explicit Filter(Level default_level = Level::Info); | ||||
| 
 | ||||
|     /// Resets the filter so that all classes have `level` as the minimum displayed level.
 | ||||
|     void ResetAll(Level level); | ||||
|     /// Sets the minimum level of `log_class` (and not of its subclasses) to `level`.
 | ||||
|     void SetClassLevel(Class log_class, Level level); | ||||
| 
 | ||||
|     /**
 | ||||
|      * Parses a filter string and applies it to this filter. | ||||
|      * | ||||
|      * A filter string consists of a space-separated list of filter rules, each of the format | ||||
|      * `<class>:<level>`. `<class>` is a log class name, with subclasses separated using periods. | ||||
|      * `*` is allowed as a class name and will reset all filters to the specified level. `<level>` | ||||
|      * a severity level name which will be set as the minimum logging level of the matched classes. | ||||
|      * Rules are applied left to right, with each rule overriding previous ones in the sequence. | ||||
|      * | ||||
|      * A few examples of filter rules: | ||||
|      *  - `*:Info` -- Resets the level of all classes to Info. | ||||
|      *  - `Service:Info` -- Sets the level of Service to Info. | ||||
|      *  - `Service.FS:Trace` -- Sets the level of the Service.FS class to Trace. | ||||
|      */ | ||||
|     void ParseFilterString(std::string_view filter_view); | ||||
| 
 | ||||
|     /// Matches class/level combination against the filter, returning true if it passed.
 | ||||
|     bool CheckMessage(Class log_class, Level level) const; | ||||
| 
 | ||||
| private: | ||||
|     std::array<Level, static_cast<std::size_t>(Class::Count)> class_levels; | ||||
| }; | ||||
| extern Filter filter; | ||||
| 
 | ||||
| void SetGlobalFilter(const Filter& f); | ||||
| 
 | ||||
| /// Logs a message to the global logger, using fmt
 | ||||
| void FmtLogMessageImpl(Class log_class, Level log_level, const char* filename, | ||||
|                        unsigned int line_num, const char* function, const char* format, | ||||
|  | @ -166,9 +28,6 @@ void FmtLogMessageImpl(Class log_class, Level log_level, const char* filename, | |||
| template <typename... Args> | ||||
| void FmtLogMessage(Class log_class, Level log_level, const char* filename, unsigned int line_num, | ||||
|                    const char* function, const char* format, const Args&... args) { | ||||
|     if (!filter.CheckMessage(log_class, log_level)) | ||||
|         return; | ||||
| 
 | ||||
|     FmtLogMessageImpl(log_class, log_level, filename, line_num, function, format, | ||||
|                       fmt::make_format_args(args...)); | ||||
| } | ||||
|  |  | |||
|  | @ -13,7 +13,7 @@ | |||
| 
 | ||||
| #include "common/assert.h" | ||||
| #include "common/common_funcs.h" | ||||
| #include "common/logging/backend.h" | ||||
| #include "common/logging/filter.h" | ||||
| #include "common/logging/log.h" | ||||
| #include "common/logging/text_formatter.h" | ||||
| #include "common/string_util.h" | ||||
|  |  | |||
							
								
								
									
										123
									
								
								src/common/logging/types.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										123
									
								
								src/common/logging/types.h
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,123 @@ | |||
| // Copyright 2023 Citra Emulator Project
 | ||||
| // Licensed under GPLv2 or any later version
 | ||||
| // Refer to the license.txt file included.
 | ||||
| 
 | ||||
| #pragma once | ||||
| 
 | ||||
| #include <chrono> | ||||
| 
 | ||||
| #include "common/common_types.h" | ||||
| 
 | ||||
| namespace Common::Log { | ||||
| 
 | ||||
| /// Specifies the severity or level of detail of the log message.
 | ||||
| enum class Level : u8 { | ||||
|     Trace, ///< Extremely detailed and repetitive debugging information that is likely to
 | ||||
|     ///< pollute logs.
 | ||||
|     Debug,   ///< Less detailed debugging information.
 | ||||
|     Info,    ///< Status information from important points during execution.
 | ||||
|     Warning, ///< Minor or potential problems found during execution of a task.
 | ||||
|     Error,   ///< Major problems found during execution of a task that prevent it from being
 | ||||
|     ///< completed.
 | ||||
|     Critical, ///< Major problems during execution that threaten the stability of the entire
 | ||||
|     ///< application.
 | ||||
| 
 | ||||
|     Count ///< Total number of logging levels
 | ||||
| }; | ||||
| 
 | ||||
| /**
 | ||||
|  * Specifies the sub-system that generated the log message. | ||||
|  * | ||||
|  * @note If you add a new entry here, also add a corresponding one to `ALL_LOG_CLASSES` in | ||||
|  * backend.cpp. | ||||
|  */ | ||||
| enum class Class : u8 { | ||||
|     Log,               ///< Messages about the log system itself
 | ||||
|     Common,            ///< Library routines
 | ||||
|     Common_Filesystem, ///< Filesystem interface library
 | ||||
|     Common_Memory,     ///< Memory mapping and management functions
 | ||||
|     Core,              ///< LLE emulation core
 | ||||
|     Core_ARM11,        ///< ARM11 CPU core
 | ||||
|     Core_Timing,       ///< CoreTiming functions
 | ||||
|     Core_Cheats,       ///< Cheat functions
 | ||||
|     Config,            ///< Emulator configuration (including commandline)
 | ||||
|     Debug,             ///< Debugging tools
 | ||||
|     Debug_Emulated,    ///< Debug messages from the emulated programs
 | ||||
|     Debug_GPU,         ///< GPU debugging tools
 | ||||
|     Debug_Breakpoint,  ///< Logging breakpoints and watchpoints
 | ||||
|     Debug_GDBStub,     ///< GDB Stub
 | ||||
|     Kernel,            ///< The HLE implementation of the CTR kernel
 | ||||
|     Kernel_SVC,        ///< Kernel system calls
 | ||||
|     Applet,            ///< HLE implementation of system applets. Each applet
 | ||||
|     ///< should have its own subclass.
 | ||||
|     Applet_SWKBD, ///< The Software Keyboard applet
 | ||||
|     Service,      ///< HLE implementation of system services. Each major service
 | ||||
|     ///< should have its own subclass.
 | ||||
|     Service_SRV,     ///< The SRV (Service Directory) implementation
 | ||||
|     Service_FRD,     ///< The FRD (Friends) service
 | ||||
|     Service_FS,      ///< The FS (Filesystem) service implementation
 | ||||
|     Service_ERR,     ///< The ERR (Error) port implementation
 | ||||
|     Service_APT,     ///< The APT (Applets) service
 | ||||
|     Service_BOSS,    ///< The BOSS (SpotPass) service
 | ||||
|     Service_GSP,     ///< The GSP (GPU control) service
 | ||||
|     Service_AC,      ///< The AC (WiFi status) service
 | ||||
|     Service_AM,      ///< The AM (Application manager) service
 | ||||
|     Service_PTM,     ///< The PTM (Power status & misc.) service
 | ||||
|     Service_LDR,     ///< The LDR (3ds dll loader) service
 | ||||
|     Service_MIC,     ///< The MIC (Microphone) service
 | ||||
|     Service_NDM,     ///< The NDM (Network daemon manager) service
 | ||||
|     Service_NFC,     ///< The NFC service
 | ||||
|     Service_NIM,     ///< The NIM (Network interface manager) service
 | ||||
|     Service_NS,      ///< The NS (Nintendo User Interface Shell) service
 | ||||
|     Service_NWM,     ///< The NWM (Network wlan manager) service
 | ||||
|     Service_CAM,     ///< The CAM (Camera) service
 | ||||
|     Service_CECD,    ///< The CECD (StreetPass) service
 | ||||
|     Service_CFG,     ///< The CFG (Configuration) service
 | ||||
|     Service_CSND,    ///< The CSND (CWAV format process) service
 | ||||
|     Service_DSP,     ///< The DSP (DSP control) service
 | ||||
|     Service_DLP,     ///< The DLP (Download Play) service
 | ||||
|     Service_HID,     ///< The HID (Human interface device) service
 | ||||
|     Service_HTTP,    ///< The HTTP service
 | ||||
|     Service_SOC,     ///< The SOC (Socket) service
 | ||||
|     Service_IR,      ///< The IR service
 | ||||
|     Service_Y2R,     ///< The Y2R (YUV to RGB conversion) service
 | ||||
|     Service_PS,      ///< The PS (Process) service
 | ||||
|     Service_PLGLDR,  ///< The PLGLDR (plugin loader) service
 | ||||
|     HW,              ///< Low-level hardware emulation
 | ||||
|     HW_Memory,       ///< Memory-map and address translation
 | ||||
|     HW_LCD,          ///< LCD register emulation
 | ||||
|     HW_GPU,          ///< GPU control emulation
 | ||||
|     HW_AES,          ///< AES engine emulation
 | ||||
|     Frontend,        ///< Emulator UI
 | ||||
|     Render,          ///< Emulator video output and hardware acceleration
 | ||||
|     Render_Software, ///< Software renderer backend
 | ||||
|     Render_OpenGL,   ///< OpenGL backend
 | ||||
|     Render_Vulkan,   ///< Vulkan backend
 | ||||
|     Audio,           ///< Audio emulation
 | ||||
|     Audio_DSP,       ///< The HLE and LLE implementations of the DSP
 | ||||
|     Audio_Sink,      ///< Emulator audio output backend
 | ||||
|     Loader,          ///< ROM loader
 | ||||
|     Input,           ///< Input emulation
 | ||||
|     Network,         ///< Network emulation
 | ||||
|     Movie,           ///< Movie (Input Recording) Playback
 | ||||
|     WebService,      ///< Interface to Citra Web Services
 | ||||
|     RPC_Server,      ///< RPC server
 | ||||
|     Count            ///< Total number of logging classes
 | ||||
| }; | ||||
| 
 | ||||
| /**
 | ||||
|  * A log entry. Log entries are store in a structured format to permit more varied output | ||||
|  * formatting on different frontends, as well as facilitating filtering and aggregation. | ||||
|  */ | ||||
| struct Entry { | ||||
|     std::chrono::microseconds timestamp; | ||||
|     Class log_class{}; | ||||
|     Level log_level{}; | ||||
|     const char* filename = nullptr; | ||||
|     unsigned int line_num = 0; | ||||
|     std::string function; | ||||
|     std::string message; | ||||
|     bool final_entry = false; | ||||
| }; | ||||
| 
 | ||||
| } // namespace Common::Log
 | ||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue