quill
TransitEvent.h
1 
7 #pragma once
8 
9 #include "quill/core/Attributes.h"
10 #include "quill/core/Codec.h"
11 #include "quill/core/LogLevel.h"
12 #include "quill/core/MacroMetadata.h"
13 
14 #include "quill/bundled/fmt/format.h"
15 
16 #include <atomic>
17 #include <cstdint>
18 #include <memory>
19 #include <string>
20 #include <string_view>
21 #include <utility>
22 #include <vector>
23 
24 QUILL_BEGIN_NAMESPACE
25 
26 namespace detail
27 {
29 class LoggerBase;
30 
31 /***/
33 {
34  using FormatBuffer = fmtquill::basic_memory_buffer<char, 88>;
35 
36  /***/
37  TransitEvent() = default;
38 
39  /***/
40  ~TransitEvent() = default;
41 
45  TransitEvent(TransitEvent const& other) = delete;
46  TransitEvent& operator=(TransitEvent const& other) = delete;
47 
48  /***/
49  TransitEvent(TransitEvent&& other) noexcept
50  : timestamp(other.timestamp),
51  macro_metadata(other.macro_metadata),
52  logger_base(other.logger_base),
53  formatted_msg(std::move(other.formatted_msg)),
54  extra_data(std::move(other.extra_data)),
55  flush_flag(other.flush_flag)
56  {
57  // Update macro_metadata pointer if it was pointing to runtime_metadata
58  if (extra_data && extra_data->runtime_metadata.has_runtime_metadata)
59  {
60  // Point to our own runtime_metadata instead of the moved-from object's
61  macro_metadata = &extra_data->runtime_metadata.macro_metadata;
62  }
63  }
64 
65  /***/
66  TransitEvent& operator=(TransitEvent&& other) noexcept
67  {
68  if (this != &other)
69  {
70  timestamp = other.timestamp;
71  macro_metadata = other.macro_metadata;
72  logger_base = other.logger_base;
73  formatted_msg = std::move(other.formatted_msg);
74  extra_data = std::move(other.extra_data);
75  flush_flag = other.flush_flag;
76  }
77 
78  if (extra_data && extra_data->runtime_metadata.has_runtime_metadata)
79  {
80  // Point to our own runtime_metadata instead of the moved-from object's
81  macro_metadata = &extra_data->runtime_metadata.macro_metadata;
82  }
83 
84  return *this;
85  }
86 
87  /***/
88  void copy_to(TransitEvent& other) const
89  {
90  other.timestamp = timestamp;
91  other.macro_metadata = macro_metadata;
92  other.logger_base = logger_base;
93  other.flush_flag = flush_flag;
94 
95  // manually copy the fmt::buffer
96  other.formatted_msg->clear();
97  other.formatted_msg->reserve(formatted_msg->size());
98  other.formatted_msg->append(*formatted_msg);
99 
100  if (extra_data)
101  {
102  other.extra_data = std::make_unique<ExtraData>(*extra_data);
103 
104  if (other.extra_data->runtime_metadata.has_runtime_metadata)
105  {
106  // then point macro_metadata to the correct object
107  other.macro_metadata = &other.extra_data->runtime_metadata.macro_metadata;
108  }
109  }
110  }
111 
112  /***/
113  QUILL_NODISCARD QUILL_ATTRIBUTE_HOT LogLevel log_level() const noexcept
114  {
115  return macro_metadata->log_level();
116  }
117 
118  /***/
119  QUILL_NODISCARD QUILL_ATTRIBUTE_HOT std::vector<std::pair<std::string, std::string>>* get_named_args() const noexcept
120  {
121  return extra_data ? &extra_data->named_args : nullptr;
122  }
123 
124  /***/
125  QUILL_ATTRIBUTE_HOT void ensure_extra_data() noexcept
126  {
127  if (extra_data)
128  {
129  return;
130  }
131 
132  extra_data = std::make_unique<ExtraData>();
133  }
134 
136  {
137  RuntimeMetadata() = default;
138 
139  RuntimeMetadata(char const* file, uint32_t line, char const* function, char const* in_tags,
140  char const* in_fmt, LogLevel log_level)
141  : fmt(in_fmt),
142  source_location(_format_file_location(file, line)),
143  function_name(function),
144  tags(in_tags),
145  macro_metadata(source_location.data(), function_name.data(), fmt.data(),
146  tags.empty() ? nullptr : tags.data(), log_level, MacroMetadata::Event::Log),
147  has_runtime_metadata(true)
148  {
149  }
150 
151  RuntimeMetadata(RuntimeMetadata const& other)
152  : fmt(other.fmt),
153  source_location(other.source_location),
154  function_name(other.function_name),
155  tags(other.tags),
156  macro_metadata(source_location.data(), function_name.data(), fmt.data(),
157  tags.empty() ? nullptr : tags.data(), other.macro_metadata.log_level(),
158  MacroMetadata::Event::Log),
159  has_runtime_metadata(other.has_runtime_metadata)
160  {
161  // Recreate macro_metadata to point to our own strings
162  }
163 
164  RuntimeMetadata& operator=(RuntimeMetadata const& other)
165  {
166  if (this != &other)
167  {
168  fmt = other.fmt;
169  source_location = other.source_location;
170  function_name = other.function_name;
171  tags = other.tags;
172  has_runtime_metadata = other.has_runtime_metadata;
173 
174  // Recreate macro_metadata to point to our own strings
175  macro_metadata = MacroMetadata(source_location.data(), function_name.data(), fmt.data(),
176  tags.empty() ? nullptr : tags.data(),
177  other.macro_metadata.log_level(), MacroMetadata::Event::Log);
178  }
179  return *this;
180  }
181 
182  RuntimeMetadata(RuntimeMetadata&& other) noexcept = delete;
183  RuntimeMetadata& operator=(RuntimeMetadata&& other) noexcept = delete;
184 
185  std::string fmt;
186  std::string source_location;
187  std::string function_name;
188  std::string tags;
189  MacroMetadata macro_metadata;
190  bool has_runtime_metadata{false};
191 
192  private:
193  QUILL_NODISCARD static std::string _format_file_location(char const* file, uint32_t line)
194  {
195  if (!file || (file[0] == '\0' && line == 0))
196  {
197  return std::string{};
198  }
199 
200  // Format as "file:line"
201  return std::string{file} + ":" + std::to_string(line);
202  }
203  };
204 
205  struct ExtraData
206  {
207  // Additional fields that are used for some features as a separate structure to keep
208  // TransitEvent size smaller for the main scenarios
209  std::vector<std::pair<std::string, std::string>> named_args;
210  RuntimeMetadata runtime_metadata;
211  };
212 
213  uint64_t timestamp{0};
214  MacroMetadata const* macro_metadata{nullptr};
215  LoggerBase* logger_base{nullptr};
216  std::unique_ptr<FormatBuffer> formatted_msg{std::make_unique<FormatBuffer>()};
217  std::unique_ptr<ExtraData> extra_data;
218  std::atomic<bool>* flush_flag{nullptr};
219 };
220 } // namespace detail
221 
222 QUILL_END_NAMESPACE
std::unique_ptr< ExtraData > extra_data
buffer for message
Definition: TransitEvent.h:217
Definition: TransitEvent.h:32
Definition: TransitEvent.h:135
Captures and stores information about a logging event in compile time.
Definition: MacroMetadata.h:22
Setups a signal handler to handle fatal signals.
Definition: BackendManager.h:24
Definition: TransitEvent.h:205
Definition: LoggerBase.h:35
std::atomic< bool > * flush_flag
A unique ptr to save space as these fields not always used.
Definition: TransitEvent.h:218