13 #include "llvm/ADT/DenseSet.h" 14 #include "llvm/ADT/ScopeExit.h" 15 #include "llvm/Support/Chrono.h" 16 #include "llvm/Support/FormatProviders.h" 17 #include "llvm/Support/FormatVariadic.h" 18 #include "llvm/Support/Threading.h" 31 JSONTracer(llvm::raw_ostream &Out,
bool Pretty)
32 : Out(Out), Sep(
""), Start(std::chrono::system_clock::now()),
33 JSONFormat(Pretty ?
"{0:2}" :
"{0}") {
36 Out << R
"({"displayTimeUnit":"ns","traceEvents":[)" 38 rawEvent(
"M", llvm::json::Object{
39 {
"name",
"process_name"},
40 {
"args", llvm::json::Object{{
"name",
"clangd"}}},
51 Context beginSpan(llvm::StringRef
Name, llvm::json::Object *Args)
override {
53 SpanKey, llvm::make_unique<JSONSpan>(
this, Name, Args));
60 void endSpan()
override {
64 void instant(llvm::StringRef Name, llvm::json::Object &&Args)
override {
65 captureThreadMetadata();
67 llvm::json::Object{{
"name", Name}, {
"args", std::move(Args)}});
72 void jsonEvent(llvm::StringRef Phase, llvm::json::Object &&
Contents,
73 uint64_t TID = llvm::get_threadid(),
double Timestamp = 0) {
74 Contents[
"ts"] = Timestamp ? Timestamp : timestamp();
76 std::lock_guard<std::mutex> Lock(Mu);
77 rawEvent(Phase, std::move(
Contents));
83 JSONSpan(JSONTracer *Tracer, llvm::StringRef Name, llvm::json::Object *Args)
84 : StartTime(Tracer->timestamp()), EndTime(0), Name(Name),
85 TID(llvm::get_threadid()), Tracer(Tracer), Args(Args) {
87 Tracer->captureThreadMetadata();
95 if (Parent && *Parent && (*Parent)->TID != TID) {
98 double OriginTime = (*Parent)->EndTime;
100 OriginTime = (*Parent)->StartTime;
102 auto FlowID = nextID();
105 llvm::json::Object{{
"id", FlowID},
106 {
"name",
"Context crosses threads"},
108 (*Parent)->TID, (*Parent)->StartTime);
111 llvm::json::Object{{
"id", FlowID},
113 {
"name",
"Context crosses threads"},
121 Tracer->jsonEvent(
"X",
122 llvm::json::Object{{
"name", std::move(Name)},
123 {
"args", std::move(*Args)},
124 {
"dur", EndTime - StartTime}},
129 void markEnded() { EndTime = Tracer->timestamp(); }
132 static int64_t nextID() {
133 static std::atomic<int64_t> Next = {0};
138 std::atomic<double> EndTime;
142 llvm::json::Object *Args;
148 void rawEvent(llvm::StringRef Phase,
149 llvm::json::Object &&
Event) {
154 << llvm::formatv(JSONFormat, llvm::json::Value(std::move(
Event)));
159 void captureThreadMetadata() {
160 uint64_t TID = llvm::get_threadid();
161 std::lock_guard<std::mutex> Lock(Mu);
162 if (ThreadsWithMD.insert(TID).second) {
163 llvm::SmallString<32> Name;
164 llvm::get_thread_name(Name);
166 rawEvent(
"M", llvm::json::Object{
167 {
"tid", int64_t(TID)},
168 {
"name",
"thread_name"},
169 {
"args", llvm::json::Object{{
"name", Name}}},
176 using namespace std::chrono;
177 return duration<double, std::micro>(system_clock::now() - Start).count();
181 llvm::raw_ostream &Out ;
183 llvm::DenseSet<uint64_t> ThreadsWithMD ;
184 const llvm::sys::TimePoint<> Start;
185 const char *JSONFormat;
194 assert(!T &&
"Resetting global tracer is not allowed.");
202 return llvm::make_unique<JSONTracer>(OS, Pretty);
208 T->instant(
"Log", llvm::json::Object{{
"Message", Message.str()}});
216 return T->beginSpan(Name.isSingleStringRef() ? Name.getSingleStringRef()
217 : llvm::StringRef(Name.str()),
225 : Args(T ? new
llvm::json::
Object() : nullptr),
Session(EventTracer &Tracer)
Some operations such as code completion produce a set of candidates.
An Event<T> allows events of type T to be broadcast to listeners.
Values in a Context are indexed by typed keys.
static const StringRef Message
const Type * get(const Key< Type > &Key) const
Get data stored for a typed Key.
Context clone() const
Clone this context object.
static const Context & current()
Returns the context for the current thread, creating it if needed.
A context is an immutable container for per-request data that must be propagated through layers that ...
const Type & getExisting(const Key< Type > &Key) const
A helper to get a reference to a Key that must exist in the map.
===– Representation.cpp - ClangDoc Representation --------—*- C++ -*-===//
void log(const llvm::Twine &Message)
Records a single instant event, associated with the current thread.
Context derive(const Key< Type > &Key, typename std::decay< Type >::type Value) const &
Derives a child context It is safe to move or destroy a parent context after calling derive()...
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...
WithContextValue extends Context::current() with a single value.
static Context makeSpanContext(llvm::Twine Name, llvm::json::Object *Args)
A consumer of trace events.