quill
LoggerBase.h
1 
7 #pragma once
8 
9 #include "quill/core/Attributes.h"
10 #include "quill/core/Common.h"
11 #include "quill/core/LogLevel.h"
12 #include "quill/core/PatternFormatterOptions.h"
13 #include "quill/core/QuillError.h"
14 #include "quill/core/ThreadContextManager.h"
15 
16 #include <atomic>
17 #include <cassert>
18 #include <memory>
19 #include <string>
20 #include <vector>
21 
22 QUILL_BEGIN_NAMESPACE
23 
25 class Sink;
26 class PatternFormatter;
27 class UserClockSource;
28 
29 namespace detail
30 {
31 class BackendWorker;
32 class BacktraceStorage;
33 class LoggerManager;
34 
35 /***/
37 {
38 public:
39  /***/
40  LoggerBase(std::string logger_name, std::vector<std::shared_ptr<Sink>> sinks,
41  PatternFormatterOptions pattern_formatter_options, ClockSourceType clock_source,
42  UserClockSource* user_clock)
43  : _logger_name(static_cast<std::string&&>(logger_name)),
44  _user_clock(user_clock),
45  _clock_source(clock_source),
46  _pattern_formatter_options(static_cast<PatternFormatterOptions&&>(pattern_formatter_options))
47  {
48 #ifndef NDEBUG
49  for (auto const& sink : sinks)
50  {
51  assert(sink && "sink pointer is nullptr");
52  }
53 #endif
54 
55  this->_sinks = static_cast<std::vector<std::shared_ptr<Sink>>&&>(sinks);
56  }
57 
58  /***/
59  LoggerBase(LoggerBase const&) = delete;
60  LoggerBase& operator=(LoggerBase const&) = delete;
61 
62  /***/
63  virtual ~LoggerBase() = default;
64 
69  QUILL_NODISCARD std::string const& get_logger_name() const noexcept { return _logger_name; }
70 
75  QUILL_NODISCARD UserClockSource* get_user_clock_source() const noexcept { return _user_clock; }
76 
81  QUILL_NODISCARD ClockSourceType get_clock_source_type() const noexcept { return _clock_source; }
82 
87  QUILL_NODISCARD PatternFormatterOptions const& get_pattern_formatter_options() const noexcept
88  {
89  return _pattern_formatter_options;
90  }
91 
97  QUILL_NODISCARD std::vector<std::shared_ptr<Sink>> const& get_sinks() const noexcept
98  {
99  return _sinks;
100  }
101 
105  void mark_invalid() { _valid.store(false, std::memory_order_release); }
106 
111  QUILL_NODISCARD bool is_valid_logger() const noexcept
112  {
113  return _valid.load(std::memory_order_acquire);
114  }
115 
119  QUILL_NODISCARD LogLevel get_log_level() const noexcept
120  {
121  return _log_level.load(std::memory_order_relaxed);
122  }
123 
128  void set_log_level(LogLevel new_log_level)
129  {
130  if (QUILL_UNLIKELY(new_log_level == LogLevel::Backtrace))
131  {
132  QUILL_THROW(QuillError{"LogLevel::Backtrace is only used internally. Please don't use it."});
133  }
134 
135  _log_level.store(new_log_level, std::memory_order_relaxed);
136  }
137 
154  void set_immediate_flush(uint32_t flush_every_n_messages = 1)
155  {
156  _message_flush_threshold.store(flush_every_n_messages, std::memory_order_relaxed);
157  }
158 
163  template <LogLevel log_statement_level>
164  QUILL_NODISCARD QUILL_ATTRIBUTE_HOT bool should_log_statement() const noexcept
165  {
166  return log_statement_level >= get_log_level();
167  }
168 
174  QUILL_NODISCARD QUILL_ATTRIBUTE_HOT bool should_log_statement(LogLevel log_statement_level) const noexcept
175  {
176  return log_statement_level >= get_log_level();
177  }
178 
179 protected:
180  friend class BackendWorker;
181  friend class LoggerManager;
182 
183  static inline QUILL_THREAD_LOCAL ThreadContext* _thread_context = nullptr; /* Set and accessed by the frontend */
184 
185  // -- frontend access BEGIN --
186  std::string _logger_name; /* Set by the frontend once, accessed by the frontend AND backend */
187  UserClockSource* _user_clock{nullptr}; /* A non-owned pointer to a custom timestamp clock, valid only when provided. used by frontend only */
188  std::atomic<uint32_t> _message_flush_threshold{0}; /* used by frontend only */
189  std::atomic<uint32_t> _messages_since_last_flush{0}; /* used by frontend only */
190  ClockSourceType _clock_source; /* Set by the frontend and accessed by the frontend AND backend */
191  std::atomic<LogLevel> _log_level{LogLevel::Info}; /* used by frontend only */
192  std::atomic<LogLevel> _backtrace_flush_level{LogLevel::None};
193  std::atomic<bool> _valid{true}; /* Updated by the frontend at any time, accessed by the backend */
194  // -- frontend access END --
195 
196  PatternFormatterOptions _pattern_formatter_options; /* Set by the frontend once and accessed by the backend to initialise PatternFormatter */
197  std::vector<std::shared_ptr<Sink>> _sinks; /* Set by the frontend once and accessed by the backend */
198  std::shared_ptr<PatternFormatter> _pattern_formatter; /* The backend thread will set this once, we never access it on the frontend */
199  std::shared_ptr<BacktraceStorage> _backtrace_storage; /* The backend thread will construct this, we never access it on the frontend */
200 };
201 } // namespace detail
202 
203 QUILL_END_NAMESPACE
QUILL_NODISCARD QUILL_ATTRIBUTE_HOT bool should_log_statement() const noexcept
Checks if the given log_statement_level can be logged by this logger.
Definition: LoggerBase.h:164
QUILL_NODISCARD QUILL_ATTRIBUTE_HOT bool should_log_statement(LogLevel log_statement_level) const noexcept
Checks if the given log_statement_level can be logged by this logger.
Definition: LoggerBase.h:174
QUILL_NODISCARD std::string const & get_logger_name() const noexcept
Returns the name of the logger.
Definition: LoggerBase.h:69
std::atomic< bool > _valid
Updated by the frontend at any time, accessed by the backend.
Definition: LoggerBase.h:193
Base class for sinks.
Definition: Sink.h:40
QUILL_NODISCARD ClockSourceType get_clock_source_type() const noexcept
Returns the type of clock source being used.
Definition: LoggerBase.h:81
Definition: PatternFormatter.h:33
QUILL_NODISCARD PatternFormatterOptions const & get_pattern_formatter_options() const noexcept
Returns the pattern formatter options.
Definition: LoggerBase.h:87
QUILL_NODISCARD bool is_valid_logger() const noexcept
Checks if the logger is valid.
Definition: LoggerBase.h:111
Configuration options for the PatternFormatter.
Definition: PatternFormatterOptions.h:23
Setups a signal handler to handle fatal signals.
Definition: BackendManager.h:24
void set_immediate_flush(uint32_t flush_every_n_messages=1)
Sets the flush interval for logging based on message count.
Definition: LoggerBase.h:154
QUILL_NODISCARD std::vector< std::shared_ptr< Sink > > const & get_sinks() const noexcept
Returns a const reference to the sinks vector.
Definition: LoggerBase.h:97
Definition: LoggerBase.h:36
QUILL_NODISCARD LogLevel get_log_level() const noexcept
Definition: LoggerBase.h:119
custom exception
Definition: QuillError.h:45
void set_log_level(LogLevel new_log_level)
Set the log level of the logger.
Definition: LoggerBase.h:128
Base class that provides a timestamp for log statements based on a user-provided clock source...
Definition: UserClockSource.h:25
QUILL_NODISCARD UserClockSource * get_user_clock_source() const noexcept
Returns the user-defined clock source.
Definition: LoggerBase.h:75
Definition: BackendWorker.h:72
Definition: LoggerManager.h:34
void mark_invalid()
This function sets the logger&#39;s validity flag to false, indicating that the logger is no longer valid...
Definition: LoggerBase.h:105
Definition: ThreadContextManager.h:48