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