[llvm] [llvm][lib]Propose a simple Telemetry framework. (PR #102323)

Vy Nguyen via llvm-commits llvm-commits at lists.llvm.org
Wed Aug 7 08:14:10 PDT 2024


https://github.com/oontvoo created https://github.com/llvm/llvm-project/pull/102323

Objective:

-  Provide a common framework in LLVM for collecting various usage metrics
-  Characteristics: 
  -   Extensible and configurable by: 
    -  tools in LLVM that want to use it 
    -  vendors in their downstream codebase 
    -  tools users (as allowed by vendor)

See also PR/98528 where the framework is extended and used.
Background:
The framework was originally proposed only for LLDB, but there were quite a few requests that it should be moved to llvm/lib given telemetry is a common usage to a lot of tools, not just LLDB.

See more details on the design and discussions here on the RFC: https://discourse.llvm.org/t/rfc-lldb-telemetry-metrics/64588/20?u=oontvoo



>From dbb8b15edb5e63f37a66dd15e67d46ee1b4f6c1b Mon Sep 17 00:00:00 2001
From: Vy Nguyen <vyng at google.com>
Date: Wed, 7 Aug 2024 11:08:44 -0400
Subject: [PATCH] [llvm][lib]Propose a simple Telemetry framework.

Objective:
  - Provide a common framework in LLVM for collecting various usage metrics
  - Characteristics:
      + Extensible and configurable by:
          * tools in LLVM that want to use it
          * vendors in their downstream codebase
          * tools users (as allowed by vendor)

Background:
The framework was originally proposed only for LLDB, but there were quite a few requests
that it should be moved to llvm/lib given telemetry is a common usage to a lot of tools,
not just LLDB.

See more details on the design and discussions here on the RFC: https://discourse.llvm.org/t/rfc-lldb-telemetry-metrics/64588/20?u=oontvoo
---
 llvm/include/llvm/Telemetry/Telemetry.h | 99 +++++++++++++++++++++++++
 llvm/lib/CMakeLists.txt                 |  1 +
 llvm/lib/Telemetry/CMakeLists.txt       |  6 ++
 llvm/lib/Telemetry/Telemetry.cpp        | 32 ++++++++
 4 files changed, 138 insertions(+)
 create mode 100644 llvm/include/llvm/Telemetry/Telemetry.h
 create mode 100644 llvm/lib/Telemetry/CMakeLists.txt
 create mode 100644 llvm/lib/Telemetry/Telemetry.cpp

diff --git a/llvm/include/llvm/Telemetry/Telemetry.h b/llvm/include/llvm/Telemetry/Telemetry.h
new file mode 100644
index 00000000000000..e34b228b219c10
--- /dev/null
+++ b/llvm/include/llvm/Telemetry/Telemetry.h
@@ -0,0 +1,99 @@
+#ifndef LVM_TELEMETRY_TELEMETRY_H
+#define LVM_TELEMETRY_TELEMETRY_H
+
+#include <chrono>
+#include <ctime>
+#include <memory>
+#include <optional>
+#include <string>
+
+#include "llvm/ADT/StringExtras.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/Error.h"
+#include "llvm/Support/JSON.h"
+
+namespace llvm {
+namespace telemetry {
+
+using SteadyTimePoint = std::chrono::time_point<std::chrono::steady_clock>;
+
+struct TelemetryConfig {
+  // If true, telemetry will be enabled.
+  bool enable_telemetry;
+
+  // Additional destinations to send the logged entries.
+  // Could be stdout, stderr, or some local paths.
+  // Note: these are destinations are __in addition to__ whatever the default
+  // destination(s) are, as implemented by vendors.
+  std::vector<std::string> additional_destinations;
+};
+
+struct TelemetryEventStats {
+  // REQUIRED: Start time of event
+  SteadyTimePoint m_start;
+  // OPTIONAL: End time of event - may be empty if not meaningful.
+  std::optional<SteadyTimePoint> m_end;
+  // TBD: could add some memory stats here too?
+
+  TelemetryEventStats() = default;
+  TelemetryEventStats(SteadyTimePoint start) : m_start(start) {}
+  TelemetryEventStats(SteadyTimePoint start, SteadyTimePoint end)
+      : m_start(start), m_end(end) {}
+
+  std::string ToString() const;
+};
+
+struct ExitDescription {
+  int exit_code;
+  std::string description;
+
+  std::string ToString() const;
+};
+
+// The base class contains the basic set of data.
+// Downstream implementations can add more fields as needed.
+struct TelemetryInfo {
+  // A "session" corresponds to every time the tool starts.
+  // All entries emitted for the same session will have
+  // the same session_uuid
+  std::string session_uuid;
+
+  TelemetryEventStats stats;
+
+  std::optional<ExitDescription> exit_description;
+
+  // Counting number of entries.
+  // (For each set of entries with the same session_uuid, this value should
+  // be unique for each entry)
+  size_t counter;
+
+  TelemetryInfo() = default;
+  ~TelemetryInfo() = default;
+  virtual std::string ToString() const;
+};
+
+// Where/how to send the telemetry entries.
+class TelemetryDestination {
+public:
+  virtual ~TelemetryDestination() = default;
+  virtual Error EmitEntry(const TelemetryInfo *entry) = 0;
+  virtual std::string name() const = 0;
+};
+
+class Telemeter {
+public:
+  virtual ~Telemeter() = default;
+
+  // Invoked upon tool startup
+  virtual void LogStartup(llvm::StringRef tool_path, TelemetryInfo *entry) = 0;
+
+  // Invoked upon tool exit.
+  virtual void LogExit(llvm::StringRef tool_path, TelemetryInfo *entry) = 0;
+
+  virtual void AddDestination(TelemetryDestination *destination) = 0;
+};
+
+} // namespace telemetry
+} // namespace llvm
+
+#endif // LVM_TELEMETRY_TELEMETRY_H
diff --git a/llvm/lib/CMakeLists.txt b/llvm/lib/CMakeLists.txt
index 638c3bd6f90f53..1d2fb329226484 100644
--- a/llvm/lib/CMakeLists.txt
+++ b/llvm/lib/CMakeLists.txt
@@ -41,6 +41,7 @@ add_subdirectory(ProfileData)
 add_subdirectory(Passes)
 add_subdirectory(TargetParser)
 add_subdirectory(TextAPI)
+add_subdirectory(Telemetry)
 add_subdirectory(ToolDrivers)
 add_subdirectory(XRay)
 if (LLVM_INCLUDE_TESTS)
diff --git a/llvm/lib/Telemetry/CMakeLists.txt b/llvm/lib/Telemetry/CMakeLists.txt
new file mode 100644
index 00000000000000..8208bdadb05e94
--- /dev/null
+++ b/llvm/lib/Telemetry/CMakeLists.txt
@@ -0,0 +1,6 @@
+add_llvm_component_library(LLVMTelemetry
+  Telemetry.cpp
+
+  ADDITIONAL_HEADER_DIRS
+  "${LLVM_MAIN_INCLUDE_DIR}/llvm/Telemetry"
+)
diff --git a/llvm/lib/Telemetry/Telemetry.cpp b/llvm/lib/Telemetry/Telemetry.cpp
new file mode 100644
index 00000000000000..f7100685ee2d2b
--- /dev/null
+++ b/llvm/lib/Telemetry/Telemetry.cpp
@@ -0,0 +1,32 @@
+#include "llvm/Telemetry/Telemetry.h"
+
+namespace llvm {
+namespace telemetry {
+
+std::string TelemetryEventStats::ToString() const {
+  std::string result;
+  llvm::raw_string_ostream os(result);
+  os << "start_timestamp: " << m_start.time_since_epoch().count()
+     << ", end_timestamp: "
+     << (m_end.has_value() ? std::to_string(m_end->time_since_epoch().count())
+                           : "<NONE>");
+  return result;
+}
+
+std::string ExitDescription::ToString() const {
+  return "exit_code: " + std::to_string(exit_code) +
+         ", description: " + description + "\n";
+}
+
+std::string TelemetryInfo::ToString() const {
+  return "[TelemetryInfo]\n" + ("  session_uuid:" + session_uuid + "\n") +
+         ("  stats: " + stats.ToString() + "\n") +
+         ("  exit_description: " +
+          (exit_description.has_value() ? exit_description->ToString()
+                                        : "<NONE>") +
+          "\n") +
+         ("  counter: " + std::to_string(counter) + "\n");
+}
+
+} // namespace telemetry
+} // namespace llvm
\ No newline at end of file



More information about the llvm-commits mailing list