OGLplus  (0.59.0) a C++ wrapper for rendering APIs

logger.hpp
Go to the documentation of this file.
1 
9 #ifndef EAGINE_LOGGING_LOGGER_HPP
10 #define EAGINE_LOGGING_LOGGER_HPP
11 
12 #include "../tagged_quantity.hpp"
13 #include "config.hpp"
14 #include "entry.hpp"
15 
16 namespace eagine {
17 //------------------------------------------------------------------------------
18 class logger_shared_backend_getter {
19  using This = logger_shared_backend_getter;
20 
21 public:
22  logger_shared_backend_getter() noexcept = default;
23  logger_shared_backend_getter(This&&) noexcept = default;
24  logger_shared_backend_getter(const This&) noexcept = default;
25  auto operator=(This&&) = delete;
26  auto operator=(const This&) = delete;
27 
28  ~logger_shared_backend_getter() noexcept = default;
29 
30  logger_shared_backend_getter(
31  std::shared_ptr<logger_backend> backend) noexcept
32  : _backend{std::move(backend)} {}
33 
34  auto operator()() noexcept -> logger_backend* {
35  return _backend.get();
36  }
37 
38 private:
39  std::shared_ptr<logger_backend> _backend{};
40 };
41 //------------------------------------------------------------------------------
44 template <typename BackendGetter>
45 class basic_logger : protected BackendGetter {
46 public:
50  template <log_event_severity severity>
51  using entry_type = std::
52  conditional_t<is_log_level_enabled_v<severity>, log_entry, no_log_entry>;
53 
55  auto backend() noexcept {
56  return _backend_getter()();
57  }
58 
60  auto instance_id() const noexcept -> logger_instance_id {
61  return reinterpret_cast<logger_instance_id>(this);
62  }
63 
64  auto configure(application_config& config) -> bool {
65  if(auto lbe{backend()}) {
66  extract(lbe).configure(config);
67  }
68  return false;
69  }
70 
71 protected:
72  basic_logger() noexcept = default;
73 
74  basic_logger(BackendGetter backend_getter) noexcept(
75  std::is_nothrow_move_constructible_v<BackendGetter>)
76  : BackendGetter(std::move(backend_getter)) {}
77 
78  void set_description(
79  identifier source,
80  string_view display_name,
81  string_view description) noexcept {
82  if(auto lbe{backend()}) {
83  extract(lbe).set_description(
84  source, instance_id(), display_name, description);
85  }
86  }
87 
88  auto make_log_entry(
89  identifier source,
90  log_event_severity severity,
91  std::true_type,
92  string_view format) noexcept -> log_entry {
93  return {
94  source,
95  instance_id(),
96  severity,
97  format,
98  _entry_backend(source, severity)};
99  }
100 
101  constexpr auto make_log_entry(
102  identifier,
104  std::false_type,
105  string_view) noexcept -> no_log_entry {
106  return {};
107  }
108 
109  template <log_event_severity severity>
110  constexpr auto make_log_entry(
111  identifier source,
112  log_event_severity_constant<severity>,
113  string_view format) noexcept -> entry_type<severity> {
114  return make_log_entry(
115  source, severity, is_log_level_enabled_t<severity>{}, format);
116  }
117 
118  auto make_log_entry(
119  identifier source,
120  log_event_severity severity,
121  string_view format) noexcept -> log_entry {
122  return {
123  source,
124  instance_id(),
125  severity,
126  format,
127  _entry_backend(source, severity)};
128  }
129 
130  constexpr auto log_fatal(identifier source, string_view format) noexcept {
131  return make_log_entry(
132  source,
133  log_event_severity_constant<log_event_severity::fatal>{},
134  format);
135  }
136 
137  constexpr auto log_error(identifier source, string_view format) noexcept {
138  return make_log_entry(
139  source,
140  log_event_severity_constant<log_event_severity::error>{},
141  format);
142  }
143 
144  constexpr auto log_warning(identifier source, string_view format) noexcept {
145  return make_log_entry(
146  source,
147  log_event_severity_constant<log_event_severity::warning>{},
148  format);
149  }
150 
151  constexpr auto log_info(identifier source, string_view format) noexcept {
152  return make_log_entry(
153  source,
154  log_event_severity_constant<log_event_severity::info>{},
155  format);
156  }
157 
158  constexpr auto log_stat(identifier source, string_view format) noexcept {
159  return make_log_entry(
160  source,
161  log_event_severity_constant<log_event_severity::stat>{},
162  format);
163  }
164 
165  auto log_debug(identifier source, string_view format) noexcept {
166  return make_log_entry(
167  source,
168  log_event_severity_constant<log_event_severity::debug>{},
169  format);
170  }
171 
172  auto log_trace(identifier source, string_view format) noexcept {
173  return make_log_entry(
174  source,
175  log_event_severity_constant<log_event_severity::trace>{},
176  format);
177  }
178 
179  auto log_backtrace(identifier source, string_view format) noexcept {
180  return make_log_entry(
181  source,
182  log_event_severity_constant<log_event_severity::backtrace>{},
183  format);
184  }
185 
186  auto log_lifetime(identifier source, string_view format) noexcept {
187  // TODO: switch depending on Debug/Release ?
188  return log_info(source, format);
189  }
190 
191  auto make_log_stream(identifier source, log_event_severity severity) noexcept
192  -> stream_log_entry {
193  return {
194  source, instance_id(), severity, _entry_backend(source, severity)};
195  }
196 
197  void log_chart_sample(
198  identifier source,
199  identifier series,
200  float value) noexcept {
201  EAGINE_MAYBE_UNUSED(source);
202  EAGINE_MAYBE_UNUSED(series);
203  EAGINE_MAYBE_UNUSED(value);
204  if constexpr(is_log_level_enabled_v<log_event_severity::stat>) {
205  if(auto lbe{_entry_backend(source, log_event_severity::stat)}) {
206  extract(lbe).log_chart_sample(
207  source, instance_id(), series, value);
208  }
209  }
210  }
211 
212  auto _entry_backend(identifier source, log_event_severity severity) noexcept
213  -> logger_backend* {
214  if(is_log_level_enabled(severity)) {
215  if(auto lbe{backend()}) {
216  return lbe->entry_backend(source, severity);
217  }
218  }
219  return nullptr;
220  }
221 
222 private:
223  auto _backend_getter() noexcept -> BackendGetter& {
224  return *this;
225  }
226 };
227 //------------------------------------------------------------------------------
234 template <typename BackendGetter>
235 class named_logging_object : public basic_logger<BackendGetter> {
237 
238 public:
242  template <log_event_severity severity>
243  using entry_type = std::
244  conditional_t<is_log_level_enabled_v<severity>, log_entry, no_log_entry>;
245 
246  using base::log_lifetime;
247 
250  named_logging_object(identifier id, BackendGetter backend_getter) noexcept
251  : base(BackendGetter(std::move(backend_getter)))
252  , _object_id{id} {
253  log_lifetime(_object_id, "${self} created with ${backend} backend")
254  .arg(EAGINE_ID(backend), this->backend())
255  .arg(EAGINE_ID(self), EAGINE_ID(LogId), _object_id);
256  }
257 
260  identifier id,
261  const named_logging_object& parent) noexcept
262  : base(static_cast<const base&>(parent))
263  , _object_id{id} {
264  log_lifetime(_object_id, "created as a child of ${parent}")
265  .arg(EAGINE_ID(parent), EAGINE_ID(LogId), parent._object_id);
266  }
267 
269  named_logging_object() noexcept = default;
270 
273  : base(static_cast<base&&>(temp))
274  , _object_id{temp._object_id} {
275  log_lifetime(_object_id, "being moved");
276  }
277 
280  : base(static_cast<const base&>(that))
281  , _object_id{that._object_id} {
282  log_lifetime(_object_id, "being copied");
283  }
284 
286  auto operator=(named_logging_object&&) noexcept
287  -> named_logging_object& = default;
288 
290  auto operator=(const named_logging_object&)
291  -> named_logging_object& = default;
292 
293  ~named_logging_object() noexcept {
294  log_lifetime(_object_id, "being destroyed");
295  }
296 
298  constexpr auto object_id() const noexcept {
299  return _object_id;
300  }
301 
304  string_view display_name,
305  string_view description) noexcept {
306  base::set_description(_object_id, display_name, description);
307  }
308 
311  auto log_fatal(string_view format) noexcept {
312  return base::log_fatal(_object_id, format);
313  }
314 
317  auto log_error(string_view format) noexcept {
318  return base::log_error(_object_id, format);
319  }
320 
323  auto log_warning(string_view format) noexcept {
324  return base::log_warning(_object_id, format);
325  }
326 
329  auto log_info(string_view format) noexcept {
330  return base::log_info(_object_id, format);
331  }
332 
335  auto log_stat(string_view format) noexcept {
336  return base::log_stat(_object_id, format);
337  }
338 
341  auto log_debug(string_view format) noexcept {
342  return base::log_debug(_object_id, format);
343  }
344 
347  auto log_trace(string_view format) noexcept {
348  return base::log_trace(_object_id, format);
349  }
350 
354  return base::log_backtrace(_object_id, format);
355  }
356 
360  auto log_debug_stream() noexcept {
361  return make_log_stream(log_event_severity::debug);
362  }
363 
367  auto log_error_stream() noexcept {
368  return make_log_stream(log_event_severity::error);
369  }
370 
372  auto log_chart_sample(identifier series, float value) noexcept
374  base::log_chart_sample(_object_id, series, value);
375  return *this;
376  }
377 
379  template <typename T, typename U>
381  identifier series,
382  const tagged_quantity<T, U>& qty) noexcept
383  -> std::enable_if_t<std::is_convertible_v<T, float>, named_logging_object&> {
384  log_chart_sample(series, qty.value());
385  return *this;
386  }
387 
389  template <typename T, typename P>
391  identifier series,
392  const valid_if<T, P>& opt_value) noexcept -> named_logging_object& {
393  if(opt_value) {
394  base::log_chart_sample(
395  _object_id, series, float(extract(opt_value)));
396  }
397  return *this;
398  }
399 
400 protected:
401  template <log_event_severity severity>
402  auto make_log_entry(
403  identifier tag,
405  string_view format) noexcept -> entry_type<severity> {
406  return base::make_log_entry(_object_id, tag, level, format);
407  }
408 
409  auto make_log_entry(log_event_severity severity, string_view format) noexcept
410  -> log_entry {
411  return base::make_log_entry(_object_id, severity, format);
412  }
413 
414  auto make_log_stream(log_event_severity severity) noexcept {
415  return base::make_log_stream(_object_id, severity);
416  }
417 
418 private:
419  identifier _object_id{EAGINE_ID(Object)};
420 };
421 //------------------------------------------------------------------------------
427 class logger : public named_logging_object<logger_shared_backend_getter> {
429 
430 public:
442  template <log_event_severity severity>
443  auto log(
446  return make_log_entry(level, format);
447  }
448 
459  auto log(log_event_severity severity, string_view format) noexcept {
460  return make_log_entry(severity, format);
461  }
462 
466  auto debug_stream() noexcept {
467  return log_debug_stream();
468  }
469 
473  auto error_stream() noexcept {
474  return log_error_stream();
475  }
476 
478  auto chart_sample(identifier series, float value) noexcept -> logger& {
479  base::log_chart_sample(series, value);
480  return *this;
481  }
482 
484  template <typename T, typename U>
485  auto
487  -> std::enable_if_t<std::is_convertible_v<T, float>, logger&> {
488  log_chart_sample(series, qty.value());
489  return *this;
490  }
491 
493  template <typename T, typename P>
494  auto
495  chart_sample(identifier series, const valid_if<T, P>& opt_value) noexcept
496  -> logger& {
497  if(opt_value) {
498  base::log_chart_sample(series, float(extract(opt_value)));
499  }
500  return *this;
501  }
502 
506  auto fatal(string_view format) noexcept {
507  return log_fatal(format);
508  }
509 
513  auto error(string_view format) noexcept {
514  return log_error(format);
515  }
516 
520  auto warning(string_view format) noexcept {
521  return log_warning(format);
522  }
523 
527  auto info(string_view format) noexcept {
528  return log_info(format);
529  }
530 
534  auto stat(string_view format) noexcept {
535  return log_stat(format);
536  }
537 
541  auto debug(string_view format) noexcept {
542  return log_debug(format);
543  }
544 
548  auto trace(string_view format) noexcept {
549  return log_trace(format);
550  }
551 
555  auto backtrace(string_view format) noexcept {
556  return log_backtrace(format);
557  }
558 
559  using base::base;
560 };
561 //------------------------------------------------------------------------------
562 } // namespace eagine
563 
564 #endif // EAGINE_LOGGING_LOGGER_HPP
auto log_debug(string_view format) noexcept
Create a log message entry for debugging, with specified format.
Definition: logger.hpp:341
auto debug(string_view format) noexcept
Returns a debugging log entry.
Definition: logger.hpp:541
basic_string_span< const char > string_view
Alias for const string views.
Definition: string_span.hpp:116
#define EAGINE_ID(NAME)
Macro for constructing instances of eagine::identifier.
Definition: identifier.hpp:353
auto log_warning(string_view format) noexcept
Create a log message entry for warning, with specified format.
Definition: logger.hpp:323
Basic template for logging objects.
Definition: logger.hpp:235
auto debug_stream() noexcept
Returns a log entry stream for debug messages.
Definition: logger.hpp:466
auto fatal(string_view format) noexcept
Returns a fatal error log entry.
Definition: logger.hpp:506
Common code is placed in this namespace.
Definition: eagine.hpp:21
auto instance_id() const noexcept -> logger_instance_id
Returns the unique id of this logger instance.
Definition: logger.hpp:60
auto chart_sample(identifier series, const tagged_quantity< T, U > &qty) noexcept -> std::enable_if_t< std::is_convertible_v< T, float >, logger & >
Stores a new value in the specified chart data series.
Definition: logger.hpp:486
std::uintptr_t logger_instance_id
Logger object instance id type.
Definition: backend.hpp:56
Class for reading application configuration.
Definition: application_config.hpp:29
named_logging_object(identifier id, BackendGetter backend_getter) noexcept
Constructor from identifier and backend_getter object.
Definition: logger.hpp:250
auto chart_sample(identifier series, const valid_if< T, P > &opt_value) noexcept -> logger &
Stores a new value in the specified chart data series.
Definition: logger.hpp:495
static constexpr auto extract(api_result_value< Result, api_result_validity::never > &) noexcept -> Result &
Overload of extract for api_result_value.
Definition: c_api_wrap.hpp:270
auto log_trace(string_view format) noexcept
Create a log message entry for tracing, with specified format.
Definition: logger.hpp:347
auto log_chart_sample(identifier series, float value) noexcept -> named_logging_object &
Stores a new value in the specified chart data series.
Definition: logger.hpp:372
static constexpr auto is_log_level_enabled(log_event_severity severity) noexcept -> bool
Function indicating if the specified log severity is enabled.
Definition: config.hpp:59
auto operator=(named_logging_object &&) noexcept -> named_logging_object &=default
Move assignment operator.
named_logging_object(const named_logging_object &that) noexcept
Copy constructor.
Definition: logger.hpp:279
@ error
Error log entries, indicating serious problems.
named_logging_object() noexcept=default
Construct logging object without backend.
auto log_stat(string_view format) noexcept
Create a log message entry for statistic, with specified format.
Definition: logger.hpp:335
auto log_info(string_view format) noexcept
Create a log message entry for information, with specified format.
Definition: logger.hpp:329
auto log_debug_stream() noexcept
Returns a log entry stream for debug messages.
Definition: logger.hpp:360
auto error_stream() noexcept
Returns a log entry stream for error messages.
Definition: logger.hpp:473
static auto format(std::string &&fmt_str) noexcept -> format_string_and_list< 0 >
Function taking a format string, returning an object for variable specification.
Definition: str_format.hpp:118
auto info(string_view format) noexcept
Returns an informational log entry.
Definition: logger.hpp:527
auto backend() noexcept
Returns a pointer to the backend of this logger object.
Definition: logger.hpp:55
@ debug
Debug log entries.
auto log_fatal(string_view format) noexcept
Create a log message entry for fatal error, with specified format.
Definition: logger.hpp:311
auto trace(string_view format) noexcept
Returns a tracing log entry.
Definition: logger.hpp:548
Do-nothing variant of log_entry with compatible API.
Definition: entry.hpp:606
auto error(string_view format) noexcept
Returns an error log entry.
Definition: logger.hpp:513
std::integral_constant< log_event_severity, severity > log_event_severity_constant
Type alias for log event severity constants.
Definition: config.hpp:34
std::conditional_t< is_log_level_enabled_v< severity >, log_entry, no_log_entry > entry_type
The entry type for the specified log_event_severity.
Definition: logger.hpp:52
named_logging_object(identifier id, const named_logging_object &parent) noexcept
Constructor from logger id and parent logging object.
Definition: logger.hpp:259
auto chart_sample(identifier series, float value) noexcept -> logger &
Stores a new value in the specified chart data series.
Definition: logger.hpp:478
void object_description(string_view display_name, string_view description) noexcept
Sets the human-readable name and description of this object.
Definition: logger.hpp:303
log_event_severity
Log event severity enumeration.
Definition: severity.hpp:18
constexpr auto object_id() const noexcept
Returns the identifier of this logging object.
Definition: logger.hpp:298
constexpr auto value() const noexcept -> T
Returns the value.
Definition: tagged_quantity.hpp:69
auto log_backtrace(string_view format) noexcept
Create a log message entry for backtracing, with specified format.
Definition: logger.hpp:353
auto log_chart_sample(identifier series, const tagged_quantity< T, U > &qty) noexcept -> std::enable_if_t< std::is_convertible_v< T, float >, named_logging_object & >
Stores a new value in the specified chart data series.
Definition: logger.hpp:380
Class representing a single log entry / message.
Definition: entry.hpp:67
auto stat(string_view format) noexcept
Returns a statistic log entry.
Definition: logger.hpp:534
auto log_error_stream() noexcept
Returns a log entry stream for error messages.
Definition: logger.hpp:367
auto log_chart_sample(identifier series, const valid_if< T, P > &opt_value) noexcept -> named_logging_object &
Stores a new value in the specified chart data series.
Definition: logger.hpp:390
auto log(log_event_severity severity, string_view format) noexcept
Returns a log entry with the specified log_event_severity.
Definition: logger.hpp:459
@ stat
Statistic log entries.
auto log(log_event_severity_constant< severity > level, string_view format) noexcept -> entry_type< severity >
Returns a log entry with the specified log_event_severity level.
Definition: logger.hpp:443
Standalone logger object type.
Definition: logger.hpp:427
auto warning(string_view format) noexcept
Returns a warning log entry.
Definition: logger.hpp:520
Value of type T with a specified unit or tag type U.
Definition: tagged_quantity.hpp:27
auto backtrace(string_view format) noexcept
Returns a backtracing log entry.
Definition: logger.hpp:555
basic_identifier< 10, 6, default_identifier_char_set, identifier_t > identifier
Default identifier type used throughout the project.
Definition: identifier.hpp:346
auto log_error(string_view format) noexcept
Create a log message entry for error, with specified format.
Definition: logger.hpp:317
Basic template for logger objects.
Definition: logger.hpp:45

Copyright © 2015-2021 Matúš Chochlík.
<chochlik -at -gmail.com>
Documentation generated on Tue Apr 13 2021 by Doxygen (version 1.8.17).