-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathlog.hxx
151 lines (128 loc) · 2.99 KB
/
log.hxx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
#ifndef LOG_HXX
#define LOG_HXX
#include <cstdio> // for std::FILE
#include <string_view>
#include <utility> // for std::forward
#include <fmt/core.h>
#include <project_dll-export.h>
namespace project::log {
/** @brief Logging severity level.
@code
-- More severe --
Level::Error
Level::Warning
Level::Info
Level::Debug
Level::Trace
-- Less severe --
@endcode
*/
enum class Level
{
None,
Error,
Warning,
Info,
Debug,
Trace,
};
namespace detail {
DLL extern Level LogLevel;
DLL extern std::FILE* LogTarget;
} // namespace detail
/** @brief Convert a string to a logging severity level.
@param level Options are: error warning info debug trace.
@return Corresponding Level or Level::None if \p level is invalid or empty.
std::string_view is constructible via e.g. cast from std::string const&
(std::basic_string::operator basic_string_view())
or via std::basic_string_view(char const* cstr) etc.
*/
DLL auto level_from(std::string_view level) -> Level;
/// Convert a logging severity level to a string.
auto constexpr level_label(Level level) -> std::string_view
{
switch (level) {
case Level::Error: return "Error";
case Level::Warning: return "Warning";
case Level::Info: return "Info";
case Level::Debug: return "Debug";
case Level::Trace: return "Trace";
default: return "None";
}
}
/// Set the global log level. Ignore messages less-severe than \p level.
DLL void set_level(Level level);
DLL auto get_level() -> Level;
/// Set the log output target.
DLL void set_target(std::FILE* target);
DLL auto get_target() -> std::FILE*;
/// Print all active log levels given the current global log level.
DLL void print_enabled_levels();
#ifndef ENABLE_LOGGING
#define ENABLE_LOGGING 0
#endif
/// Emit a log message.
template <typename... Args>
void print(Level level, Args&&... args)
{
#if ENABLE_LOGGING
if (detail::LogLevel >= level) {
fmt::print(detail::LogTarget, "{}: {}\n", level_label(level), fmt::format(std::forward<Args>(args)...));
}
#else
(void) level;
((void) args, ...);
#endif
}
/// Emit an error message.
template <typename... Args>
void error(Args&&... args)
{
#if ENABLE_LOGGING
print(Level::Error, std::forward<Args>(args)...);
#else
((void) args, ...);
#endif
}
/// Emit a warning message.
template <typename... Args>
void warning(Args&&... args)
{
#if ENABLE_LOGGING
print(Level::Warning, std::forward<Args>(args)...);
#else
((void) args, ...);
#endif
}
/// Emit an informational message.
template <typename... Args>
void info(Args&&... args)
{
#if ENABLE_LOGGING
print(Level::Info, std::forward<Args>(args)...);
#else
((void) args, ...);
#endif
}
/// Emit a debugging message.
template <typename... Args>
void debug(Args&&... args)
{
#if ENABLE_LOGGING
print(Level::Debug, std::forward<Args>(args)...);
#else
((void) args, ...);
#endif
}
/// Emit a trace message.
template <typename... Args>
void trace(Args&&... args)
{
#if ENABLE_LOGGING
print(Level::Trace, std::forward<Args>(args)...);
#else
((void) args, ...);
#endif
}
} // namespace project::log
#endif