Skip to content

Commit 0e49b93

Browse files
committed
Rework the default impl of Telemetry in LLDB as "Plugin" to allow for testing
1 parent 04b7da8 commit 0e49b93

File tree

10 files changed

+695
-505
lines changed

10 files changed

+695
-505
lines changed

lldb/include/lldb/Core/PluginManager.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -379,6 +379,15 @@ class PluginManager {
379379
const UUID *uuid,
380380
const ArchSpec *arch);
381381

382+
// TelemetryVendor
383+
static bool RegisterPlugin(llvm::StringRef name, llvm::StringRef description,
384+
TelemetryVendorCreateInstance create_callback);
385+
386+
static bool UnregisterPlugin(TelemetryVendorCreateInstance create_callback);
387+
388+
static TelemetryVendorCreateInstance
389+
GetTelemetryVendorCreateCallbackAtIndex(uint32_t idx);
390+
382391
// Trace
383392
static bool RegisterPlugin(
384393
llvm::StringRef name, llvm::StringRef description,

lldb/include/lldb/Core/Telemetry.h

Lines changed: 50 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -192,15 +192,15 @@ struct CommandTelemetryInfo : public LldbBaseTelemetryInfo {
192192
std::string ToString() const override;
193193
};
194194

195-
// The "catch-all" entry to store a set of custom/non-standard
196-
// data.
195+
/// The "catch-all" entry to store a set of custom/non-standard
196+
/// data.
197197
struct MiscTelemetryInfo : public LldbBaseTelemetryInfo {
198-
// If the event is/can be associated with a target entry,
199-
// this field contains that target's UUID.
200-
// <EMPTY> otherwise.
198+
/// If the event is/can be associated with a target entry,
199+
/// this field contains that target's UUID.
200+
/// <EMPTY> otherwise.
201201
std::string target_uuid;
202202

203-
// Set of key-value pairs for any optional (or impl-specific) data
203+
/// Set of key-value pairs for any optional (or impl-specific) data
204204
std::unordered_map<std::string, std::string> meta_data;
205205

206206
MiscTelemetryInfo() = default;
@@ -223,29 +223,39 @@ struct MiscTelemetryInfo : public LldbBaseTelemetryInfo {
223223
std::string ToString() const override;
224224
};
225225

226+
/// The base Telemeter instance in LLDB.
227+
/// This class declares additional instrumentation points
228+
/// applicable to LLDB.
226229
class LldbTelemeter : public llvm::telemetry::Telemeter {
227230
public:
228-
static std::unique_ptr<LldbTelemeter> CreateInstance(Debugger *);
231+
/// Creates an instance of LldbTelemeter.
232+
/// This uses the plugin registry to find an instance:
233+
/// - If a vendor supplies a implementation, it will use it.
234+
/// - If not, it will either return a no-op instance or a basic
235+
/// implementation for testing.
236+
///
237+
/// See also lldb_private::TelemetryVendor.
238+
static std::unique_ptr<LldbTelemeter> CreateInstance(Debugger *debugger);
229239

230240
virtual ~LldbTelemeter() = default;
231241

232-
// Invoked upon process exit
242+
/// Invoked upon process exit
233243
virtual void LogProcessExit(int status, llvm::StringRef exit_string,
234244
llvm::telemetry::EventStats stats,
235245
Target *target_ptr) = 0;
236246

237-
// Invoked upon loading the main executable module
238-
// We log in a fire-n-forget fashion so that if the load
239-
// crashes, we don't lose the entry.
247+
/// Invoked upon loading the main executable module
248+
/// We log in a fire-n-forget fashion so that if the load
249+
/// crashes, we don't lose the entry.
240250
virtual void
241251
LogMainExecutableLoadStart(lldb::ModuleSP exec_mod,
242252
llvm::telemetry::EventStats stats) = 0;
243253
virtual void LogMainExecutableLoadEnd(lldb::ModuleSP exec_mod,
244254
llvm::telemetry::EventStats stats) = 0;
245255

246-
// Invoked for each command
247-
// We log in a fire-n-forget fashion so that if the command execution
248-
// crashes, we don't lose the entry.
256+
/// Invoked for each command
257+
/// We log in a fire-n-forget fashion so that if the command execution
258+
/// crashes, we don't lose the entry.
249259
virtual void LogCommandStart(llvm::StringRef uuid,
250260
llvm::StringRef original_command,
251261
llvm::telemetry::EventStats stats,
@@ -258,36 +268,36 @@ class LldbTelemeter : public llvm::telemetry::Telemeter {
258268

259269
virtual std::string GetNextUUID() = 0;
260270

261-
// For client (eg., SB API) to send telemetry entries.
271+
/// For client (eg., SB API) to send telemetry entries.
262272
virtual void
263273
LogClientTelemetry(const lldb_private::StructuredDataImpl &entry) = 0;
264274
};
265275

266-
// Logger configs: LLDB users can also supply their own configs via:
267-
// $HOME/.lldb_telemetry_config
268-
//
269-
// We can propose simple syntax: <field_name><colon><value>
270-
// Eg.,
271-
// enable_telemetry:true
272-
// destination:stdout
273-
// destination:stderr
274-
// destination:/path/to/some/file
275-
//
276-
// The allowed field_name values are:
277-
// * enable_telemetry
278-
// If the fields are specified more than once, the last line will take
279-
// precedence If enable_logging is set to false, no logging will occur.
280-
// * destination.
281-
// This is allowed to be specified multiple times - it will add to the
282-
// default (ie, specified by vendor) list of destinations.
283-
// The value can be either:
284-
// + one of the two magic values "stdout" or "stderr".
285-
// + a path to a local file
286-
// !!NOTE!!: We decided to use a separate file instead of the existing settings
287-
// file because that file is parsed too late in the process and by the
288-
// there might have been lots of telemetry-entries that need to be
289-
// sent already.
290-
// This approach avoid losing log entries if LLDB crashes during init.
276+
/// Logger configs: LLDB users can also supply their own configs via:
277+
/// $HOME/.lldb_telemetry_config
278+
///
279+
/// We can propose simple syntax: <field_name><colon><value>
280+
/// Eg.,
281+
/// enable_telemetry:true
282+
/// destination:stdout
283+
/// destination:stderr
284+
/// destination:/path/to/some/file
285+
///
286+
/// The allowed field_name values are:
287+
/// * enable_telemetry
288+
/// If the fields are specified more than once, the last line will take
289+
/// precedence If enable_logging is set to false, no logging will occur.
290+
/// * destination.
291+
/// This is allowed to be specified multiple times - it will add to the
292+
/// default (ie, specified by vendor) list of destinations.
293+
/// The value can be either:
294+
/// + one of the two magic values "stdout" or "stderr".
295+
/// + a path to a local file
296+
/// !!NOTE!!: We decided to use a separate file instead of the existing settings
297+
/// file because that file is parsed too late in the process and by the
298+
/// there might have been lots of telemetry-entries that need to be
299+
/// sent already.
300+
/// This approach avoid losing log entries if LLDB crashes during init.
291301
llvm::telemetry::Config *GetTelemetryConfig();
292302

293303
} // namespace lldb_private
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
//===-- TelemetryVendor.h ---------------------------------------*- C++ -*-===//
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_TELEMETRYVENDOR_H
10+
#define LLDB_CORE_TELEMETRYVENDOR_H
11+
12+
#include "lldb/Core/PluginInterface.h"
13+
#include "lldb/Core/Telemetry.h"
14+
#include "llvm/Telemetry/Telemetry.h"
15+
16+
#include <memory>
17+
18+
namespace lldb_private {
19+
20+
class TelemetryVendor : public PluginInterface {
21+
public:
22+
static TelemetryVendor *FindPlugin();
23+
24+
TelemetryVendor() = default;
25+
26+
llvm::StringRef GetPluginName() override;
27+
28+
std::unique_ptr<llvm::telemetry::Config> GetTelemetryConfig();
29+
30+
// Creates an LldbTelemeter instance.
31+
// Vendor plugins can override this to create customized instance as needed.
32+
virtual std::unique_ptr<LldbTelemeter>
33+
CreateTelemeter(lldb_private::Debugger *debugger);
34+
35+
// TODO: move most of the basictelemeter concrete impl here to the plug in (to
36+
// its .ccpp file that is)
37+
protected:
38+
// Returns a vendor-specific config which may or may not be the same as the
39+
// given "default_config". Downstream implementation can define their
40+
// configugrations in addition to OR overriding the default option.
41+
virtual std::unique_ptr<llvm::telemetry::Config> GetVendorSpecificConfig(
42+
std::unique_ptr<llvm::telemetry::Config> default_config);
43+
};
44+
45+
} // namespace lldb_private
46+
#endif // LLDB_CORE_TELEMETRYVENDOR_H

lldb/include/lldb/lldb-forward.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -234,6 +234,7 @@ class SystemRuntime;
234234
class Target;
235235
class TargetList;
236236
class TargetProperties;
237+
class TelemetryVendor;
237238
class Thread;
238239
class ThreadCollection;
239240
class ThreadList;

lldb/include/lldb/lldb-private-interfaces.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,7 @@ typedef bool (*ScriptedInterfaceCreateInstance)(lldb::ScriptLanguage language,
129129
ScriptedInterfaceUsages usages);
130130
typedef int (*ComparisonFunction)(const void *, const void *);
131131
typedef void (*DebuggerInitializeCallback)(Debugger &debugger);
132+
typedef TelemetryVendor *(*TelemetryVendorCreateInstance)();
132133
/// Trace
133134
/// \{
134135
typedef llvm::Expected<lldb::TraceSP> (*TraceCreateInstanceFromBundle)(

lldb/source/Core/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ add_lldb_library(lldbCore
5252
SourceLocationSpec.cpp
5353
SourceManager.cpp
5454
Telemetry.cpp
55+
TelemetryVendor.cpp
5556
StreamAsynchronousIO.cpp
5657
ThreadedCommunication.cpp
5758
UserSettingsController.cpp

lldb/source/Core/PluginManager.cpp

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1224,6 +1224,33 @@ FileSpec PluginManager::FindSymbolFileInBundle(const FileSpec &symfile_bundle,
12241224
return {};
12251225
}
12261226

1227+
#pragma mark TelemetryVendor
1228+
1229+
typedef PluginInstance<TelemetryVendorCreateInstance> TelemetryVendorInstance;
1230+
typedef PluginInstances<TelemetryVendorInstance> TelemetryVendorInstances;
1231+
1232+
static TelemetryVendorInstances &GetTelemetryVendorInstances() {
1233+
static TelemetryVendorInstances g_instances;
1234+
return g_instances;
1235+
}
1236+
1237+
bool PluginManager::RegisterPlugin(
1238+
llvm::StringRef name, llvm::StringRef description,
1239+
TelemetryVendorCreateInstance create_callback) {
1240+
return GetTelemetryVendorInstances().RegisterPlugin(name, description,
1241+
create_callback);
1242+
}
1243+
1244+
bool PluginManager::UnregisterPlugin(
1245+
TelemetryVendorCreateInstance create_callback) {
1246+
return GetTelemetryVendorInstances().UnregisterPlugin(create_callback);
1247+
}
1248+
1249+
TelemetryVendorCreateInstance
1250+
PluginManager::GetTelemetryVendorCreateCallbackAtIndex(uint32_t idx) {
1251+
return GetTelemetryVendorInstances().GetCallbackAtIndex(idx);
1252+
}
1253+
12271254
#pragma mark Trace
12281255

12291256
struct TraceInstance

0 commit comments

Comments
 (0)