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->reserve(formatted_msg->size());
97  other.formatted_msg->append(*formatted_msg);
98 
99  if (extra_data)
100  {
101  other.extra_data = std::make_unique<ExtraData>(*extra_data);
102 
103  if (other.extra_data->runtime_metadata.has_runtime_metadata)
104  {
105  // then point macro_metadata to the correct object
106  other.macro_metadata = &other.extra_data->runtime_metadata.macro_metadata;
107  }
108  }
109  }
110 
111  /***/
112  QUILL_NODISCARD QUILL_ATTRIBUTE_HOT LogLevel log_level() const noexcept
113  {
114  return macro_metadata->log_level();
115  }
116 
117  /***/
118  QUILL_NODISCARD QUILL_ATTRIBUTE_HOT std::vector<std::pair<std::string, std::string>>* get_named_args() const noexcept
119  {
120  return extra_data ? &extra_data->named_args : nullptr;
121  }
122 
123  /***/
124  QUILL_ATTRIBUTE_HOT void ensure_extra_data() noexcept
125  {
126  if (extra_data)
127  {
128  return;
129  }
130 
131  extra_data = std::make_unique<ExtraData>();
132  }
133 
135  {
136  RuntimeMetadata() = default;
137 
138  RuntimeMetadata(char const* file, uint32_t line, char const* function, char const* in_tags,
139  char const* in_fmt, LogLevel log_level)
140  : fmt(in_fmt),
141  source_location(_format_file_location(file, line)),
142  function_name(function),
143  tags(in_tags),
144  macro_metadata(source_location.data(), function_name.data(), fmt.data(),
145  tags.empty() ? nullptr : tags.data(), log_level, MacroMetadata::Event::Log),
146  has_runtime_metadata(true)
147  {
148  }
149 
150  RuntimeMetadata(RuntimeMetadata const& other)
151  : fmt(other.fmt),
152  source_location(other.source_location),
153  function_name(other.function_name),
154  tags(other.tags),
155  macro_metadata(source_location.data(), function_name.data(), fmt.data(),
156  tags.empty() ? nullptr : tags.data(), other.macro_metadata.log_level(),
157  MacroMetadata::Event::Log),
158  has_runtime_metadata(other.has_runtime_metadata)
159  {
160  // Recreate macro_metadata to point to our own strings
161  }
162 
163  RuntimeMetadata& operator=(RuntimeMetadata const& other)
164  {
165  if (this != &other)
166  {
167  fmt = other.fmt;
168  source_location = other.source_location;
169  function_name = other.function_name;
170  tags = other.tags;
171  has_runtime_metadata = other.has_runtime_metadata;
172 
173  // Recreate macro_metadata to point to our own strings
174  macro_metadata = MacroMetadata(source_location.data(), function_name.data(), fmt.data(),
175  tags.empty() ? nullptr : tags.data(),
176  other.macro_metadata.log_level(), MacroMetadata::Event::Log);
177  }
178  return *this;
179  }
180 
181  RuntimeMetadata(RuntimeMetadata&& other) noexcept = delete;
182  RuntimeMetadata& operator=(RuntimeMetadata&& other) noexcept = delete;
183 
184  std::string fmt;
185  std::string source_location;
186  std::string function_name;
187  std::string tags;
188  MacroMetadata macro_metadata;
189  bool has_runtime_metadata{false};
190 
191  private:
192  QUILL_NODISCARD static std::string _format_file_location(char const* file, uint32_t line)
193  {
194  if (!file || (file[0] == '\0' && line == 0))
195  {
196  return std::string{};
197  }
198 
199  // Format as "file:line"
200  return std::string{file} + ":" + std::to_string(line);
201  }
202  };
203 
204  struct ExtraData
205  {
206  // Additional fields that are used for some features as a separate structure to keep
207  // TransitEvent size smaller for the main scenarios
208  std::vector<std::pair<std::string, std::string>> named_args;
209  RuntimeMetadata runtime_metadata;
210  };
211 
212  uint64_t timestamp{0};
213  MacroMetadata const* macro_metadata{nullptr};
214  LoggerBase* logger_base{nullptr};
215  std::unique_ptr<FormatBuffer> formatted_msg{std::make_unique<FormatBuffer>()};
216  std::unique_ptr<ExtraData> extra_data;
217  std::atomic<bool>* flush_flag{nullptr};
218 };
219 } // namespace detail
220 
221 QUILL_END_NAMESPACE
std::unique_ptr< ExtraData > extra_data
buffer for message
Definition: TransitEvent.h:216
Definition: TransitEvent.h:32
Definition: TransitEvent.h:134
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:204
Definition: LoggerBase.h:36
std::atomic< bool > * flush_flag
A unique ptr to save space as these fields not always used.
Definition: TransitEvent.h:217