//===--- Trace.h - Performance tracing facilities ---------------*- C++ -*-===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // // Supports writing performance traces describing clangd's behavior. // Traces are consumed by implementations of the EventTracer interface. // // // All APIs are no-ops unless a Session is active (created by ClangdMain). // //===----------------------------------------------------------------------===// #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANGD_SUPPORT_TRACE_H #define LLVM_CLANG_TOOLS_EXTRA_CLANGD_SUPPORT_TRACE_H #include "support/Context.h" #include "llvm/ADT/StringRef.h" #include "llvm/ADT/Twine.h" #include "llvm/Support/JSON.h" #include "llvm/Support/raw_ostream.h" #include <chrono> #include <string> #include <vector> namespace clang { namespace clangd { namespace trace { /// Represents measurements of clangd events, e.g. operation latency. Those /// measurements are recorded per-label, defaulting to an empty one for metrics /// that don't care about it. This enables aggregation of measurements across /// labels. For example a metric tracking accesses to a cache can have labels /// named hit and miss. struct Metric { … }; /// A consumer of trace events and measurements. The events are produced by /// Spans and trace::log, the measurements are produced by Metrics::record. /// Implementations of this interface must be thread-safe. class EventTracer { … }; /// 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 { … }; /// Create an instance of EventTracer that produces an output in the Trace Event /// format supported by Chrome's trace viewer (chrome://tracing). /// /// FIXME: Metrics are not recorded, some could become counter events. /// /// The format is documented here: /// https://docs.google.com/document/d/1CvAClvFfyA5R-PhYUmn5OOQtYMH4h6I0nSsKchNAySU/preview std::unique_ptr<EventTracer> createJSONTracer(llvm::raw_ostream &OS, bool Pretty = false); /// Create an instance of EventTracer that outputs metric measurements as CSV. /// /// Trace spans and instant events are ignored. std::unique_ptr<EventTracer> createCSVMetricTracer(llvm::raw_ostream &OS); /// Records a single instant event, associated with the current thread. void log(const llvm::Twine &Name); /// Returns true if there is an active tracer. bool enabled(); /// Records an event whose duration is the lifetime of the Span object. /// This lifetime is extended when the span's context is reused. /// /// 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 { … }; /// Attach a key-value pair to a Span event. /// This is not threadsafe when used with the same Span. #define SPAN_ATTACH(S, Name, Expr) … } // namespace trace } // namespace clangd } // namespace clang #endif