Overte C++ Documentation
Trace.h
1 //
2 // Created by Ryan Huffman on 2016-12-14
3 // Copyright 2013-2016 High Fidelity, Inc.
4 //
5 // Distributed under the Apache License, Version 2.0.
6 // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
7 //
8 
9 #pragma once
10 #ifndef hifi_Trace_h
11 #define hifi_Trace_h
12 
13 #include <cstdint>
14 #include <mutex>
15 
16 #include <QtCore/QString>
17 #include <QtCore/QVariantMap>
18 #include <QtCore/QHash>
19 #include <QtCore/QSet>
20 #include <QtCore/QLoggingCategory>
21 
22 #include "DependencyManager.h"
23 
24 namespace tracing {
25 
26 bool enabled();
27 
28 using TraceTimestamp = uint64_t;
29 
30 enum EventType : char {
31  DurationBegin = 'B',
32  DurationEnd = 'E',
33 
34  Complete = 'X',
35  Instant = 'i',
36  Counter = 'C',
37 
38  AsyncNestableStart = 'b',
39  AsyncNestableInstant = 'n',
40  AsyncNestableEnd = 'e',
41 
42  FlowStart = 's',
43  FlowStep = 't',
44  FlowEnd = 'f',
45 
46  Sample = 'P',
47 
48  ObjectCreated = 'N',
49  ObjectSnapshot = 'O',
50  ObjectDestroyed = 'D',
51 
52  Metadata = 'M',
53 
54  MemoryDumpGlobal = 'V',
55  MemoryDumpProcess = 'v',
56 
57  Mark = 'R',
58 
59  ClockSync = 'c',
60 
61  ContextEnter = '(',
62  ContextLeave = ')'
63 };
64 
65 struct TraceEvent {
66  QString id;
67  QString name;
68  EventType type;
69  qint64 timestamp;
70  qint64 processID;
71  qint64 threadID;
72  const QLoggingCategory& category;
73  QVariantMap args;
74  QVariantMap extra;
75 
76  void writeJson(QTextStream& out) const;
77 };
78 
79 class Tracer : public Dependency {
80 public:
81  static int64_t now();
82  void traceEvent(const QLoggingCategory& category,
83  const QString& name, EventType type,
84  const QString& id = "",
85  const QVariantMap& args = QVariantMap(), const QVariantMap& extra = QVariantMap());
86 
87  void traceEvent(const QLoggingCategory& category,
88  const QString& name, EventType type,
89  int64_t timestamp,
90  const QString& id = "",
91  const QVariantMap& args = QVariantMap(), const QVariantMap& extra = QVariantMap());
92 
93  void startTracing();
94  void stopTracing();
95  void serialize(const QString& file);
96  bool isEnabled() const { return _enabled; }
97 
98 private:
99  void traceEvent(const QLoggingCategory& category,
100  const QString& name, EventType type,
101  qint64 timestamp, qint64 processID, qint64 threadID,
102  const QString& id = "",
103  const QVariantMap& args = QVariantMap(), const QVariantMap& extra = QVariantMap());
104 
105  bool _enabled { false };
106  std::list<TraceEvent> _events;
107  std::list<TraceEvent> _metadataEvents;
108  std::mutex _eventsMutex;
109 };
110 
111 inline void traceEvent(const QLoggingCategory& category, int64_t timestamp, const QString& name, EventType type, const QString& id = "", const QVariantMap& args = {}, const QVariantMap& extra = {}) {
112  if (!DependencyManager::isSet<Tracer>()) {
113  return;
114  }
115  const auto& tracer = DependencyManager::get<Tracer>();
116  if (tracer) {
117  tracer->traceEvent(category, name, type, timestamp, id, args, extra);
118  }
119 }
120 
121 inline void traceEvent(const QLoggingCategory& category, const QString& name, EventType type, const QString& id = "", const QVariantMap& args = {}, const QVariantMap& extra = {}) {
122  if (!DependencyManager::isSet<Tracer>()) {
123  return;
124  }
125  const auto& tracer = DependencyManager::get<Tracer>();
126  if (tracer) {
127  tracer->traceEvent(category, name, type, id, args, extra);
128  }
129 }
130 
131 inline void traceEvent(const QLoggingCategory& category, const QString& name, EventType type, int id, const QVariantMap& args = {}, const QVariantMap& extra = {}) {
132  traceEvent(category, name, type, QString::number(id), args, extra);
133 }
134 
135 }
136 
137 #endif // hifi_Trace_h