quill
BacktraceStorage.h
1 
7 #pragma once
8 
9 #include "quill/backend/TransitEvent.h"
10 #include "quill/core/Attributes.h"
11 
12 #include <cstdint>
13 #include <functional>
14 #include <string>
15 #include <string_view>
16 #include <utility>
17 #include <vector>
18 
19 QUILL_BEGIN_NAMESPACE
20 
21 namespace detail
22 {
29 {
30 public:
31  BacktraceStorage() = default;
32 
33  /***/
34  void store(TransitEvent transit_event, std::string_view const& thread_id, std::string_view const& thread_name)
35  {
36  if (_stored_events.size() < _capacity)
37  {
38  // We are still growing the vector to max capacity
39  _stored_events.emplace_back(std::string{thread_id}, std::string{thread_name}, std::move(transit_event));
40  }
41  else
42  {
43  // Store the object in the vector, replacing the previous
44  StoredTransitEvent& ste = _stored_events[_index];
45 
46  ste = StoredTransitEvent{std::string{thread_id}, std::string{thread_name}, std::move(transit_event)};
47 
48  // Update the index wrapping around the vector capacity
49  if (_index < _capacity - 1)
50  {
51  _index += 1;
52  }
53  else
54  {
55  _index = 0;
56  }
57  }
58  }
59 
60  /***/
61  void process(std::function<void(TransitEvent const&, std::string_view thread_id, std::string_view thread_name)> const& callback)
62  {
63  // we found stored messages for this logger
64  uint32_t index = _index;
65 
66  // Iterate retrieved records in order from first message using index
67  for (uint32_t i = 0; i < _stored_events.size(); ++i)
68  {
69  // Give to the user callback the thread id and the RecordBase pointer
70  callback(_stored_events[index].transit_event, _stored_events[index].thread_id,
71  _stored_events[index].thread_name);
72 
73  // We wrap around to iterate all messages
74  if (index < _stored_events.size() - 1)
75  {
76  index += 1;
77  }
78  else
79  {
80  index = 0;
81  }
82  }
83 
84  // finally clean all messages
85  _stored_events.clear();
86  }
87 
88  /***/
89  void set_capacity(uint32_t capacity)
90  {
91  if (_capacity != capacity)
92  {
93  _capacity = capacity;
94  _index = 0;
95  _stored_events.clear();
96  _stored_events.reserve(_capacity);
97  }
98  }
99 
100 private:
101  struct StoredTransitEvent
102  {
103  StoredTransitEvent(std::string thread_id, std::string thread_name, TransitEvent transit_event)
104  : thread_id(std::move(thread_id)),
105  thread_name(std::move(thread_name)),
106  transit_event(std::move(transit_event))
107  {
108  }
109 
114  std::string thread_id;
115  std::string thread_name;
116  TransitEvent transit_event;
117  };
118 
119 private:
120  uint32_t _capacity{0};
121  uint32_t _index{0};
122  std::vector<StoredTransitEvent> _stored_events;
123 };
124 } // namespace detail
125 
126 QUILL_END_NAMESPACE
Stores N max messages per logger name in a vector.
Definition: BacktraceStorage.h:28
Definition: TransitEvent.h:32
Setups a signal handler to handle fatal signals.
Definition: BackendManager.h:24