clang-tools  11.0.0git
Trace.h
Go to the documentation of this file.
1 //===--- Trace.h - Performance tracing facilities ---------------*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // Supports writing performance traces describing clangd's behavior.
10 // Traces are consumed by implementations of the EventTracer interface.
11 //
12 //
13 // All APIs are no-ops unless a Session is active (created by ClangdMain).
14 //
15 //===----------------------------------------------------------------------===//
16 
17 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANGD_SUPPORT_TRACE_H_
18 #define LLVM_CLANG_TOOLS_EXTRA_CLANGD_SUPPORT_TRACE_H_
19 
20 #include "support/Context.h"
21 #include "llvm/ADT/StringRef.h"
22 #include "llvm/ADT/Twine.h"
23 #include "llvm/Support/JSON.h"
24 #include "llvm/Support/raw_ostream.h"
25 #include <chrono>
26 #include <string>
27 #include <vector>
28 
29 namespace clang {
30 namespace clangd {
31 namespace trace {
32 
33 /// Represents measurements of clangd events, e.g. operation latency. Those
34 /// measurements are recorded per-label, defaulting to an empty one for metrics
35 /// that don't care about it. This enables aggregation of measurements across
36 /// labels. For example a metric tracking accesses to a cache can have labels
37 /// named hit and miss.
38 struct Metric {
39  enum MetricType {
40  /// A number whose value is meaningful, and may vary over time.
41  /// Each measurement replaces the current value.
43 
44  /// An aggregate number whose rate of change over time is meaningful.
45  /// Each measurement is an increment for the counter.
47 
48  /// A distribution of values with a meaningful mean and count.
49  /// Each measured value is a sample for the distribution.
50  /// The distribution is assumed not to vary, samples are aggregated over
51  /// time.
53  };
54  constexpr Metric(llvm::StringLiteral Name, MetricType Type,
55  llvm::StringLiteral LabelName = llvm::StringLiteral(""))
56  : Name(Name), Type(Type), LabelName(LabelName) {}
57 
58  /// Records a measurement for this metric to active tracer.
59  void record(double Value, llvm::StringRef Label = "") const;
60 
61  /// Uniquely identifies the metric. Should use snake_case identifiers, can use
62  /// dots for hierarchy if needed. e.g. method_latency, foo.bar.
63  const llvm::StringLiteral Name;
65  /// Indicates what measurement labels represent, e.g. "operation_name" for a
66  /// metric tracking latencies. If non empty all measurements must also have a
67  /// non-empty label.
68  const llvm::StringLiteral LabelName;
69 };
70 
71 /// A consumer of trace events and measurements. The events are produced by
72 /// Spans and trace::log, the measurements are produced by Metrics::record.
73 /// Implementations of this interface must be thread-safe.
74 class EventTracer {
75 public:
76  virtual ~EventTracer() = default;
77 
78  /// Called when event that has a duration starts. \p Name describes the event.
79  /// Returns a derived context that will be destroyed when the event ends.
80  /// Usually implementations will store an object in the returned context
81  /// whose destructor records the end of the event.
82  /// The args are *Args, only complete when the event ends.
83  virtual Context beginSpan(llvm::StringRef Name, llvm::json::Object *Args);
84  // Called when a Span is destroyed (it may still be active on other threads).
85  // beginSpan() and endSpan() will always form a proper stack on each thread.
86  // The Context returned by beginSpan is active, but Args is not ready.
87  // Tracers should not override this unless they need to observe strict
88  // per-thread nesting. Instead they should observe context destruction.
89  virtual void endSpan() {}
90 
91  /// Called for instant events.
92  virtual void instant(llvm::StringRef Name, llvm::json::Object &&Args) {}
93 
94  /// Called whenever a metrics records a measurement.
95  virtual void record(const Metric &Metric, double Value,
96  llvm::StringRef Label) {}
97 };
98 
99 /// Sets up a global EventTracer that consumes events produced by Span and
100 /// trace::log. Only one TracingSession can be active at a time and it should be
101 /// set up before calling any clangd-specific functions.
102 class Session {
103 public:
105  ~Session();
106 };
107 
108 /// Create an instance of EventTracer that produces an output in the Trace Event
109 /// format supported by Chrome's trace viewer (chrome://tracing).
110 ///
111 /// FIXME: Metrics are not recorded, some could become counter events.
112 ///
113 /// The format is documented here:
114 /// https://docs.google.com/document/d/1CvAClvFfyA5R-PhYUmn5OOQtYMH4h6I0nSsKchNAySU/preview
115 std::unique_ptr<EventTracer> createJSONTracer(llvm::raw_ostream &OS,
116  bool Pretty = false);
117 
118 /// Create an instance of EventTracer that outputs metric measurements as CSV.
119 ///
120 /// Trace spans and instant events are ignored.
121 std::unique_ptr<EventTracer> createCSVMetricTracer(llvm::raw_ostream &OS);
122 
123 /// Records a single instant event, associated with the current thread.
124 void log(const llvm::Twine &Name);
125 
126 /// Records an event whose duration is the lifetime of the Span object.
127 /// This lifetime is extended when the span's context is reused.
128 ///
129 /// This is the main public interface for producing tracing events.
130 ///
131 /// Arbitrary JSON metadata can be attached while this span is active:
132 /// SPAN_ATTACH(MySpan, "Payload", SomeJSONExpr);
133 ///
134 /// SomeJSONExpr is evaluated and copied only if actually needed.
135 class Span {
136 public:
137  Span(llvm::Twine Name);
138  /// Records span's duration in seconds to \p LatencyMetric with \p Name as the
139  /// label.
140  Span(llvm::Twine Name, const Metric &LatencyMetric);
141  ~Span();
142 
143  /// Mutable metadata, if this span is interested.
144  /// Prefer to use SPAN_ATTACH rather than accessing this directly.
145  /// The lifetime of Args is the whole event, even if the Span dies.
146  llvm::json::Object *const Args;
147 
148 private:
149  WithContext RestoreCtx;
150 };
151 
152 /// Attach a key-value pair to a Span event.
153 /// This is not threadsafe when used with the same Span.
154 #define SPAN_ATTACH(S, Name, Expr) \
155  do { \
156  if (auto *Args = (S).Args) \
157  (*Args)[Name] = Expr; \
158  } while (0)
159 
160 } // namespace trace
161 } // namespace clangd
162 } // namespace clang
163 
164 #endif
A number whose value is meaningful, and may vary over time.
Definition: Trace.h:42
Sets up a global EventTracer that consumes events produced by Span and trace::log.
Definition: Trace.h:102
void record(double Value, llvm::StringRef Label="") const
Records a measurement for this metric to active tracer.
Definition: Trace.cpp:318
const llvm::StringLiteral Name
Uniquely identifies the metric.
Definition: Trace.h:63
trace::Session Session
Definition: TraceTests.cpp:164
A distribution of values with a meaningful mean and count.
Definition: Trace.h:52
Represents measurements of clangd events, e.g.
Definition: Trace.h:38
An aggregate number whose rate of change over time is meaningful.
Definition: Trace.h:46
llvm::raw_string_ostream OS
Definition: TraceTests.cpp:162
A context is an immutable container for per-request data that must be propagated through layers that ...
Definition: Context.h:69
WithContext replaces Context::current() with a provided scope.
Definition: Context.h:189
const MetricType Type
Definition: Trace.h:64
===– Representation.cpp - ClangDoc Representation --------—*- C++ -*-===//
virtual void instant(llvm::StringRef Name, llvm::json::Object &&Args)
Called for instant events.
Definition: Trace.h:92
void log(const llvm::Twine &Message)
Records a single instant event, associated with the current thread.
Definition: Trace.cpp:274
std::unique_ptr< trace::EventTracer > Tracer
Definition: TraceTests.cpp:163
std::unique_ptr< EventTracer > createJSONTracer(llvm::raw_ostream &OS, bool Pretty)
Create an instance of EventTracer that produces an output in the Trace Event format supported by Chro...
Definition: Trace.cpp:265
constexpr Metric(llvm::StringLiteral Name, MetricType Type, llvm::StringLiteral LabelName=llvm::StringLiteral(""))
Definition: Trace.h:54
virtual void record(const Metric &Metric, double Value, llvm::StringRef Label)
Called whenever a metrics records a measurement.
Definition: Trace.h:95
llvm::json::Object *const Args
Mutable metadata, if this span is interested.
Definition: Trace.h:146
Records an event whose duration is the lifetime of the Span object.
Definition: Trace.h:135
std::unique_ptr< EventTracer > createCSVMetricTracer(llvm::raw_ostream &OS)
Create an instance of EventTracer that outputs metric measurements as CSV.
Definition: Trace.cpp:270
A consumer of trace events and measurements.
Definition: Trace.h:74
const llvm::StringLiteral LabelName
Indicates what measurement labels represent, e.g.
Definition: Trace.h:68