Author: Vy Nguyen Date: 2025-02-10T13:59:52-05:00 New Revision: 50317ca13f6ad9b2196f92f8c719f5c31e5d6812
URL: https://github.com/llvm/llvm-project/commit/50317ca13f6ad9b2196f92f8c719f5c31e5d6812 DIFF: https://github.com/llvm/llvm-project/commit/50317ca13f6ad9b2196f92f8c719f5c31e5d6812.diff LOG: [lldb][telemetry] Implement LLDB Telemetry (part 1) (#119716) Details: - This is a subset of PR/98528.( Pavel's suggestion was to split up the patch to make reviewing easier) - This contains only the concrete implementation of the framework to be used but no usages yet. - 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 --------- Co-authored-by: Pavel Labath <pa...@labath.sk> Co-authored-by: Jonas Devlieghere <jo...@devlieghere.com> Added: lldb/include/lldb/Core/Telemetry.h lldb/source/Core/Telemetry.cpp Modified: lldb/source/Core/CMakeLists.txt Removed: ################################################################################ diff --git a/lldb/include/lldb/Core/Telemetry.h b/lldb/include/lldb/Core/Telemetry.h new file mode 100644 index 000000000000000..60a7097de5eeef5 --- /dev/null +++ b/lldb/include/lldb/Core/Telemetry.h @@ -0,0 +1,74 @@ +//===-- Telemetry.h -------------------------------------------------------===// +// +// 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 "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" +#include <chrono> +#include <ctime> +#include <memory> +#include <optional> +#include <string> +#include <unordered_map> + +namespace lldb_private { +namespace telemetry { + +struct LLDBEntryKind : public ::llvm::telemetry::EntryKind { + static const llvm::telemetry::KindType BaseInfo = 0b11000; +}; + +/// Defines a convenient type for timestamp of various events. +using SteadyTimePoint = std::chrono::time_point<std::chrono::steady_clock, + std::chrono::nanoseconds>; +struct LLDBBaseTelemetryInfo : public llvm::telemetry::TelemetryInfo { + /// Start time of an event + SteadyTimePoint start_time; + /// End time of an event - may be empty if not meaningful. + std::optional<SteadyTimePoint> end_time; + // TBD: could add some memory stats here too? + + Debugger *debugger; + + // For dyn_cast, isa, etc operations. + llvm::telemetry::KindType getKind() const override { + return LLDBEntryKind::BaseInfo; + } + + static bool classof(const llvm::telemetry::TelemetryInfo *t) { + // Subclasses of this is also acceptable. + return (t->getKind() & LLDBEntryKind::BaseInfo) == LLDBEntryKind::BaseInfo; + } + + void serialize(llvm::telemetry::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 preDispatch(llvm::telemetry::TelemetryInfo *entry) override; + +private: + std::unique_ptr<llvm::telemetry::Config> m_config; +}; + +} // namespace telemetry +} // namespace lldb_private +#endif // LLDB_CORE_TELEMETRY_H diff --git a/lldb/source/Core/CMakeLists.txt b/lldb/source/Core/CMakeLists.txt index 6d14f7a87764e05..4b1f41816201608 100644 --- a/lldb/source/Core/CMakeLists.txt +++ b/lldb/source/Core/CMakeLists.txt @@ -16,6 +16,11 @@ if (LLDB_ENABLE_CURSES) endif() endif() +if (LLVM_BUILD_TELEMETRY) + set(TELEMETRY_SOURCES Telemetry.cpp) + set(TELEMETRY_DEPS Telemetry) +endif() + # TODO: Add property `NO_PLUGIN_DEPENDENCIES` to lldbCore add_lldb_library(lldbCore Address.cpp @@ -55,7 +60,8 @@ add_lldb_library(lldbCore ThreadedCommunication.cpp UserSettingsController.cpp Value.cpp - + ${TELEMETRY_SOURCES} + PARTIAL_SOURCES_INTENDED DEPENDS clang-tablegen-targets @@ -80,6 +86,7 @@ add_lldb_library(lldbCore Support Demangle TargetParser + ${TELEMETRY_DEPS} ) add_dependencies(lldbCore diff --git a/lldb/source/Core/Telemetry.cpp b/lldb/source/Core/Telemetry.cpp new file mode 100644 index 000000000000000..a474a7663a0185a --- /dev/null +++ b/lldb/source/Core/Telemetry.cpp @@ -0,0 +1,69 @@ +//===-- 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/Utility/LLDBLog.h" +#include "lldb/Utility/UUID.h" +#include "lldb/lldb-enumerations.h" +#include "lldb/lldb-forward.h" +#include "llvm/ADT/StringRef.h" +#include "llvm/Support/Error.h" +#include "llvm/Support/RandomNumberGenerator.h" +#include "llvm/Telemetry/Telemetry.h" +#include <chrono> +#include <cstdlib> +#include <memory> +#include <string> +#include <utility> + +namespace lldb_private { +namespace telemetry { + +using ::llvm::Error; +using ::llvm::telemetry::Destination; +using ::llvm::telemetry::Serializer; +using ::llvm::telemetry::TelemetryInfo; + +static uint64_t ToNanosec(const SteadyTimePoint Point) { + return std::chrono::nanoseconds(Point.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(start_time)); + if (end_time.has_value()) + serializer.write("end_time", ToNanosec(end_time.value())); +} + +static std::string MakeUUID(lldb_private::Debugger *debugger) { + 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. + return llvm::formatv( + "{0}_{1}", std::chrono::steady_clock::now().time_since_epoch().count(), + debugger->GetID()); + } + return lldb_private::UUID(random_bytes).GetAsString(); +} + +TelemetryManager::TelemetryManager( + std::unique_ptr<llvm::telemetry::Config> config) + : m_config(std::move(config)) {} + +llvm::Error TelemetryManager::preDispatch(TelemetryInfo *entry) { + // Do nothing for now. + // In up-coming patch, this would be where the manager + // attach the session_uuid to the entry. + return Error::success(); +} + +} // namespace telemetry +} // namespace lldb_private _______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits