[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