Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-10 08:44:37

0001 //===----------------------------------------------------------------------===//
0002 //
0003 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
0004 // See https://llvm.org/LICENSE.txt for license information.
0005 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
0006 //
0007 //===----------------------------------------------------------------------===//
0008 ///
0009 /// \file
0010 /// This file provides the basic framework for Telemetry.
0011 /// Refer to its documentation at llvm/docs/Telemetry.rst for more details.
0012 //===---------------------------------------------------------------------===//
0013 
0014 #ifndef LLVM_TELEMETRY_TELEMETRY_H
0015 #define LLVM_TELEMETRY_TELEMETRY_H
0016 
0017 #include "llvm/ADT/DenseMap.h"
0018 #include "llvm/ADT/StringExtras.h"
0019 #include "llvm/ADT/StringRef.h"
0020 #include "llvm/Support/Error.h"
0021 #include <map>
0022 #include <memory>
0023 #include <optional>
0024 #include <string>
0025 #include <type_traits>
0026 #include <vector>
0027 
0028 namespace llvm {
0029 namespace telemetry {
0030 
0031 class Serializer {
0032 public:
0033   virtual ~Serializer() = default;
0034 
0035   virtual Error init() = 0;
0036   virtual void write(StringRef KeyName, bool Value) = 0;
0037   virtual void write(StringRef KeyName, StringRef Value) = 0;
0038   virtual void write(StringRef KeyName, int Value) = 0;
0039   virtual void write(StringRef KeyName, long Value) = 0;
0040   virtual void write(StringRef KeyName, long long Value) = 0;
0041   virtual void write(StringRef KeyName, unsigned int Value) = 0;
0042   virtual void write(StringRef KeyName, unsigned long Value) = 0;
0043   virtual void write(StringRef KeyName, unsigned long long Value) = 0;
0044   virtual void beginObject(StringRef KeyName) = 0;
0045   virtual void endObject() = 0;
0046   virtual Error finalize() = 0;
0047 
0048   template <typename T, typename = typename T::mapped_type>
0049   void write(StringRef KeyName, const T &Map) {
0050     static_assert(std::is_convertible_v<typename T::key_type, StringRef>,
0051                   "KeyType must be convertible to string");
0052     beginObject(KeyName);
0053     for (const auto &KeyVal : Map)
0054       write(KeyVal.first, KeyVal.second);
0055     endObject();
0056   }
0057 };
0058 
0059 /// Configuration for the Manager class.
0060 /// This stores configurations from both users and vendors and is passed
0061 /// to the Manager upon construction. (Any changes to the config after
0062 /// the Manager's construction will not have any effect on it).
0063 ///
0064 /// This struct can be extended as needed to add additional configuration
0065 /// points specific to a vendor's implementation.
0066 struct Config {
0067   virtual ~Config() = default;
0068 
0069   // If true, telemetry will be enabled.
0070   const bool EnableTelemetry;
0071   Config(bool E) : EnableTelemetry(E) {}
0072 
0073   virtual std::optional<std::string> makeSessionId() { return std::nullopt; }
0074 };
0075 
0076 /// For isa, dyn_cast, etc operations on TelemetryInfo.
0077 typedef unsigned KindType;
0078 /// This struct is used by TelemetryInfo to support isa<>, dyn_cast<>
0079 /// operations.
0080 /// It is defined as a struct (rather than an enum) because it is
0081 /// expected to be extended by subclasses which may have
0082 /// additional TelemetryInfo types defined to describe different events.
0083 struct EntryKind {
0084   static const KindType Base = 0;
0085 };
0086 
0087 /// TelemetryInfo is the data courier, used to move instrumented data
0088 /// from the tool being monitored to the Telemetry framework.
0089 ///
0090 /// This base class contains only the basic set of telemetry data.
0091 /// Downstream implementations can define more subclasses with
0092 /// additional fields to describe different events and concepts.
0093 ///
0094 /// For example, The LLDB debugger can define a DebugCommandInfo subclass
0095 /// which has additional fields about the debug-command being instrumented,
0096 /// such as `CommandArguments` or `CommandName`.
0097 struct TelemetryInfo {
0098   // This represents a unique-id, conventionally corresponding to
0099   // a tool's session - i.e., every time the tool starts until it exits.
0100   //
0101   // Note: a tool could have multiple sessions running at once, in which
0102   // case, these shall be multiple sets of TelemetryInfo with multiple unique
0103   // IDs.
0104   //
0105   // Different usages can assign different types of IDs to this field.
0106   std::string SessionId;
0107 
0108   TelemetryInfo() = default;
0109   virtual ~TelemetryInfo() = default;
0110 
0111   virtual void serialize(Serializer &serializer) const;
0112 
0113   // For isa, dyn_cast, etc, operations.
0114   virtual KindType getKind() const { return EntryKind::Base; }
0115   static bool classof(const TelemetryInfo *T) {
0116     return T->getKind() == EntryKind::Base;
0117   }
0118 };
0119 
0120 /// This class presents a data sink to which the Telemetry framework
0121 /// sends data.
0122 ///
0123 /// Its implementation is transparent to the framework.
0124 /// It is up to the vendor to decide which pieces of data to forward
0125 /// and where to forward them.
0126 class Destination {
0127 public:
0128   virtual ~Destination() = default;
0129   virtual Error receiveEntry(const TelemetryInfo *Entry) = 0;
0130   virtual StringLiteral name() const = 0;
0131 };
0132 
0133 /// This class is the main interaction point between any LLVM tool
0134 /// and this framework.
0135 /// It is responsible for collecting telemetry data from the tool being
0136 /// monitored and transmitting the data elsewhere.
0137 class Manager {
0138 public:
0139   virtual ~Manager() = default;
0140 
0141   // Optional callback for subclasses to perform additional tasks before
0142   // dispatching to Destinations.
0143   virtual Error preDispatch(TelemetryInfo *Entry) = 0;
0144 
0145   // Dispatch Telemetry data to the Destination(s).
0146   // The argument is non-const because the Manager may add or remove
0147   // data from the entry.
0148   virtual Error dispatch(TelemetryInfo *Entry);
0149 
0150   // Register a Destination.
0151   void addDestination(std::unique_ptr<Destination> Destination);
0152 
0153 private:
0154   std::vector<std::unique_ptr<Destination>> Destinations;
0155 };
0156 
0157 } // namespace telemetry
0158 } // namespace llvm
0159 
0160 #endif // LLVM_TELEMETRY_TELEMETRY_H