Avara3D 0.2.0
C++ API reference
Log.h
1//
2// Log.h
3// avara3d
4//
5// Created by Morgan Davis on 1/5/18.
6// Copyright © 2026 Morgan K Davis. All rights reserved.
7//
8
9#ifndef A3D_LOG_LOG_H
10#define A3D_LOG_LOG_H
11
12#include <format>
13#include <memory>
14#include <optional>
15#include <source_location>
16#include <string>
17#include <string_view>
18#include <tuple>
19#include <utility>
20#include <vector>
21
22namespace a3d::log {
23
24 class Log;
25 class LogSink;
26
27 // [Public Types]
28
30 enum class Level : uint8_t {
31 Trace = 0,
32 Debug = 1,
33 Info = 2,
34 Warn = 3,
35 Error = 4,
36 Fatal = 5,
37 Off = 6
38 };
39
40 // [Public Functions]
41
43 Log& AppLog();
44
46 void AppLog(std::unique_ptr<Log> log);
47
49 Log& MainLog();
50
57 class Log {
58
59 public:
60 // [Internal Types]
61
62 struct SourceInfo {
63 std::string_view filename;
64 unsigned line;
65 std::string_view function;
66 };
67
68 class Entry {
69 public:
70 Entry(Log& logger, Level lvl, SourceInfo src);
71
72 void operator()(std::string_view msg) const;
73
74 template<class... Args>
75 void operator()(std::format_string<Args...> fmt, Args&&... args) const {
76 nl(fmt, std::forward<Args>(args)...);
77 }
78
79 void nl(std::string_view msg) const;
80
81 template<class... Args>
82 void nl(std::format_string<Args...> fmt, Args&&... args) const
83 requires(sizeof...(Args) > 0)
84 {
85 nlf(fmt, std::forward<Args>(args)...);
86 }
87
88 template<class... Args>
89 void nlf(std::format_string<Args...> fmt, Args&&... args) const {
90 if (!_logger->enabled(_level)) {
91 return;
92 }
93 _logger->log(_level, _source, std::format(fmt, std::forward<Args>(args)...));
94 }
95
96 void raw(std::string_view msg) const;
97
98 template<class... Args>
99 void raw(std::format_string<Args...> fmt, Args&&... args) const
100 requires(sizeof...(Args) > 0)
101 {
102 rawf(fmt, std::forward<Args>(args)...);
103 }
104
105 template<class... Args>
106 void rawf(std::format_string<Args...> fmt, Args&&... args) const {
107 if (!_logger->enabled(_level)) {
108 return;
109 }
110 _logger->write(_level, _source, std::format(fmt, std::forward<Args>(args)...));
111 }
112
113 private:
114 Log* _logger;
115 Level _level;
116 SourceInfo _source;
117 };
118
119 // [Public Lifecycle Functions]
120
123
129 Log(const std::string& name,
130 std::unique_ptr<LogSink> sink,
131 Level level = DEFAULT_LEVEL,
132 Level flushLevel = DEFAULT_FLUSH_LEVEL);
133
135 Log(const std::string& name,
136 std::vector<std::unique_ptr<LogSink>> sinks,
137 Level level = DEFAULT_LEVEL,
138 Level flushLevel = DEFAULT_FLUSH_LEVEL);
139
140 Log(const Log& other) = delete;
141 Log& operator=(const Log& other) = delete;
142
143 Log(Log&&) = delete;
144 Log& operator=(Log&&) = delete;
145
146 ~Log();
147
148 // [Public Member Functions]
149
151 const std::string& name() const;
152
154 const std::vector<std::unique_ptr<LogSink>>& sinks() const;
155
157 Level level() const;
158
160 void level(Level level);
161
163 Level flushLevel() const;
164
167
169 void trace(const std::string& msg);
170
172 void debug(const std::string& msg);
173
175 void info(const std::string& msg);
176
178 void warn(const std::string& msg);
179
181 void error(const std::string& msg);
182
184 void fatal(const std::string& msg);
185
187 void flush();
188
189 // [Internal Member Functions]
190
191 void log(Level level, const SourceInfo& sourceInfo, const std::string& msg);
192
193 Entry trace(std::source_location where = std::source_location::current());
194 Entry debug(std::source_location where = std::source_location::current());
195 Entry info(std::source_location where = std::source_location::current());
196 Entry warn(std::source_location where = std::source_location::current());
197 Entry error(std::source_location where = std::source_location::current());
198 Entry fatal(std::source_location where = std::source_location::current());
199
200 void write(Level level, const SourceInfo& sourceInfo, std::string_view msg);
201 void write(Level level, std::string_view msg);
202
203 private:
204 // [Private Static Member Functions]
205
206 static std::string_view Basename(std::string_view p);
207 static std::string_view ShortFunction(std::string_view s, int keepScopes = 2);
208 static SourceInfo MakeSourceInfo(const std::source_location& where);
209
210 // [Private Lifecycle]
211
212 Log(const std::string& name);
213
214 // [Private Member Functions]
215
216 void log(Level level, const std::string& msg);
217 void dispatch(Level level, std::string& output);
218
219 bool enabled(Level lvl) const;
220
221 // [Private Constants]
222
223 static constexpr Level DEFAULT_LEVEL = Level::Debug;
224 static constexpr Level DEFAULT_FLUSH_LEVEL = Level::Warn;
225
226 // [Private Member Variables]
227
228 std::string _name;
229 std::vector<std::unique_ptr<LogSink>> _sinks;
230 Level _level;
231 Level _flushLevel;
232 };
233
234 // [Public Functions]
235
252 inline Log::Entry t(std::source_location where = std::source_location::current()) {
253 return MainLog().trace(where);
254 }
255
257 inline Log::Entry d(std::source_location where = std::source_location::current()) {
258 return MainLog().debug(where);
259 }
260
262 inline Log::Entry i(std::source_location where = std::source_location::current()) {
263 return MainLog().info(where);
264 }
265
267 inline Log::Entry w(std::source_location where = std::source_location::current()) {
268 return MainLog().warn(where);
269 }
270
272 inline Log::Entry e(std::source_location where = std::source_location::current()) {
273 return MainLog().error(where);
274 }
275
277 inline Log::Entry f(std::source_location where = std::source_location::current()) {
278 return MainLog().fatal(where);
279 }
280
283 namespace app {
284
285 // [Public Functions]
286
302 inline Log::Entry t(std::source_location where = std::source_location::current()) {
303 return AppLog().trace(where);
304 }
305
307 inline Log::Entry d(std::source_location where = std::source_location::current()) {
308 return AppLog().debug(where);
309 }
310
312 inline Log::Entry i(std::source_location where = std::source_location::current()) {
313 return AppLog().info(where);
314 }
315
317 inline Log::Entry w(std::source_location where = std::source_location::current()) {
318 return AppLog().warn(where);
319 }
320
322 inline Log::Entry e(std::source_location where = std::source_location::current()) {
323 return AppLog().error(where);
324 }
325
327 inline Log::Entry f(std::source_location where = std::source_location::current()) {
328 return AppLog().fatal(where);
329 }
330
333 } // namespace app
334
335} // namespace a3d::log
336
337#endif // A3D_LOG_LOG_H
Dispatches severity-filtered log messages to one or more LogSink objects.
Definition: Log.h:57
Log(const std::string &name, std::unique_ptr< LogSink > sink, Level level=DEFAULT_LEVEL, Level flushLevel=DEFAULT_FLUSH_LEVEL)
Creates a named Log that takes ownership of sink.
void fatal(const std::string &msg)
Emits msg at Fatal severity when enabled.
Level level() const
Returns the minimum severity currently emitted by the Log.
Log()
Creates an unnamed Log with default thresholds and no sinks.
void debug(const std::string &msg)
Emits msg at Debug severity when enabled.
void level(Level level)
Sets the minimum emitted severity; Level::Off disables message emission.
void error(const std::string &msg)
Emits msg at Error severity when enabled.
const std::vector< std::unique_ptr< LogSink > > & sinks() const
Returns the sinks owned by the Log.
Log(const std::string &name, std::vector< std::unique_ptr< LogSink > > sinks, Level level=DEFAULT_LEVEL, Level flushLevel=DEFAULT_FLUSH_LEVEL)
Creates a named Log that takes ownership of sinks.
void trace(const std::string &msg)
Emits msg at Trace severity when enabled.
void flushLevel(Level flushLevel)
Sets the severity threshold that triggers an automatic sink flush.
const std::string & name() const
Returns the name included in formatted log output.
void flush()
Flushes every owned sink.
Level flushLevel() const
Returns the severity threshold that triggers an automatic sink flush.
void warn(const std::string &msg)
Emits msg at Warn severity when enabled.
void info(const std::string &msg)
Emits msg at Info severity when enabled.