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" 32 JSONTracer(raw_ostream &Out,
bool Pretty)
33 : Out(Out), Sep(
""), Start(std::chrono::system_clock::now()),
34 JSONFormat(Pretty ?
"{0:2}" :
"{0}") {
37 Out << R
"({"displayTimeUnit":"ns","traceEvents":[)" 40 {
"name",
"process_name"},
54 SpanKey, llvm::make_unique<JSONSpan>(
this, Name, Args));
61 void endSpan()
override {
65 void instant(llvm::StringRef Name,
json::Object &&Args)
override {
66 captureThreadMetadata();
67 jsonEvent(
"i",
json::Object{{
"name", Name}, {
"args", std::move(Args)}});
73 uint64_t TID = 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,
json::Object *Args)
84 : StartTime(Tracer->timestamp()), EndTime(0), Name(Name),
85 TID(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();
103 Tracer->jsonEvent(
"s",
105 {
"name",
"Context crosses threads"},
107 (*Parent)->TID, (*Parent)->StartTime);
108 Tracer->jsonEvent(
"f",
111 {
"name",
"Context crosses threads"},
119 Tracer->jsonEvent(
"X",
121 {
"args", std::move(*Args)},
122 {
"dur", EndTime - StartTime}},
128 EndTime = Tracer->timestamp();
132 static int64_t nextID() {
133 static std::atomic<int64_t> Next = {0};
138 std::atomic<double> EndTime;
157 void captureThreadMetadata() {
158 uint64_t TID = get_threadid();
159 std::lock_guard<std::mutex> Lock(Mu);
160 if (ThreadsWithMD.insert(TID).second) {
161 SmallString<32> Name;
162 get_thread_name(Name);
165 {
"tid", int64_t(TID)},
166 {
"name",
"thread_name"},
174 using namespace std::chrono;
175 return duration<double, std::micro>(system_clock::now() - Start).count();
181 DenseSet<uint64_t> ThreadsWithMD ;
182 const sys::TimePoint<> Start;
183 const char *JSONFormat;
192 assert(!T &&
"Resetting global tracer is not allowed.");
200 return llvm::make_unique<JSONTracer>(OS, Pretty);
206 T->instant(
"Log",
json::Object{{
"Message", Message.str()}});
214 return T->beginSpan(Name.isSingleStringRef() ? Name.getSingleStringRef()
215 : llvm::StringRef(Name.str()),
223 : Args(T ? new json::
Object() : nullptr),
Session(EventTracer &Tracer)
Some operations such as code completion produce a set of candidates.
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.
void log(const Twine &Message)
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++ -*-===//
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...
static Context makeSpanContext(llvm::Twine Name, json::Object *Args)
WithContextValue extends Context::current() with a single value.
A consumer of trace events.