log.h (4988B)
1 // SPDX-FileCopyrightText: 2019-2023 Connor McLaughlin <stenzek@gmail.com> 2 // SPDX-License-Identifier: (GPL-3.0 OR CC-BY-NC-ND-4.0) 3 4 #pragma once 5 6 #include "types.h" 7 8 #include "fmt/core.h" 9 10 #include <cinttypes> 11 #include <cstdarg> 12 #include <mutex> 13 #include <string_view> 14 15 enum LOGLEVEL 16 { 17 LOGLEVEL_NONE, // Silences all log traffic 18 LOGLEVEL_ERROR, 19 LOGLEVEL_WARNING, 20 LOGLEVEL_INFO, 21 LOGLEVEL_VERBOSE, 22 LOGLEVEL_DEV, 23 LOGLEVEL_DEBUG, 24 LOGLEVEL_TRACE, 25 26 LOGLEVEL_COUNT 27 }; 28 29 namespace Log { 30 // log message callback type 31 using CallbackFunctionType = void (*)(void* pUserParam, const char* channelName, const char* functionName, 32 LOGLEVEL level, std::string_view message); 33 34 // registers a log callback 35 void RegisterCallback(CallbackFunctionType callbackFunction, void* pUserParam); 36 37 // unregisters a log callback 38 void UnregisterCallback(CallbackFunctionType callbackFunction, void* pUserParam); 39 40 // returns the time in seconds since the start of the process 41 float GetCurrentMessageTime(); 42 43 // adds a standard console output 44 bool IsConsoleOutputEnabled(); 45 void SetConsoleOutputParams(bool enabled, bool timestamps = true); 46 47 // adds a debug console output [win32/android only] 48 bool IsDebugOutputEnabled(); 49 void SetDebugOutputParams(bool enabled); 50 51 // adds a file output 52 void SetFileOutputParams(bool enabled, const char* filename, bool timestamps = true); 53 54 // Returns the current global filtering level. 55 LOGLEVEL GetLogLevel(); 56 57 // Returns true if log messages for the specified log level/filter would not be filtered (and visible). 58 bool IsLogVisible(LOGLEVEL level, const char* channelName); 59 60 // Sets global filtering level, messages below this level won't be sent to any of the logging sinks. 61 void SetLogLevel(LOGLEVEL level); 62 63 // Sets global filter, any messages from these channels won't be sent to any of the logging sinks. 64 void SetLogFilter(std::string_view filter); 65 66 // writes a message to the log 67 void Write(const char* channelName, LOGLEVEL level, std::string_view message); 68 void Write(const char* channelName, const char* functionName, LOGLEVEL level, std::string_view message); 69 void WriteFmtArgs(const char* channelName, LOGLEVEL level, fmt::string_view fmt, fmt::format_args args); 70 void WriteFmtArgs(const char* channelName, const char* functionName, LOGLEVEL level, fmt::string_view fmt, 71 fmt::format_args args); 72 73 ALWAYS_INLINE static void FastWrite(const char* channelName, LOGLEVEL level, std::string_view message) 74 { 75 if (level <= GetLogLevel()) [[unlikely]] 76 Write(channelName, level, message); 77 } 78 ALWAYS_INLINE static void FastWrite(const char* channelName, const char* functionName, LOGLEVEL level, 79 std::string_view message) 80 { 81 if (level <= GetLogLevel()) [[unlikely]] 82 Write(channelName, functionName, level, message); 83 } 84 template<typename... T> 85 ALWAYS_INLINE static void FastWrite(const char* channelName, LOGLEVEL level, fmt::format_string<T...> fmt, T&&... args) 86 { 87 if (level <= GetLogLevel()) [[unlikely]] 88 WriteFmtArgs(channelName, level, fmt, fmt::make_format_args(args...)); 89 } 90 template<typename... T> 91 ALWAYS_INLINE static void FastWrite(const char* channelName, const char* functionName, LOGLEVEL level, 92 fmt::format_string<T...> fmt, T&&... args) 93 { 94 if (level <= GetLogLevel()) [[unlikely]] 95 WriteFmtArgs(channelName, functionName, level, fmt, fmt::make_format_args(args...)); 96 } 97 } // namespace Log 98 99 // log wrappers 100 #define Log_SetChannel(ChannelName) [[maybe_unused]] static const char* ___LogChannel___ = #ChannelName; 101 102 #define ERROR_LOG(...) Log::FastWrite(___LogChannel___, __func__, LOGLEVEL_ERROR, __VA_ARGS__) 103 #define WARNING_LOG(...) Log::FastWrite(___LogChannel___, __func__, LOGLEVEL_WARNING, __VA_ARGS__) 104 #define INFO_LOG(...) Log::FastWrite(___LogChannel___, LOGLEVEL_INFO, __VA_ARGS__) 105 #define VERBOSE_LOG(...) Log::FastWrite(___LogChannel___, LOGLEVEL_VERBOSE, __VA_ARGS__) 106 #define DEV_LOG(...) Log::FastWrite(___LogChannel___, LOGLEVEL_DEV, __VA_ARGS__) 107 108 #ifdef _DEBUG 109 #define DEBUG_LOG(...) Log::FastWrite(___LogChannel___, LOGLEVEL_DEBUG, __VA_ARGS__) 110 #define TRACE_LOG(...) Log::FastWrite(___LogChannel___, LOGLEVEL_TRACE, __VA_ARGS__) 111 #else 112 #define DEBUG_LOG(...) \ 113 do \ 114 { \ 115 } while (0) 116 #define TRACE_LOG(...) \ 117 do \ 118 { \ 119 } while (0) 120 #endif