LibQuicR
log.h
Go to the documentation of this file.
1 // SPDX-FileCopyrightText: Copyright (c) 2026 Cisco Systems
2 // SPDX-License-Identifier: BSD-2-Clause
3 
4 #pragma once
5 
7 
8 #include <memory>
9 #include <source_location>
10 #include <string_view>
11 #include <version>
12 
13 namespace quicr {
14 
15 #define QUICR_LOG_TRACE 0
16 #define QUICR_LOG_DEBUG 1
17 #define QUICR_LOG_INFO 2
18 #define QUICR_LOG_WARN 3
19 #define QUICR_LOG_ERROR 4
20 #define QUICR_LOG_CRITICAL 5
21 #define QUICR_LOG_OFF 6
22 
24  class Logger
25  {
26  public:
28  enum class Level
29  {
36  Off = QUICR_LOG_OFF,
37  };
38 
40  virtual ~Logger() = default;
41 
47  virtual void SetLevel(Level max_level) = 0;
48 
56  virtual void Log(Level level,
57  std::string_view msg,
58  std::source_location location = std::source_location::current()) = 0;
59 
66  virtual bool ShouldLog(Level level) const noexcept;
67 
79  template<typename... Args>
80  void Log(std::source_location location,
81  Level level,
82  std::conditional_t<sizeof...(Args) == 0, std::string_view, std_or_fmt::format_string<Args...>> msg,
83  Args&&... args)
84  try {
85  if (!ShouldLog(level)) {
86  return;
87  }
88 
89  if constexpr (sizeof...(Args) == 0) {
90  Log(level, msg, location);
91  } else {
92  Log(level, std_or_fmt::vformat(msg.get(), std_or_fmt::make_format_args(args...)), location);
93  }
94  } catch (const std::exception& e) {
95  Log(Level::Error, std_or_fmt::format("log failed to format (error={})", e.what()), location);
96  }
97  };
98 
99 #define QUICR_LOGGER_LOG(logger, level, msg, ...) \
100  do { \
101  if (logger) { \
102  logger->Log(std::source_location::current(), level, msg __VA_OPT__(, ) __VA_ARGS__); \
103  } \
104  } while (0)
105 
106 #ifndef QUICR_ACTIVE_LOG_LEVEL
107 #ifdef NDEBUG
108 #define QUICR_ACTIVE_LOG_LEVEL QUICR_LOG_INFO
109 #else
110 #define QUICR_ACTIVE_LOG_LEVEL QUICR_LOG_DEBUG
111 #endif
112 #endif
113 
114 #if QUICR_ACTIVE_LOG_LEVEL <= QUICR_LOG_TRACE
115 #define QUICR_LOGGER_TRACE(logger, msg, ...) \
116  QUICR_LOGGER_LOG(logger, quicr::Logger::Level::Trace, msg __VA_OPT__(, ) __VA_ARGS__)
117 #else
118 #define QUICR_LOGGER_TRACE(logger, msg, ...)
119 #endif
120 #if QUICR_ACTIVE_LOG_LEVEL <= QUICR_LOG_DEBUG
121 #define QUICR_LOGGER_DEBUG(logger, msg, ...) \
122  QUICR_LOGGER_LOG(logger, quicr::Logger::Level::Debug, msg __VA_OPT__(, ) __VA_ARGS__)
123 #else
124 #define QUICR_LOGGER_DEBUG(logger, msg, ...)
125 #endif
126 #if QUICR_ACTIVE_LOG_LEVEL <= QUICR_LOG_INFO
127 #define QUICR_LOGGER_INFO(logger, msg, ...) \
128  QUICR_LOGGER_LOG(logger, quicr::Logger::Level::Info, msg __VA_OPT__(, ) __VA_ARGS__)
129 #else
130 #define QUICR_LOGGER_INFO(logger, msg, ...)
131 #endif
132 #if QUICR_ACTIVE_LOG_LEVEL <= QUICR_LOG_WARN
133 #define QUICR_LOGGER_WARN(logger, msg, ...) \
134  QUICR_LOGGER_LOG(logger, quicr::Logger::Level::Warn, msg __VA_OPT__(, ) __VA_ARGS__)
135 #else
136 #define QUICR_LOGGER_WARN(logger, msg, ...)
137 #endif
138 #if QUICR_ACTIVE_LOG_LEVEL <= QUICR_LOG_ERROR
139 #define QUICR_LOGGER_ERROR(logger, msg, ...) \
140  QUICR_LOGGER_LOG(logger, quicr::Logger::Level::Error, msg __VA_OPT__(, ) __VA_ARGS__)
141 #else
142 #define QUICR_LOGGER_ERROR(logger, msg, ...)
143 #endif
144 #if QUICR_ACTIVE_LOG_LEVEL <= QUICR_LOG_CRITICAL
145 #define QUICR_LOGGER_CRITICAL(logger, msg, ...) \
146  QUICR_LOGGER_LOG(logger, quicr::Logger::Level::Critical, msg __VA_OPT__(, ) __VA_ARGS__)
147 #else
148 #define QUICR_LOGGER_CRITICAL(logger, msg, ...)
149 #endif
150 
151 }
Abstract sink for libquicr diagnostic messages.
Definition: log.h:25
Level
Log severity in increasing order.
Definition: log.h:29
@ Critical
A severe failure requiring immediate attention.
@ Info
Normal operational information.
@ Warn
A recoverable or potentially harmful condition.
@ Error
An operation failed.
@ Debug
Diagnostic information for debugging.
@ Off
Disable logging.
@ Trace
Fine-grained execution tracing.
virtual void SetLevel(Level max_level)=0
Set the minimum severity emitted by this logger.
virtual bool ShouldLog(Level level) const noexcept
Determine whether a message severity is enabled at compile time.
virtual ~Logger()=default
Destroy the logger.
virtual void Log(Level level, std::string_view msg, std::source_location location=std::source_location::current())=0
Emit an already formatted message.
void Log(std::source_location location, Level level, std::conditional_t< sizeof...(Args)==0, std::string_view, std_or_fmt::format_string< Args... >> msg, Args &&... args)
Format and emit a message if its severity is enabled.
Definition: log.h:80
#define QUICR_LOG_WARN
Definition: log.h:18
#define QUICR_LOG_DEBUG
Definition: log.h:16
#define QUICR_LOG_CRITICAL
Definition: log.h:20
#define QUICR_LOG_OFF
Definition: log.h:21
#define QUICR_LOG_INFO
Definition: log.h:17
#define QUICR_LOG_TRACE
Definition: log.h:15
#define QUICR_LOG_ERROR
Definition: log.h:19
Definition: attributes.h:13
std::string vformat(std::string_view msg, Args &&... args)
Formats arguments using a runtime format string.
Definition: format.h:45
std::string format(std_or_fmt::format_string< Args... > msg, Args &&... args)
Formats arguments using the configured std::format or {fmt} backend.
Definition: format.h:30
A rejected result, holding why the request was rejected.
Definition: errors.h:21