libdballe  9.14
db/v7/trace.h
1 #ifndef DBALLE_DB_V7_TRACE_H
2 #define DBALLE_DB_V7_TRACE_H
3 
4 #include <dballe/core/json.h>
5 #include <dballe/db/v7/fwd.h>
6 #include <dballe/fwd.h>
7 #include <sstream>
8 #include <string>
9 #include <vector>
10 
11 namespace dballe {
12 namespace db {
13 namespace v7 {
14 
15 namespace trace {
16 
17 struct Aggregate
18 {
19  unsigned count = 0;
20  unsigned rows = 0;
21  clock_t ticks = 0;
22 };
23 
27 class Step
28 {
29 protected:
31  Step* parent = nullptr;
33  Step* child = nullptr;
35  Step* sibling = nullptr;
37  std::string name;
39  std::string detail;
41  unsigned rows = 0;
43  clock_t start = 0;
45  clock_t end = 0;
46 
47  template <typename T> void add_sibling(T* step)
48  {
49  if (!sibling)
50  {
51  sibling = step;
52  step->parent = parent;
53  }
54  else
55  sibling->add_sibling(step);
56  }
57 
58  Step* first_sibling(const std::string& name)
59  {
60  if (this->name == name)
61  return this;
62  if (!sibling)
63  return nullptr;
64  return sibling->first_sibling(name);
65  }
66 
67  Step* last_sibling(const std::string& name, Step* last = nullptr)
68  {
69  if (this->name == name)
70  {
71  if (!sibling)
72  return this;
73  return sibling->last_sibling(name, this);
74  }
75  if (!sibling)
76  return last;
77  return sibling->last_sibling(name, last);
78  }
79 
80  void _aggregate(const std::string& name, Aggregate& agg)
81  {
82  if (this->name == name)
83  {
84  ++agg.count;
85  agg.rows += rows;
86  agg.ticks += end - start;
87  }
88  if (sibling)
89  sibling->_aggregate(name, agg);
90  if (child)
91  child->_aggregate(name, agg);
92  }
93 
94 public:
95  Step(const std::string& name);
96  Step(const std::string& name, const std::string& detail);
97  ~Step();
98 
99  void done();
100  unsigned elapsed_usec() const;
101 
102  void to_json(core::JSONWriter& writer) const;
103 
104  // Remove all children accumulated so far
105  void clear()
106  {
107  delete child;
108  child = nullptr;
109  }
110 
111  Aggregate aggregate(const std::string& name)
112  {
113  Aggregate res;
114  if (child)
115  child->_aggregate(name, res);
116  return res;
117  }
118 
119  Step* first_child(const std::string& name)
120  {
121  if (!child)
122  return nullptr;
123  return child->first_sibling(name);
124  }
125 
126  Step* last_child(const std::string& name)
127  {
128  if (!child)
129  return nullptr;
130  return child->last_sibling(name);
131  }
132 
133  void add_row(unsigned amount = 1) { rows += amount; }
134 
135  template <typename T> T* add_child(T* step)
136  {
137  if (!child)
138  {
139  child = step;
140  step->parent = this;
141  }
142  else
143  child->add_sibling(step);
144  return step;
145  }
146 
147  Step* trace_select(const std::string& query, unsigned rows = 0)
148  {
149  Step* res = add_child(new Step("select", query));
150  res->rows = rows;
151  return res;
152  }
153 
154  Step* trace_insert(const std::string& query, unsigned rows = 0)
155  {
156  Step* res = add_child(new Step("insert", query));
157  res->rows = rows;
158  return res;
159  }
160 
161  Step* trace_update(const std::string& query, unsigned rows = 0)
162  {
163  Step* res = add_child(new Step("update", query));
164  res->rows = rows;
165  return res;
166  }
167 
168  Step* trace_delete(const std::string& query, unsigned rows = 0)
169  {
170  Step* res = add_child(new Step("delete", query));
171  res->rows = rows;
172  return res;
173  }
174 };
175 
176 class Transaction : public Step
177 {
178 public:
179  Transaction() : Step("transaction") {}
180 
181  Tracer<> trace_query_stations(const Query& query);
182  Tracer<> trace_query_station_data(const Query& query);
183  Tracer<> trace_query_data(const Query& query);
184  Tracer<> trace_query_summary(const Query& query);
185  Tracer<> trace_import(unsigned count);
186  Tracer<> trace_export_msgs(const Query& query);
187  Tracer<> trace_insert_station_data();
188  Tracer<> trace_insert_data();
189  Tracer<> trace_add_station_vars();
190  Tracer<> trace_func(const std::string& name);
191  Tracer<> trace_remove_station_data(const Query& query);
192  Tracer<> trace_remove_data(const Query& query);
193  Tracer<> trace_remove_station_data_by_id(int id);
194  Tracer<> trace_remove_data_by_id(int id);
195 };
196 
197 } // namespace trace
198 
199 struct Trace
200 {
201  virtual ~Trace() {}
202 
203  virtual Tracer<> trace_connect(const std::string& url) = 0;
204  virtual Tracer<> trace_reset(const char* repinfo_file = 0) = 0;
205  virtual Tracer<trace::Transaction> trace_transaction() = 0;
206  virtual Tracer<> trace_remove_all() = 0;
207  virtual Tracer<> trace_vacuum() = 0;
208  virtual void save() = 0;
209 
210  static bool in_test_suite();
211  static void set_in_test_suite();
212 };
213 
214 struct NullTrace : public Trace
215 {
216  Tracer<> trace_connect(const std::string& url) override
217  {
218  return Tracer<>(nullptr);
219  }
220  Tracer<> trace_reset(const char* repinfo_file = 0) override
221  {
222  return Tracer<>(nullptr);
223  }
224  Tracer<trace::Transaction> trace_transaction() override
225  {
226  return Tracer<trace::Transaction>(nullptr);
227  }
228  Tracer<> trace_remove_all() override { return Tracer<>(nullptr); }
229  Tracer<> trace_vacuum() override { return Tracer<>(nullptr); }
230  void save() override {}
231 };
232 
233 class QuietCollectTrace : public Trace
234 {
235 protected:
236  std::vector<trace::Step*> steps;
237 
238 public:
239  QuietCollectTrace() = default;
240  QuietCollectTrace(const QuietCollectTrace&) = delete;
242  QuietCollectTrace& operator=(const QuietCollectTrace&) = delete;
243  QuietCollectTrace& operator=(QuietCollectTrace&&) = delete;
245 
246  Tracer<> trace_connect(const std::string& url) override;
247  Tracer<> trace_reset(const char* repinfo_file = 0) override;
248  Tracer<trace::Transaction> trace_transaction() override;
249  Tracer<> trace_remove_all() override;
250  Tracer<> trace_vacuum() override;
251 
252  void save() override {}
253 };
254 
256 {
257 protected:
258  std::string logdir;
259  time_t start;
260 
261 public:
262  CollectTrace(const std::string& logdir);
263 
264  void save() override;
265 };
266 
267 } // namespace v7
268 } // namespace db
269 } // namespace dballe
270 
271 #endif
Step * sibling
Next sibling operation in the operation stack.
Definition: db/v7/trace.h:35
One operation being traced.
Definition: db/v7/trace.h:27
clock_t end
Timing end.
Definition: db/v7/trace.h:45
std::string detail
Optional details about the operation.
Definition: db/v7/trace.h:39
Step * child
First child operation in the operation stack.
Definition: db/v7/trace.h:33
clock_t start
Timing start.
Definition: db/v7/trace.h:43
Definition: db/v7/trace.h:255
Definition: db/v7/trace.h:176
unsigned rows
Number of database rows affected.
Definition: db/v7/trace.h:41
Step * parent
Parent operation in the operation stack.
Definition: db/v7/trace.h:31
Definition: db/v7/trace.h:199
Definition: cmdline.h:18
std::string name
Operation name.
Definition: db/v7/trace.h:37
Definition: db/v7/trace.h:214
Definition: db/v7/trace.h:233
Smart pointer for trace::Step objects, which calls done() when going out of scope.
Definition: db/v7/fwd.h:44
Definition: db/v7/trace.h:17
Query used to filter DB-All.e data.
Definition: query.h:16