https://github.com/oontvoo updated https://github.com/llvm/llvm-project/pull/119716
>From b7216d7c3edd5974d84612586fbabdef19037387 Mon Sep 17 00:00:00 2001 From: Vy Nguyen <v...@google.com> Date: Thu, 26 Dec 2024 20:50:40 -0500 Subject: [PATCH 1/2] Implement LLDB Telemetry (Part 1) This contains only the concrete implementation of the framework to be used but no usages yet. This is a subset of PR/98528. I plan to send a few follow-up patches: part2 : includes changes in the plugin-manager to set up the plugin stuff (ie., how to create a default vs vendor impl) part3 (all of the following can be done in parallel): * part 3_a: define DebuggerTelemetryInfo and related methods to collect data about debugger startup/exit * part 3_b: define TargetTelemetryInfo and related methods to collect data about debug target(s) * part 3_c: define CommandTelemetryInfo and related methods to collect data about debug-commands * part 3_d: define ClientTelemtryInfo and related methods to collect data about lldb-dap/any other client --- lldb/include/lldb/Core/Telemetry.h | 101 ++++++++++++++++++++++++++ lldb/include/lldb/lldb-enumerations.h | 4 +- lldb/source/Core/CMakeLists.txt | 2 + lldb/source/Core/Telemetry.cpp | 92 +++++++++++++++++++++++ lldb/test/CMakeLists.txt | 3 + 5 files changed, 200 insertions(+), 2 deletions(-) create mode 100644 lldb/include/lldb/Core/Telemetry.h create mode 100644 lldb/source/Core/Telemetry.cpp diff --git a/lldb/include/lldb/Core/Telemetry.h b/lldb/include/lldb/Core/Telemetry.h new file mode 100644 index 000000000000000..882511efd804d23 --- /dev/null +++ b/lldb/include/lldb/Core/Telemetry.h @@ -0,0 +1,101 @@ +//===-- Telemetry.h ----------------------------------------------*- 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 +// +//===----------------------------------------------------------------------===// + +#ifndef LLDB_CORE_TELEMETRY_H +#define LLDB_CORE_TELEMETRY_H + +#include <chrono> +#include <ctime> +#include <memory> +#include <optional> +#include <string> +#include <unordered_map> + +#include "lldb/Core/StructuredDataImpl.h" +#include "lldb/Interpreter/CommandReturnObject.h" +#include "lldb/Utility/StructuredData.h" +#include "lldb/lldb-forward.h" +#include "llvm/ADT/StringExtras.h" +#include "llvm/ADT/StringRef.h" +#include "llvm/Support/JSON.h" +#include "llvm/Telemetry/Telemetry.h" + +namespace lldb_private { + +using llvm::telemetry::Destination; +using llvm::telemetry::KindType; +using llvm::telemetry::Serializer; +using llvm::telemetry::TelemetryInfo; + +struct LldbEntryKind : public ::llvm::telemetry::EntryKind { + static const KindType BaseInfo = 0b11000; +}; + +/// Defines a convenient type for timestamp of various events. +/// This is used by the EventStats below. +using SteadyTimePoint = std::chrono::time_point<std::chrono::steady_clock, + std::chrono::nanoseconds>; + +/// Various time (and possibly memory) statistics of an event. +struct EventStats { + // REQUIRED: Start time of an event + SteadyTimePoint start; + // OPTIONAL: End time of an event - may be empty if not meaningful. + std::optional<SteadyTimePoint> end; + // TBD: could add some memory stats here too? + + EventStats() = default; + EventStats(SteadyTimePoint start) : start(start) {} + EventStats(SteadyTimePoint start, SteadyTimePoint end) + : start(start), end(end) {} +}; + +/// Describes the exit signal of an event. +struct ExitDescription { + int exit_code; + std::string description; +}; + +struct LldbBaseTelemetryInfo : public TelemetryInfo { + EventStats stats; + + std::optional<ExitDescription> exit_desc; + + Debugger *debugger; + + // For dyn_cast, isa, etc operations. + KindType getKind() const override { return LldbEntryKind::BaseInfo; } + + static bool classof(const TelemetryInfo *t) { + // Subclasses of this is also acceptable. + return (t->getKind() & LldbEntryKind::BaseInfo) == LldbEntryKind::BaseInfo; + } + + void serialize(Serializer &serializer) const override; +}; + +/// The base Telemetry manager instance in LLDB +/// This class declares additional instrumentation points +/// applicable to LLDB. +class TelemetryManager : public llvm::telemetry::Manager { +public: + TelemetryManager(std::unique_ptr<llvm::telemetry::Config> config); + + llvm::Error dispatch(TelemetryInfo *entry) override; + + void addDestination(std::unique_ptr<Destination> destination) override; + +private: + std::unique_ptr<llvm::telemetry::Config> m_config; + const std::string m_session_uuid; + std::vector<std::unique_ptr<Destination>> m_destinations; +}; + +} // namespace lldb_private +#endif // LLDB_CORE_TELEMETRY_H diff --git a/lldb/include/lldb/lldb-enumerations.h b/lldb/include/lldb/lldb-enumerations.h index 0094fcd596fdf70..f63e446b6042f62 100644 --- a/lldb/include/lldb/lldb-enumerations.h +++ b/lldb/include/lldb/lldb-enumerations.h @@ -257,8 +257,8 @@ enum StopReason { }; /// Command Return Status Types. -enum ReturnStatus { - eReturnStatusInvalid, +enum ReturnStatus : int { + eReturnStatusInvalid = 0, eReturnStatusSuccessFinishNoResult, eReturnStatusSuccessFinishResult, eReturnStatusSuccessContinuingNoResult, diff --git a/lldb/source/Core/CMakeLists.txt b/lldb/source/Core/CMakeLists.txt index 6d14f7a87764e05..dcab3b19ad8ff90 100644 --- a/lldb/source/Core/CMakeLists.txt +++ b/lldb/source/Core/CMakeLists.txt @@ -51,6 +51,7 @@ add_lldb_library(lldbCore Section.cpp SourceLocationSpec.cpp SourceManager.cpp + Telemetry.cpp StreamAsynchronousIO.cpp ThreadedCommunication.cpp UserSettingsController.cpp @@ -80,6 +81,7 @@ add_lldb_library(lldbCore Support Demangle TargetParser + Telemetry ) add_dependencies(lldbCore diff --git a/lldb/source/Core/Telemetry.cpp b/lldb/source/Core/Telemetry.cpp new file mode 100644 index 000000000000000..3d6264a4c8e57a3 --- /dev/null +++ b/lldb/source/Core/Telemetry.cpp @@ -0,0 +1,92 @@ +//===-- Telemetry.cpp -----------------------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// +#include "lldb/Core/Telemetry.h" +#include "lldb/Core/Debugger.h" +#include "lldb/Target/Statistics.h" +#include "lldb/Utility/ConstString.h" +#include "lldb/Utility/LLDBLog.h" +#include "lldb/Utility/UUID.h" +#include "lldb/Version/Version.h" +#include "lldb/lldb-enumerations.h" +#include "lldb/lldb-forward.h" +#include "llvm/ADT/SmallString.h" +#include "llvm/ADT/StringRef.h" +#include "llvm/ADT/Twine.h" +#include "llvm/Support/Error.h" +#include "llvm/Support/RandomNumberGenerator.h" +#include "llvm/Telemetry/Telemetry.h" +#include <chrono> +#include <cstdlib> +#include <ctime> +#include <memory> +#include <string> +#include <utility> +#include <vector> + +namespace lldb_private { + +using ::llvm::Error; +using ::llvm::telemetry::Destination; +using ::llvm::telemetry::TelemetryInfo; + +static uint64_t ToNanosec(const SteadyTimePoint Point) { + return nanoseconds(Point.value().time_since_epoch()).count(); +} + +void LldbBaseTelemetryInfo::serialize(Serializer &serializer) const { + serializer.write("entry_kind", getKind()); + serializer.write("session_id", SessionId); + serializer.write("start_time", ToNanosec(stats.start)); + if (stats.end.has_value()) + serializer.write("end_time", ToNanosec(stats.end.value())); + if (exit_desc.has_value()) { + serializer.write("exit_code", exit_desc->exit_code); + serializer.write("exit_msg", exit_desc->description); + } +} + +static std::string MakeUUID(lldb_private::Debugger *debugger) { + std::string ret; + uint8_t random_bytes[16]; + if (auto ec = llvm::getRandomBytes(random_bytes, 16)) { + LLDB_LOG(GetLog(LLDBLog::Object), + "Failed to generate random bytes for UUID: {0}", ec.message()); + // fallback to using timestamp + debugger ID. + ret = std::to_string( + std::chrono::steady_clock::now().time_since_epoch().count()) + + "_" + std::to_string(debugger->GetID()); + } else { + ret = lldb_private::UUID(random_bytes).GetAsString(); + } + + return ret; +} + +TelemetryManager::TelemetryManager( + std::unique_ptr<llvm::telemetry::Config> config, + lldb_private::Debugger *debugger) + : m_config(std::move(config)), m_debugger(debugger), + m_session_uuid(MakeUUID(debugger)) {} + +llvm::Error TelemetryManager::dispatch(TelemetryInfo *entry) { + entry->SessionId = m_session_uuid; + + llvm::Error defferedErrs = llvm::Error::success(); + for (auto &destination : m_destinations) + deferredErrs = llvm::joinErrors(std::move(deferredErrs), + destination->receiveEntry(entry)); + + return std::move(deferredErrs); +} + +void TelemetryManager::addDestination( + std::unique_ptr<Destination> destination) { + m_destinations.push_back(std::move(destination)); +} + +} // namespace lldb_private diff --git a/lldb/test/CMakeLists.txt b/lldb/test/CMakeLists.txt index 6449ac5a9247f69..b71550d17888649 100644 --- a/lldb/test/CMakeLists.txt +++ b/lldb/test/CMakeLists.txt @@ -108,6 +108,9 @@ endfunction(add_lldb_test_dependency) add_lldb_test_dependency(lldb) add_lldb_test_dependency(lldb-test) +# Enable Telemetry for testing. +target_compile_definitions(lldb PRIVATE -DTEST_TELEMETRY) + # On Darwin, darwin-debug is an hard dependency for the testsuites. if (CMAKE_SYSTEM_NAME MATCHES "Darwin") add_lldb_test_dependency(darwin-debug) >From fca467450e244b54bcf88cc81de91e28fb3bd3cd Mon Sep 17 00:00:00 2001 From: Vy Nguyen <v...@google.com> Date: Thu, 26 Dec 2024 21:08:14 -0500 Subject: [PATCH 2/2] fix order --- lldb/include/lldb/Core/Telemetry.h | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/lldb/include/lldb/Core/Telemetry.h b/lldb/include/lldb/Core/Telemetry.h index 882511efd804d23..025f73bc5daeab7 100644 --- a/lldb/include/lldb/Core/Telemetry.h +++ b/lldb/include/lldb/Core/Telemetry.h @@ -10,13 +10,6 @@ #ifndef LLDB_CORE_TELEMETRY_H #define LLDB_CORE_TELEMETRY_H -#include <chrono> -#include <ctime> -#include <memory> -#include <optional> -#include <string> -#include <unordered_map> - #include "lldb/Core/StructuredDataImpl.h" #include "lldb/Interpreter/CommandReturnObject.h" #include "lldb/Utility/StructuredData.h" @@ -25,6 +18,12 @@ #include "llvm/ADT/StringRef.h" #include "llvm/Support/JSON.h" #include "llvm/Telemetry/Telemetry.h" +#include <chrono> +#include <ctime> +#include <memory> +#include <optional> +#include <string> +#include <unordered_map> namespace lldb_private { _______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits