[PATCH] D40488: [clangd] Implemented tracing using Context
This revision was automatically updated to reflect the committed changes. Closed by commit rL320706: [clangd] Implemented tracing using Context (authored by ibiryukov, committed by ). Repository: rL LLVM https://reviews.llvm.org/D40488 Files: clang-tools-extra/trunk/clangd/ClangdUnit.cpp clang-tools-extra/trunk/clangd/JSONRPCDispatcher.cpp clang-tools-extra/trunk/clangd/Trace.cpp clang-tools-extra/trunk/clangd/Trace.h clang-tools-extra/trunk/clangd/tool/ClangdMain.cpp clang-tools-extra/trunk/unittests/clangd/TraceTests.cpp Index: clang-tools-extra/trunk/clangd/Trace.h === --- clang-tools-extra/trunk/clangd/Trace.h +++ clang-tools-extra/trunk/clangd/Trace.h @@ -8,60 +8,74 @@ //===--===// // // Supports writing performance traces describing clangd's behavior. -// Traces are written in the Trace Event format supported by chrome's trace -// viewer (chrome://tracing). +// Traces are consumed by implementations of the EventTracer interface. // -// The format is documented here: -// https://docs.google.com/document/d/1CvAClvFfyA5R-PhYUmn5OOQtYMH4h6I0nSsKchNAySU/preview // // All APIs are no-ops unless a Session is active (created by ClangdMain). // //===--===// #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANGD_TRACE_H_ #define LLVM_CLANG_TOOLS_EXTRA_CLANGD_TRACE_H_ +#include "Context.h" #include "JSONExpr.h" #include "llvm/ADT/Twine.h" #include "llvm/Support/raw_ostream.h" namespace clang { namespace clangd { namespace trace { -// A session directs the output of trace events. Only one Session can exist. -// It should be created before clangd threads are spawned, and destroyed after -// they exit. -// TODO: we may want to add pluggable support for other tracing backends. +/// A consumer of trace events. The events are produced by Spans and trace::log. +class EventTracer { +public: + virtual ~EventTracer() = default; + /// Consume a trace event. + virtual void event(const Context , llvm::StringRef Phase, + json::obj &) = 0; +}; + +/// Sets up a global EventTracer that consumes events produced by Span and +/// trace::log. Only one TracingSession can be active at a time and it should be +/// set up before calling any clangd-specific functions. class Session { public: - // Starts a sessions capturing trace events and writing Trace Event JSON. - static std::unique_ptr create(llvm::raw_ostream , - bool Pretty = false); + Session(EventTracer ); ~Session(); - -private: - Session() = default; }; -// Records a single instant event, associated with the current thread. -void log(const llvm::Twine ); - -// Records an event whose duration is the lifetime of the Span object. -// -// Arbitrary JSON metadata can be attached while this span is active: -// SPAN_ATTACH(MySpan, "Payload", SomeJSONExpr); -// SomeJSONExpr is evaluated and copied only if actually needed. +/// Create an instance of EventTracer that produces an output in the Trace Event +/// format supported by Chrome's trace viewer (chrome://tracing). +/// +/// 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 createJSONTracer(llvm::raw_ostream , + bool Pretty = false); + +/// Records a single instant event, associated with the current thread. +void log(const Context , const llvm::Twine ); + +/// Records an event whose duration is the lifetime of the Span object. +/// This is the main public interface for producing tracing events. +/// +/// Arbitrary JSON metadata can be attached while this span is active: +/// SPAN_ATTACH(MySpan, "Payload", SomeJSONExpr); +/// SomeJSONExpr is evaluated and copied only if actually needed. class Span { public: - Span(std::string Name); + Span(const Context , std::string Name); ~Span(); - // Returns mutable span metadata if this span is interested. - // Prefer to use SPAN_ATTACH rather than accessing this directly. + /// Returns mutable span metadata if this span is interested. + /// Prefer to use SPAN_ATTACH rather than accessing this directly. json::obj *args() { return Args.get(); } private: + llvm::Optional Ctx; std::unique_ptr Args; }; Index: clang-tools-extra/trunk/clangd/tool/ClangdMain.cpp === --- clang-tools-extra/trunk/clangd/tool/ClangdMain.cpp +++ clang-tools-extra/trunk/clangd/tool/ClangdMain.cpp @@ -115,19 +115,25 @@ << EC.message(); } } + + // Setup tracing facilities. llvm::Optional TraceStream; - std::unique_ptr TraceSession; +
[PATCH] D40488: [clangd] Implemented tracing using Context
ilya-biryukov updated this revision to Diff 126951. ilya-biryukov added a comment. - Renamed TracingSession to Session (it is always used qualified via trace::Session anyway) Repository: rCTE Clang Tools Extra https://reviews.llvm.org/D40488 Files: clangd/ClangdUnit.cpp clangd/JSONRPCDispatcher.cpp clangd/Trace.cpp clangd/Trace.h clangd/tool/ClangdMain.cpp unittests/clangd/TraceTests.cpp Index: unittests/clangd/TraceTests.cpp === --- unittests/clangd/TraceTests.cpp +++ unittests/clangd/TraceTests.cpp @@ -7,6 +7,7 @@ // //===--===// +#include "Context.h" #include "Trace.h" #include "llvm/ADT/DenseMap.h" @@ -74,10 +75,11 @@ std::string JSON; { raw_string_ostream OS(JSON); -auto Session = trace::Session::create(OS); +auto JSONTracer = trace::createJSONTracer(OS); +trace::Session Session(*JSONTracer); { - trace::Span S("A"); - trace::log("B"); + trace::Span S(Context::empty(), "A"); + trace::log(Context::empty(), "B"); } } Index: clangd/tool/ClangdMain.cpp === --- clangd/tool/ClangdMain.cpp +++ clangd/tool/ClangdMain.cpp @@ -115,19 +115,25 @@ << EC.message(); } } + + // Setup tracing facilities. llvm::Optional TraceStream; - std::unique_ptr TraceSession; + std::unique_ptr Tracer; if (!TraceFile.empty()) { std::error_code EC; TraceStream.emplace(TraceFile, /*ref*/ EC, llvm::sys::fs::F_RW); if (EC) { TraceFile.reset(); llvm::errs() << "Error while opening trace file: " << EC.message(); } else { - TraceSession = trace::Session::create(*TraceStream, PrettyPrint); + Tracer = trace::createJSONTracer(*TraceStream, PrettyPrint); } } + llvm::Optional TracingSession; + if (Tracer) +TracingSession.emplace(*Tracer); + llvm::raw_ostream = llvm::outs(); llvm::raw_ostream = llvm::errs(); JSONOutput Out(Outs, Logs, Index: clangd/Trace.h === --- clangd/Trace.h +++ clangd/Trace.h @@ -8,60 +8,74 @@ //===--===// // // Supports writing performance traces describing clangd's behavior. -// Traces are written in the Trace Event format supported by chrome's trace -// viewer (chrome://tracing). +// Traces are consumed by implementations of the EventTracer interface. // -// The format is documented here: -// https://docs.google.com/document/d/1CvAClvFfyA5R-PhYUmn5OOQtYMH4h6I0nSsKchNAySU/preview // // All APIs are no-ops unless a Session is active (created by ClangdMain). // //===--===// #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANGD_TRACE_H_ #define LLVM_CLANG_TOOLS_EXTRA_CLANGD_TRACE_H_ +#include "Context.h" #include "JSONExpr.h" #include "llvm/ADT/Twine.h" #include "llvm/Support/raw_ostream.h" namespace clang { namespace clangd { namespace trace { -// A session directs the output of trace events. Only one Session can exist. -// It should be created before clangd threads are spawned, and destroyed after -// they exit. -// TODO: we may want to add pluggable support for other tracing backends. +/// A consumer of trace events. The events are produced by Spans and trace::log. +class EventTracer { +public: + virtual ~EventTracer() = default; + /// Consume a trace event. + virtual void event(const Context , llvm::StringRef Phase, + json::obj &) = 0; +}; + +/// Sets up a global EventTracer that consumes events produced by Span and +/// trace::log. Only one TracingSession can be active at a time and it should be +/// set up before calling any clangd-specific functions. class Session { public: - // Starts a sessions capturing trace events and writing Trace Event JSON. - static std::unique_ptr create(llvm::raw_ostream , - bool Pretty = false); + Session(EventTracer ); ~Session(); - -private: - Session() = default; }; -// Records a single instant event, associated with the current thread. -void log(const llvm::Twine ); +/// Create an instance of EventTracer that produces an output in the Trace Event +/// format supported by Chrome's trace viewer (chrome://tracing). +/// +/// 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 createJSONTracer(llvm::raw_ostream , + bool Pretty = false); -// Records an event whose duration is the lifetime of the Span object. -// -// Arbitrary JSON metadata can be attached while
[PATCH] D40488: [clangd] Implemented tracing using Context
sammccall accepted this revision. sammccall added inline comments. This revision is now accepted and ready to land. Comment at: clangd/Trace.cpp:123 + // Clone the context, so that the original Context can be moved. + this->Ctx.emplace(Ctx.clone()); + This is a little unfortunate. Oh, well. Comment at: clangd/Trace.h:42 +/// set up before calling any clangd-specific functions. +class TracingSession { +public: hmm, `trace::TracingSession` seems redundant? Up to you Repository: rCTE Clang Tools Extra https://reviews.llvm.org/D40488 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D40488: [clangd] Implemented tracing using Context
ilya-biryukov updated this revision to Diff 126748. ilya-biryukov added a comment. Merged with head Repository: rCTE Clang Tools Extra https://reviews.llvm.org/D40488 Files: clangd/ClangdUnit.cpp clangd/JSONRPCDispatcher.cpp clangd/Trace.cpp clangd/Trace.h clangd/tool/ClangdMain.cpp unittests/clangd/TraceTests.cpp Index: unittests/clangd/TraceTests.cpp === --- unittests/clangd/TraceTests.cpp +++ unittests/clangd/TraceTests.cpp @@ -7,6 +7,7 @@ // //===--===// +#include "Context.h" #include "Trace.h" #include "llvm/ADT/DenseMap.h" @@ -74,10 +75,11 @@ std::string JSON; { raw_string_ostream OS(JSON); -auto Session = trace::Session::create(OS); +auto JSONTracer = trace::createJSONTracer(OS); +trace::TracingSession Session(*JSONTracer); { - trace::Span S("A"); - trace::log("B"); + trace::Span S(Context::empty(), "A"); + trace::log(Context::empty(), "B"); } } Index: clangd/tool/ClangdMain.cpp === --- clangd/tool/ClangdMain.cpp +++ clangd/tool/ClangdMain.cpp @@ -115,19 +115,25 @@ << EC.message(); } } + + // Setup tracing facilities. llvm::Optional TraceStream; - std::unique_ptr TraceSession; + std::unique_ptr Tracer; if (!TraceFile.empty()) { std::error_code EC; TraceStream.emplace(TraceFile, /*ref*/ EC, llvm::sys::fs::F_RW); if (EC) { TraceFile.reset(); llvm::errs() << "Error while opening trace file: " << EC.message(); } else { - TraceSession = trace::Session::create(*TraceStream, PrettyPrint); + Tracer = trace::createJSONTracer(*TraceStream, PrettyPrint); } } + llvm::Optional TracingSession; + if (Tracer) +TracingSession.emplace(*Tracer); + llvm::raw_ostream = llvm::outs(); llvm::raw_ostream = llvm::errs(); JSONOutput Out(Outs, Logs, Index: clangd/Trace.h === --- clangd/Trace.h +++ clangd/Trace.h @@ -8,60 +8,74 @@ //===--===// // // Supports writing performance traces describing clangd's behavior. -// Traces are written in the Trace Event format supported by chrome's trace -// viewer (chrome://tracing). +// Traces are consumed by implementations of the EventTracer interface. // -// The format is documented here: -// https://docs.google.com/document/d/1CvAClvFfyA5R-PhYUmn5OOQtYMH4h6I0nSsKchNAySU/preview // // All APIs are no-ops unless a Session is active (created by ClangdMain). // //===--===// #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANGD_TRACE_H_ #define LLVM_CLANG_TOOLS_EXTRA_CLANGD_TRACE_H_ +#include "Context.h" #include "JSONExpr.h" #include "llvm/ADT/Twine.h" #include "llvm/Support/raw_ostream.h" namespace clang { namespace clangd { namespace trace { -// A session directs the output of trace events. Only one Session can exist. -// It should be created before clangd threads are spawned, and destroyed after -// they exit. -// TODO: we may want to add pluggable support for other tracing backends. -class Session { +/// A consumer of trace events. The events are produced by Spans and trace::log. +class EventTracer { public: - // Starts a sessions capturing trace events and writing Trace Event JSON. - static std::unique_ptr create(llvm::raw_ostream , - bool Pretty = false); - ~Session(); + virtual ~EventTracer() = default; + /// Consume a trace event. + virtual void event(const Context , llvm::StringRef Phase, + json::obj &) = 0; +}; -private: - Session() = default; +/// Sets up a global EventTracer that consumes events produced by Span and +/// trace::log. Only one TracingSession can be active at a time and it should be +/// set up before calling any clangd-specific functions. +class TracingSession { +public: + TracingSession(EventTracer ); + ~TracingSession(); }; -// Records a single instant event, associated with the current thread. -void log(const llvm::Twine ); +/// Create an instance of EventTracer that produces an output in the Trace Event +/// format supported by Chrome's trace viewer (chrome://tracing). +/// +/// 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 createJSONTracer(llvm::raw_ostream , + bool Pretty = false); -// Records an event whose duration is the lifetime of the Span object. -// -// Arbitrary JSON metadata can be attached while this span is
[PATCH] D40488: [clangd] Implemented tracing using Context
ilya-biryukov updated this revision to Diff 126376. ilya-biryukov added a comment. - Use derive(key, value) instead of derive().add(key, value). Repository: rCTE Clang Tools Extra https://reviews.llvm.org/D40488 Files: clangd/ClangdUnit.cpp clangd/JSONRPCDispatcher.cpp clangd/Trace.cpp clangd/Trace.h clangd/tool/ClangdMain.cpp unittests/clangd/TraceTests.cpp Index: unittests/clangd/TraceTests.cpp === --- unittests/clangd/TraceTests.cpp +++ unittests/clangd/TraceTests.cpp @@ -7,6 +7,7 @@ // //===--===// +#include "Context.h" #include "Trace.h" #include "llvm/ADT/DenseMap.h" @@ -74,10 +75,11 @@ std::string JSON; { raw_string_ostream OS(JSON); -auto Session = trace::Session::create(OS); +auto JSONTracer = trace::createJSONTracer(OS); +trace::TracingSession Session(*JSONTracer); { - trace::Span S("A"); - trace::log("B"); + trace::Span S(Context::empty(), "A"); + trace::log(Context::empty(), "B"); } } Index: clangd/tool/ClangdMain.cpp === --- clangd/tool/ClangdMain.cpp +++ clangd/tool/ClangdMain.cpp @@ -115,19 +115,25 @@ << EC.message(); } } + + // Setup tracing facilities. llvm::Optional TraceStream; - std::unique_ptr TraceSession; + std::unique_ptr Tracer; if (!TraceFile.empty()) { std::error_code EC; TraceStream.emplace(TraceFile, /*ref*/ EC, llvm::sys::fs::F_RW); if (EC) { TraceFile.reset(); llvm::errs() << "Error while opening trace file: " << EC.message(); } else { - TraceSession = trace::Session::create(*TraceStream, PrettyPrint); + Tracer = trace::createJSONTracer(*TraceStream, PrettyPrint); } } + llvm::Optional TracingSession; + if (Tracer) +TracingSession.emplace(*Tracer); + llvm::raw_ostream = llvm::outs(); llvm::raw_ostream = llvm::errs(); JSONOutput Out(Outs, Logs, Index: clangd/Trace.h === --- clangd/Trace.h +++ clangd/Trace.h @@ -8,60 +8,74 @@ //===--===// // // Supports writing performance traces describing clangd's behavior. -// Traces are written in the Trace Event format supported by chrome's trace -// viewer (chrome://tracing). +// Traces are consumed by implementations of the EventTracer interface. // -// The format is documented here: -// https://docs.google.com/document/d/1CvAClvFfyA5R-PhYUmn5OOQtYMH4h6I0nSsKchNAySU/preview // // All APIs are no-ops unless a Session is active (created by ClangdMain). // //===--===// #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANGD_TRACE_H_ #define LLVM_CLANG_TOOLS_EXTRA_CLANGD_TRACE_H_ +#include "Context.h" #include "JSONExpr.h" #include "llvm/ADT/Twine.h" #include "llvm/Support/raw_ostream.h" namespace clang { namespace clangd { namespace trace { -// A session directs the output of trace events. Only one Session can exist. -// It should be created before clangd threads are spawned, and destroyed after -// they exit. -// TODO: we may want to add pluggable support for other tracing backends. -class Session { +/// A consumer of trace events. The events are produced by Spans and trace::log. +class EventTracer { public: - // Starts a sessions capturing trace events and writing Trace Event JSON. - static std::unique_ptr create(llvm::raw_ostream , - bool Pretty = false); - ~Session(); + virtual ~EventTracer() = default; + /// Consume a trace event. + virtual void event(const Context , llvm::StringRef Phase, + json::obj &) = 0; +}; -private: - Session() = default; +/// Sets up a global EventTracer that consumes events produced by Span and +/// trace::log. Only one TracingSession can be active at a time and it should be +/// set up before calling any clangd-specific functions. +class TracingSession { +public: + TracingSession(EventTracer ); + ~TracingSession(); }; -// Records a single instant event, associated with the current thread. -void log(const llvm::Twine ); +/// Create an instance of EventTracer that produces an output in the Trace Event +/// format supported by Chrome's trace viewer (chrome://tracing). +/// +/// 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 createJSONTracer(llvm::raw_ostream , + bool Pretty = false); -// Records an event whose duration is the lifetime of the Span object. -// -// Arbitrary JSON
[PATCH] D40488: [clangd] Implemented tracing using Context
ilya-biryukov updated this revision to Diff 126328. ilya-biryukov added a comment. Updated the patch after changes to Context Repository: rCTE Clang Tools Extra https://reviews.llvm.org/D40488 Files: clangd/ClangdUnit.cpp clangd/JSONRPCDispatcher.cpp clangd/Trace.cpp clangd/Trace.h clangd/tool/ClangdMain.cpp unittests/clangd/TraceTests.cpp Index: unittests/clangd/TraceTests.cpp === --- unittests/clangd/TraceTests.cpp +++ unittests/clangd/TraceTests.cpp @@ -7,6 +7,7 @@ // //===--===// +#include "Context.h" #include "Trace.h" #include "llvm/ADT/DenseMap.h" @@ -74,10 +75,11 @@ std::string JSON; { raw_string_ostream OS(JSON); -auto Session = trace::Session::create(OS); +auto JSONTracer = trace::createJSONTracer(OS); +trace::TracingSession Session(*JSONTracer); { - trace::Span S("A"); - trace::log("B"); + trace::Span S(Context::empty(), "A"); + trace::log(Context::empty(), "B"); } } Index: clangd/tool/ClangdMain.cpp === --- clangd/tool/ClangdMain.cpp +++ clangd/tool/ClangdMain.cpp @@ -115,19 +115,25 @@ << EC.message(); } } + + // Setup tracing facilities. llvm::Optional TraceStream; - std::unique_ptr TraceSession; + std::unique_ptr Tracer; if (!TraceFile.empty()) { std::error_code EC; TraceStream.emplace(TraceFile, /*ref*/ EC, llvm::sys::fs::F_RW); if (EC) { TraceFile.reset(); llvm::errs() << "Error while opening trace file: " << EC.message(); } else { - TraceSession = trace::Session::create(*TraceStream, PrettyPrint); + Tracer = trace::createJSONTracer(*TraceStream, PrettyPrint); } } + llvm::Optional TracingSession; + if (Tracer) +TracingSession.emplace(*Tracer); + llvm::raw_ostream = llvm::outs(); llvm::raw_ostream = llvm::errs(); JSONOutput Out(Outs, Logs, Index: clangd/Trace.h === --- clangd/Trace.h +++ clangd/Trace.h @@ -8,60 +8,74 @@ //===--===// // // Supports writing performance traces describing clangd's behavior. -// Traces are written in the Trace Event format supported by chrome's trace -// viewer (chrome://tracing). +// Traces are consumed by implementations of the EventTracer interface. // -// The format is documented here: -// https://docs.google.com/document/d/1CvAClvFfyA5R-PhYUmn5OOQtYMH4h6I0nSsKchNAySU/preview // // All APIs are no-ops unless a Session is active (created by ClangdMain). // //===--===// #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANGD_TRACE_H_ #define LLVM_CLANG_TOOLS_EXTRA_CLANGD_TRACE_H_ +#include "Context.h" #include "JSONExpr.h" #include "llvm/ADT/Twine.h" #include "llvm/Support/raw_ostream.h" namespace clang { namespace clangd { namespace trace { -// A session directs the output of trace events. Only one Session can exist. -// It should be created before clangd threads are spawned, and destroyed after -// they exit. -// TODO: we may want to add pluggable support for other tracing backends. -class Session { +/// A consumer of trace events. The events are produced by Spans and trace::log. +class EventTracer { public: - // Starts a sessions capturing trace events and writing Trace Event JSON. - static std::unique_ptr create(llvm::raw_ostream , - bool Pretty = false); - ~Session(); + virtual ~EventTracer() = default; + /// Consume a trace event. + virtual void event(const Context , llvm::StringRef Phase, + json::obj &) = 0; +}; -private: - Session() = default; +/// Sets up a global EventTracer that consumes events produced by Span and +/// trace::log. Only one TracingSession can be active at a time and it should be +/// set up before calling any clangd-specific functions. +class TracingSession { +public: + TracingSession(EventTracer ); + ~TracingSession(); }; -// Records a single instant event, associated with the current thread. -void log(const llvm::Twine ); +/// Create an instance of EventTracer that produces an output in the Trace Event +/// format supported by Chrome's trace viewer (chrome://tracing). +/// +/// 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 createJSONTracer(llvm::raw_ostream , + bool Pretty = false); -// Records an event whose duration is the lifetime of the Span object. -// -// Arbitrary JSON metadata can be
[PATCH] D40488: [clangd] Implemented tracing using Context
ilya-biryukov updated this revision to Diff 125713. ilya-biryukov added a comment. - Use getExistingKey instead of getPtr in JSONRPCDispatcher. Repository: rCTE Clang Tools Extra https://reviews.llvm.org/D40488 Files: clangd/ClangdUnit.cpp clangd/JSONRPCDispatcher.cpp clangd/Trace.cpp clangd/Trace.h clangd/tool/ClangdMain.cpp unittests/clangd/TraceTests.cpp Index: unittests/clangd/TraceTests.cpp === --- unittests/clangd/TraceTests.cpp +++ unittests/clangd/TraceTests.cpp @@ -7,6 +7,7 @@ // //===--===// +#include "Context.h" #include "Trace.h" #include "llvm/ADT/DenseMap.h" @@ -74,10 +75,11 @@ std::string JSON; { raw_string_ostream OS(JSON); -auto Session = trace::Session::create(OS); +auto JSONTracer = trace::createJSONTracer(OS); +trace::TracingSession Session(*JSONTracer); { - trace::Span S("A"); - trace::log("B"); + trace::Span S(emptyCtx(), "A"); + trace::log(emptyCtx(), "B"); } } Index: clangd/tool/ClangdMain.cpp === --- clangd/tool/ClangdMain.cpp +++ clangd/tool/ClangdMain.cpp @@ -115,19 +115,25 @@ << EC.message(); } } + + // Setup tracing facilities. llvm::Optional TraceStream; - std::unique_ptr TraceSession; + std::unique_ptr Tracer; if (!TraceFile.empty()) { std::error_code EC; TraceStream.emplace(TraceFile, /*ref*/ EC, llvm::sys::fs::F_RW); if (EC) { TraceFile.reset(); llvm::errs() << "Error while opening trace file: " << EC.message(); } else { - TraceSession = trace::Session::create(*TraceStream, PrettyPrint); + Tracer = trace::createJSONTracer(*TraceStream, PrettyPrint); } } + llvm::Optional TracingSession; + if (Tracer) +TracingSession.emplace(*Tracer); + llvm::raw_ostream = llvm::outs(); llvm::raw_ostream = llvm::errs(); JSONOutput Out(Outs, Logs, Index: clangd/Trace.h === --- clangd/Trace.h +++ clangd/Trace.h @@ -8,60 +8,74 @@ //===--===// // // Supports writing performance traces describing clangd's behavior. -// Traces are written in the Trace Event format supported by chrome's trace -// viewer (chrome://tracing). +// Traces are consumed by implementations of the EventTracer interface. // -// The format is documented here: -// https://docs.google.com/document/d/1CvAClvFfyA5R-PhYUmn5OOQtYMH4h6I0nSsKchNAySU/preview // // All APIs are no-ops unless a Session is active (created by ClangdMain). // //===--===// #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANGD_TRACE_H_ #define LLVM_CLANG_TOOLS_EXTRA_CLANGD_TRACE_H_ +#include "Context.h" #include "JSONExpr.h" #include "llvm/ADT/Twine.h" #include "llvm/Support/raw_ostream.h" namespace clang { namespace clangd { namespace trace { -// A session directs the output of trace events. Only one Session can exist. -// It should be created before clangd threads are spawned, and destroyed after -// they exit. -// TODO: we may want to add pluggable support for other tracing backends. -class Session { +/// A consumer of trace events. The events are produced by Spans and trace::log. +class EventTracer { public: - // Starts a sessions capturing trace events and writing Trace Event JSON. - static std::unique_ptr create(llvm::raw_ostream , - bool Pretty = false); - ~Session(); + virtual ~EventTracer() = default; + /// Consume a trace event. + virtual void event(const ContextData , llvm::StringRef Phase, + json::obj &) = 0; +}; -private: - Session() = default; +/// Sets up a global EventTracer that consumes events produced by Span and +/// trace::log. Only one TracingSession can be active at a time and it should be +/// set up before calling any clangd-specific functions. +class TracingSession { +public: + TracingSession(EventTracer ); + ~TracingSession(); }; -// Records a single instant event, associated with the current thread. -void log(const llvm::Twine ); +/// Create an instance of EventTracer that produces an output in the Trace Event +/// format supported by Chrome's trace viewer (chrome://tracing). +/// +/// 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 createJSONTracer(llvm::raw_ostream , + bool Pretty = false); -// Records an event whose duration is the lifetime of the Span object. -// -// Arbitrary JSON metadata can
[PATCH] D40488: [clangd] Implemented tracing using Context
ilya-biryukov updated this revision to Diff 125690. ilya-biryukov added a comment. Herald added a subscriber: klimek. - Updated tracing to use the new Context implementation. - Restored global tracer. Repository: rCTE Clang Tools Extra https://reviews.llvm.org/D40488 Files: clangd/ClangdUnit.cpp clangd/JSONRPCDispatcher.cpp clangd/Trace.cpp clangd/Trace.h clangd/tool/ClangdMain.cpp unittests/clangd/TraceTests.cpp Index: unittests/clangd/TraceTests.cpp === --- unittests/clangd/TraceTests.cpp +++ unittests/clangd/TraceTests.cpp @@ -7,6 +7,7 @@ // //===--===// +#include "Context.h" #include "Trace.h" #include "llvm/ADT/DenseMap.h" @@ -74,10 +75,11 @@ std::string JSON; { raw_string_ostream OS(JSON); -auto Session = trace::Session::create(OS); +auto JSONTracer = trace::createJSONTracer(OS); +trace::TracingSession Session(*JSONTracer); { - trace::Span S("A"); - trace::log("B"); + trace::Span S(emptyCtx(), "A"); + trace::log(emptyCtx(), "B"); } } Index: clangd/tool/ClangdMain.cpp === --- clangd/tool/ClangdMain.cpp +++ clangd/tool/ClangdMain.cpp @@ -115,19 +115,25 @@ << EC.message(); } } + + // Setup tracing facilities. llvm::Optional TraceStream; - std::unique_ptr TraceSession; + std::unique_ptr Tracer; if (!TraceFile.empty()) { std::error_code EC; TraceStream.emplace(TraceFile, /*ref*/ EC, llvm::sys::fs::F_RW); if (EC) { TraceFile.reset(); llvm::errs() << "Error while opening trace file: " << EC.message(); } else { - TraceSession = trace::Session::create(*TraceStream, PrettyPrint); + Tracer = trace::createJSONTracer(*TraceStream, PrettyPrint); } } + llvm::Optional TracingSession; + if (Tracer) +TracingSession.emplace(*Tracer); + llvm::raw_ostream = llvm::outs(); llvm::raw_ostream = llvm::errs(); JSONOutput Out(Outs, Logs, Index: clangd/Trace.h === --- clangd/Trace.h +++ clangd/Trace.h @@ -8,60 +8,74 @@ //===--===// // // Supports writing performance traces describing clangd's behavior. -// Traces are written in the Trace Event format supported by chrome's trace -// viewer (chrome://tracing). +// Traces are consumed by implementations of the EventTracer interface. // -// The format is documented here: -// https://docs.google.com/document/d/1CvAClvFfyA5R-PhYUmn5OOQtYMH4h6I0nSsKchNAySU/preview // // All APIs are no-ops unless a Session is active (created by ClangdMain). // //===--===// #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANGD_TRACE_H_ #define LLVM_CLANG_TOOLS_EXTRA_CLANGD_TRACE_H_ +#include "Context.h" #include "JSONExpr.h" #include "llvm/ADT/Twine.h" #include "llvm/Support/raw_ostream.h" namespace clang { namespace clangd { namespace trace { -// A session directs the output of trace events. Only one Session can exist. -// It should be created before clangd threads are spawned, and destroyed after -// they exit. -// TODO: we may want to add pluggable support for other tracing backends. -class Session { +/// A consumer of trace events. The events are produced by Spans and trace::log. +class EventTracer { public: - // Starts a sessions capturing trace events and writing Trace Event JSON. - static std::unique_ptr create(llvm::raw_ostream , - bool Pretty = false); - ~Session(); + virtual ~EventTracer() = default; + /// Consume a trace event. + virtual void event(const ContextData , llvm::StringRef Phase, + json::obj &) = 0; +}; -private: - Session() = default; +/// Sets up a global EventTracer that consumes events produced by Span and +/// trace::log. Only one TracingSession can be active at a time and it should be +/// set up before calling any clangd-specific functions. +class TracingSession { +public: + TracingSession(EventTracer ); + ~TracingSession(); }; -// Records a single instant event, associated with the current thread. -void log(const llvm::Twine ); +/// Create an instance of EventTracer that produces an output in the Trace Event +/// format supported by Chrome's trace viewer (chrome://tracing). +/// +/// 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 createJSONTracer(llvm::raw_ostream , + bool Pretty = false); -// Records an event whose duration is the lifetime
[PATCH] D40488: [clangd] Implemented tracing using Context
ilya-biryukov planned changes to this revision. ilya-biryukov added inline comments. Comment at: clangd/JSONRPCDispatcher.h:80 + // Ctx must be before Tracer! Context Ctx; JSONOutput This is still wrong, `Context` is used by `Tracer` internally and should not be moved. https://reviews.llvm.org/D40488 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D40488: [clangd] Implemented tracing using Context
ilya-biryukov created this revision. https://reviews.llvm.org/D40488 Files: clangd/ClangdUnit.cpp clangd/JSONRPCDispatcher.cpp clangd/JSONRPCDispatcher.h clangd/ProtocolHandlers.cpp clangd/Trace.cpp clangd/Trace.h clangd/tool/ClangdMain.cpp unittests/clangd/TraceTests.cpp Index: unittests/clangd/TraceTests.cpp === --- unittests/clangd/TraceTests.cpp +++ unittests/clangd/TraceTests.cpp @@ -7,6 +7,7 @@ // //===--===// +#include "Context.h" #include "Trace.h" #include "llvm/ADT/DenseMap.h" @@ -74,10 +75,12 @@ std::string JSON; { raw_string_ostream OS(JSON); -auto Session = trace::Session::create(OS); +auto JSONTracer = trace::createJSONTracer(OS); +Context TraceCtx = +buildCtx().add(trace::EventTracer::CtxKey, JSONTracer.get()); { - trace::Span S("A"); - trace::log("B"); + trace::Span S(TraceCtx, "A"); + trace::log(TraceCtx, "B"); } } Index: clangd/tool/ClangdMain.cpp === --- clangd/tool/ClangdMain.cpp +++ clangd/tool/ClangdMain.cpp @@ -116,15 +116,15 @@ } } llvm::Optional TraceStream; - std::unique_ptr TraceSession; + std::unique_ptr TraceSession; if (!TraceFile.empty()) { std::error_code EC; TraceStream.emplace(TraceFile, /*ref*/ EC, llvm::sys::fs::F_RW); if (EC) { TraceFile.reset(); llvm::errs() << "Error while opening trace file: " << EC.message(); } else { - TraceSession = trace::Session::create(*TraceStream, PrettyPrint); + TraceSession = trace::createJSONTracer(*TraceStream, PrettyPrint); } } @@ -134,7 +134,11 @@ InputMirrorStream ? InputMirrorStream.getPointer() : nullptr, PrettyPrint); - GlobalSession Session(buildCtx().add(Logger::CtxKey, )); + TypedValueMap ContextMap; + ContextMap.emplace(Logger::CtxKey, ); + if (TraceSession) +ContextMap.emplace(trace::EventTracer::CtxKey, TraceSession.get()); + GlobalSession Session(Context(/*Parent=*/nullptr, std::move(ContextMap))); // If --compile-commands-dir arg was invoked, check value and override default // path. Index: clangd/Trace.h === --- clangd/Trace.h +++ clangd/Trace.h @@ -8,60 +8,64 @@ //===--===// // // Supports writing performance traces describing clangd's behavior. -// Traces are written in the Trace Event format supported by chrome's trace -// viewer (chrome://tracing). +// Traces are consumed by implementations of the EventTracer interface. // -// The format is documented here: -// https://docs.google.com/document/d/1CvAClvFfyA5R-PhYUmn5OOQtYMH4h6I0nSsKchNAySU/preview // // All APIs are no-ops unless a Session is active (created by ClangdMain). // //===--===// #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANGD_TRACE_H_ #define LLVM_CLANG_TOOLS_EXTRA_CLANGD_TRACE_H_ +#include "Context.h" #include "JSONExpr.h" #include "llvm/ADT/Twine.h" #include "llvm/Support/raw_ostream.h" namespace clang { namespace clangd { namespace trace { -// A session directs the output of trace events. Only one Session can exist. -// It should be created before clangd threads are spawned, and destroyed after -// they exit. -// TODO: we may want to add pluggable support for other tracing backends. -class Session { +class EventTracer { public: - // Starts a sessions capturing trace events and writing Trace Event JSON. - static std::unique_ptr create(llvm::raw_ostream , - bool Pretty = false); - ~Session(); + static PtrKey CtxKey; -private: - Session() = default; + virtual ~EventTracer() = default; + virtual void event(llvm::StringRef Phase, json::obj &) = 0; }; -// Records a single instant event, associated with the current thread. -void log(const llvm::Twine ); +/// Create an instance of EventTracer that produces an output in the Trace Event +/// format supported by Chrome's trace viewer (chrome://tracing). +/// +/// 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 createJSONTracer(llvm::raw_ostream , + bool Pretty = false); -// Records an event whose duration is the lifetime of the Span object. -// -// Arbitrary JSON metadata can be attached while this span is active: -// SPAN_ATTACH(MySpan, "Payload", SomeJSONExpr); -// SomeJSONExpr is evaluated and copied only if actually needed. +/// Records a single instant event, associated