[clangd] Changed tracing interfaces
Summary: EventTracer interface now contains two methods: - spanEvent for events that have duration, - instant for events that are instant. Reviewers: sammccall Reviewed By: sammccall Subscribers: klimek, luckygeck, cfe-commits Differential Revision: https://reviews.llvm.org/D40489 llvm-svn: 320708
This commit is contained in:
parent
c70f1d63f8
commit
12cdb4fd33
|
@ -44,10 +44,24 @@ public:
|
|||
Out.flush();
|
||||
}
|
||||
|
||||
EndEventCallback beginSpan(const Context &Ctx,
|
||||
llvm::StringRef Name) override {
|
||||
jsonEvent("B", json::obj{{"name", Name}});
|
||||
|
||||
// The callback that will run when event ends.
|
||||
return [this](json::Expr &&Args) {
|
||||
jsonEvent("E", json::obj{{"args", std::move(Args)}});
|
||||
};
|
||||
}
|
||||
|
||||
void instant(const Context &Ctx, llvm::StringRef Name,
|
||||
json::obj &&Args) override {
|
||||
jsonEvent("i", json::obj{{"name", Name}, {"args", std::move(Args)}});
|
||||
}
|
||||
|
||||
// Record an event on the current thread. ph, pid, tid, ts are set.
|
||||
// Contents must be a list of the other JSON key/values.
|
||||
void event(const Context &Ctx, StringRef Phase,
|
||||
json::obj &&Contents) override {
|
||||
void jsonEvent(StringRef Phase, json::obj &&Contents) {
|
||||
uint64_t TID = get_threadid();
|
||||
std::lock_guard<std::mutex> Lock(Mu);
|
||||
// If we haven't already, emit metadata describing this thread.
|
||||
|
@ -109,30 +123,26 @@ std::unique_ptr<EventTracer> createJSONTracer(llvm::raw_ostream &OS,
|
|||
void log(const Context &Ctx, const Twine &Message) {
|
||||
if (!T)
|
||||
return;
|
||||
T->event(Ctx, "i",
|
||||
json::obj{
|
||||
{"name", "Log"},
|
||||
{"args", json::obj{{"Message", Message.str()}}},
|
||||
});
|
||||
T->instant(Ctx, "Log", json::obj{{"Message", Message.str()}});
|
||||
}
|
||||
|
||||
Span::Span(const Context &Ctx, std::string Name) {
|
||||
Span::Span(const Context &Ctx, llvm::StringRef Name) {
|
||||
if (!T)
|
||||
return;
|
||||
// Clone the context, so that the original Context can be moved.
|
||||
this->Ctx.emplace(Ctx.clone());
|
||||
|
||||
T->event(*this->Ctx, "B", json::obj{{"name", std::move(Name)}});
|
||||
Callback = T->beginSpan(Ctx, Name);
|
||||
if (!Callback)
|
||||
return;
|
||||
|
||||
Args = llvm::make_unique<json::obj>();
|
||||
}
|
||||
|
||||
Span::~Span() {
|
||||
if (!T)
|
||||
if (!Callback)
|
||||
return;
|
||||
if (!Args)
|
||||
Args = llvm::make_unique<json::obj>();
|
||||
T->event(*Ctx, "E",
|
||||
Args ? json::obj{{"args", std::move(*Args)}} : json::obj{});
|
||||
|
||||
assert(Args && "Args must be non-null if Callback is defined");
|
||||
Callback(std::move(*Args));
|
||||
}
|
||||
|
||||
} // namespace trace
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
#define LLVM_CLANG_TOOLS_EXTRA_CLANGD_TRACE_H_
|
||||
|
||||
#include "Context.h"
|
||||
#include "Function.h"
|
||||
#include "JSONExpr.h"
|
||||
#include "llvm/ADT/Twine.h"
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
|
@ -28,12 +29,24 @@ namespace clangd {
|
|||
namespace trace {
|
||||
|
||||
/// A consumer of trace events. The events are produced by Spans and trace::log.
|
||||
/// Implmentations of this interface must be thread-safe.
|
||||
class EventTracer {
|
||||
public:
|
||||
/// A callback executed when an event with duration ends. Args represent data
|
||||
/// that was attached to the event via SPAN_ATTACH.
|
||||
using EndEventCallback = UniqueFunction<void(json::obj &&Args)>;
|
||||
|
||||
virtual ~EventTracer() = default;
|
||||
/// Consume a trace event.
|
||||
virtual void event(const Context &Ctx, llvm::StringRef Phase,
|
||||
json::obj &&Contents) = 0;
|
||||
|
||||
/// Called when event that has a duration starts. The returned callback will
|
||||
/// be executed when the event ends. \p Name is a descriptive name
|
||||
/// of the event that was passed to Span constructor.
|
||||
virtual EndEventCallback beginSpan(const Context &Ctx,
|
||||
llvm::StringRef Name) = 0;
|
||||
|
||||
/// Called for instant events.
|
||||
virtual void instant(const Context &Ctx, llvm::StringRef Name,
|
||||
json::obj &&Args) = 0;
|
||||
};
|
||||
|
||||
/// Sets up a global EventTracer that consumes events produced by Span and
|
||||
|
@ -50,9 +63,6 @@ public:
|
|||
///
|
||||
/// The format is documented here:
|
||||
/// https://docs.google.com/document/d/1CvAClvFfyA5R-PhYUmn5OOQtYMH4h6I0nSsKchNAySU/preview
|
||||
///
|
||||
/// The implementation supports concurrent calls and can be used as a global
|
||||
/// tracer (i.e., can be put into a global Context).
|
||||
std::unique_ptr<EventTracer> createJSONTracer(llvm::raw_ostream &OS,
|
||||
bool Pretty = false);
|
||||
|
||||
|
@ -67,7 +77,7 @@ void log(const Context &Ctx, const llvm::Twine &Name);
|
|||
/// SomeJSONExpr is evaluated and copied only if actually needed.
|
||||
class Span {
|
||||
public:
|
||||
Span(const Context &Ctx, std::string Name);
|
||||
Span(const Context &Ctx, llvm::StringRef Name);
|
||||
~Span();
|
||||
|
||||
/// Returns mutable span metadata if this span is interested.
|
||||
|
@ -75,8 +85,8 @@ public:
|
|||
json::obj *args() { return Args.get(); }
|
||||
|
||||
private:
|
||||
llvm::Optional<Context> Ctx;
|
||||
std::unique_ptr<json::obj> Args;
|
||||
EventTracer::EndEventCallback Callback;
|
||||
};
|
||||
|
||||
#define SPAN_ATTACH(S, Name, Expr) \
|
||||
|
|
Loading…
Reference in New Issue