Skip to content

Commit 282e356

Browse files
oontvoolabathJDevlieghere
authored andcommitted
[lldb][telemetry] Implement LLDB Telemetry (part 1) (llvm#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 <[email protected]> Co-authored-by: Jonas Devlieghere <[email protected]>
1 parent 3cbed80 commit 282e356

File tree

3 files changed

+151
-1
lines changed

3 files changed

+151
-1
lines changed

lldb/include/lldb/Core/Telemetry.h

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
//===-- Telemetry.h -------------------------------------------------------===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
#ifndef LLDB_CORE_TELEMETRY_H
10+
#define LLDB_CORE_TELEMETRY_H
11+
12+
#include "lldb/Core/StructuredDataImpl.h"
13+
#include "lldb/Interpreter/CommandReturnObject.h"
14+
#include "lldb/Utility/StructuredData.h"
15+
#include "lldb/lldb-forward.h"
16+
#include "llvm/ADT/StringExtras.h"
17+
#include "llvm/ADT/StringRef.h"
18+
#include "llvm/Support/JSON.h"
19+
#include "llvm/Telemetry/Telemetry.h"
20+
#include <chrono>
21+
#include <ctime>
22+
#include <memory>
23+
#include <optional>
24+
#include <string>
25+
#include <unordered_map>
26+
27+
namespace lldb_private {
28+
namespace telemetry {
29+
30+
struct LLDBEntryKind : public ::llvm::telemetry::EntryKind {
31+
static const llvm::telemetry::KindType BaseInfo = 0b11000;
32+
};
33+
34+
/// Defines a convenient type for timestamp of various events.
35+
using SteadyTimePoint = std::chrono::time_point<std::chrono::steady_clock,
36+
std::chrono::nanoseconds>;
37+
struct LLDBBaseTelemetryInfo : public llvm::telemetry::TelemetryInfo {
38+
/// Start time of an event
39+
SteadyTimePoint start_time;
40+
/// End time of an event - may be empty if not meaningful.
41+
std::optional<SteadyTimePoint> end_time;
42+
// TBD: could add some memory stats here too?
43+
44+
Debugger *debugger;
45+
46+
// For dyn_cast, isa, etc operations.
47+
llvm::telemetry::KindType getKind() const override {
48+
return LLDBEntryKind::BaseInfo;
49+
}
50+
51+
static bool classof(const llvm::telemetry::TelemetryInfo *t) {
52+
// Subclasses of this is also acceptable.
53+
return (t->getKind() & LLDBEntryKind::BaseInfo) == LLDBEntryKind::BaseInfo;
54+
}
55+
56+
void serialize(llvm::telemetry::Serializer &serializer) const override;
57+
};
58+
59+
/// The base Telemetry manager instance in LLDB
60+
/// This class declares additional instrumentation points
61+
/// applicable to LLDB.
62+
class TelemetryManager : public llvm::telemetry::Manager {
63+
public:
64+
TelemetryManager(std::unique_ptr<llvm::telemetry::Config> config);
65+
66+
llvm::Error preDispatch(llvm::telemetry::TelemetryInfo *entry) override;
67+
68+
private:
69+
std::unique_ptr<llvm::telemetry::Config> m_config;
70+
};
71+
72+
} // namespace telemetry
73+
} // namespace lldb_private
74+
#endif // LLDB_CORE_TELEMETRY_H

lldb/source/Core/CMakeLists.txt

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,11 @@ if (LLDB_ENABLE_CURSES)
1616
endif()
1717
endif()
1818

19+
if (LLVM_BUILD_TELEMETRY)
20+
set(TELEMETRY_SOURCES Telemetry.cpp)
21+
set(TELEMETRY_DEPS Telemetry)
22+
endif()
23+
1924
# TODO: Add property `NO_PLUGIN_DEPENDENCIES` to lldbCore
2025
add_lldb_library(lldbCore
2126
Address.cpp
@@ -55,7 +60,8 @@ add_lldb_library(lldbCore
5560
ThreadedCommunication.cpp
5661
UserSettingsController.cpp
5762
Value.cpp
58-
63+
${TELEMETRY_SOURCES}
64+
PARTIAL_SOURCES_INTENDED
5965
DEPENDS
6066
clang-tablegen-targets
6167

@@ -80,6 +86,7 @@ add_lldb_library(lldbCore
8086
Support
8187
Demangle
8288
TargetParser
89+
${TELEMETRY_DEPS}
8390
)
8491

8592
add_dependencies(lldbCore

lldb/source/Core/Telemetry.cpp

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
//===-- Telemetry.cpp -----------------------------------------------------===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
#include "lldb/Core/Telemetry.h"
9+
#include "lldb/Core/Debugger.h"
10+
#include "lldb/Utility/LLDBLog.h"
11+
#include "lldb/Utility/UUID.h"
12+
#include "lldb/lldb-enumerations.h"
13+
#include "lldb/lldb-forward.h"
14+
#include "llvm/ADT/StringRef.h"
15+
#include "llvm/Support/Error.h"
16+
#include "llvm/Support/RandomNumberGenerator.h"
17+
#include "llvm/Telemetry/Telemetry.h"
18+
#include <chrono>
19+
#include <cstdlib>
20+
#include <memory>
21+
#include <string>
22+
#include <utility>
23+
24+
namespace lldb_private {
25+
namespace telemetry {
26+
27+
using ::llvm::Error;
28+
using ::llvm::telemetry::Destination;
29+
using ::llvm::telemetry::Serializer;
30+
using ::llvm::telemetry::TelemetryInfo;
31+
32+
static uint64_t ToNanosec(const SteadyTimePoint Point) {
33+
return std::chrono::nanoseconds(Point.time_since_epoch()).count();
34+
}
35+
36+
void LLDBBaseTelemetryInfo::serialize(Serializer &serializer) const {
37+
serializer.write("entry_kind", getKind());
38+
serializer.write("session_id", SessionId);
39+
serializer.write("start_time", ToNanosec(start_time));
40+
if (end_time.has_value())
41+
serializer.write("end_time", ToNanosec(end_time.value()));
42+
}
43+
44+
static std::string MakeUUID(lldb_private::Debugger *debugger) {
45+
uint8_t random_bytes[16];
46+
if (auto ec = llvm::getRandomBytes(random_bytes, 16)) {
47+
LLDB_LOG(GetLog(LLDBLog::Object),
48+
"Failed to generate random bytes for UUID: {0}", ec.message());
49+
// fallback to using timestamp + debugger ID.
50+
return llvm::formatv(
51+
"{0}_{1}", std::chrono::steady_clock::now().time_since_epoch().count(),
52+
debugger->GetID());
53+
}
54+
return lldb_private::UUID(random_bytes).GetAsString();
55+
}
56+
57+
TelemetryManager::TelemetryManager(
58+
std::unique_ptr<llvm::telemetry::Config> config)
59+
: m_config(std::move(config)) {}
60+
61+
llvm::Error TelemetryManager::preDispatch(TelemetryInfo *entry) {
62+
// Do nothing for now.
63+
// In up-coming patch, this would be where the manager
64+
// attach the session_uuid to the entry.
65+
return Error::success();
66+
}
67+
68+
} // namespace telemetry
69+
} // namespace lldb_private

0 commit comments

Comments
 (0)