-
Notifications
You must be signed in to change notification settings - Fork 14.3k
[lldb]Implement LLDB Telemetry #98528
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
Why does any part of this need to be in llvm/ at all? |
Please see comments on the rfc at https://discourse.llvm.org/t/rfc-lldb-telemetry-metrics/64588/15 TL;DR : A few people feel that Telemetry is not something unique to LLDB and that other tools might be interested in having it too. So rather than having mutliple Telemetry libs doing similar things, it might be good to have at least a common API |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've made one pass over the PR. I think this would be easier to review if it was split into multiple patches:
- core llvm infrastructure
- core lldb infrastructure
- ~one patch per event type
I think the biggest hurdle will be finding someone to approve the addition of the new llvm library (I doubt it's going to be someone from the current reviewer set). I wouldn't be surprised if this ends up needing its own RFC.
lldb/include/lldb/API/SBDebugger.h
Outdated
@@ -9,10 +9,12 @@ | |||
#ifndef LLDB_API_SBDEBUGGER_H | |||
#define LLDB_API_SBDEBUGGER_H | |||
|
|||
#include <chrono> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this used anywhere?
lldb/include/lldb/API/SBDebugger.h
Outdated
@@ -245,6 +247,8 @@ class LLDB_API SBDebugger { | |||
|
|||
lldb::SBTarget GetDummyTarget(); | |||
|
|||
void SendTelemetry(SBStructuredData *entry); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
void SendTelemetry(SBStructuredData *entry); | |
void SendTelemetry(const SBStructuredData &entry); |
lldb/include/lldb/Core/Telemetry.h
Outdated
// Logger configs: LLDB users can also supply their own configs via: | ||
// $HOME/.lldb_telemetry_config | ||
// | ||
// We can propose simple syntax: <field_name><colon><value> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since this is actual code, it should talk about the (real) syntax, not the proposed one.
lldb/source/Core/Telemetry.cpp
Outdated
|
||
auto *ret = new llvm::telemetry::TelemetryConfig{enable_telemetry, | ||
additional_destinations}; | ||
#ifdef HAS_VENDOR_TELEMETRY_CONFIG |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd probably do this by providing dummy/empty implementations of these functions when there's no vendor customization.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can you clarify what you mean by dummy implementations? (w/o causing either duplicate-symbols errors) I'd tried the weak-def but it wasn't very portable, so I thought this was the simplest.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I just meant that we could conditionally provide an empty implementation of the "vendor" function instead of conditionally calling it. So something like:
#if VENDOR
// do something to get the vendor definition
#else
// provide an empty definition ourselves, e.g:
void ApplyVendorSpecificConfigs(...) {}
#endif
Then you don't need the ifdef at the call site.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done - reworked this to use Plugin registry (the default plugin is enabled for test, then vendors can add their own impl as needed)
Good point - so here's the plane:
|
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
Provide the concrete implementation for telemetry in LLDB. (This is follow-up patch to PR/102323)
d290895
to
42781f7
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it'd be good to separate the general mechanics of creating and managing a telemetry (telemeter) instance from the details of logging individual telemetry entries. I.e. one PR for the general infrastructure (maybe include one simple (startup?) telemetry entry, if you think it's necessary to make a point), and then one PR for each of the entries.
The plugin infrastructure seems very.. baroque. Why do we need the intermediate TelemetryVendor class? And why a whole list of them?
The reason we support registering more than one e.g. SymbolFile plugin is that we can choose which one to use at runtime (based on which file the user opens, etc.). Do we want to do something like that here? What would that even mean?
To create a basic indirection (so that the vendor implementation can be decoupled from the rest of lldb), it sounds to me like all one need is one function pointer (the factory function for the "telemeter"), a way to set it from inside the plugin (PluginManager::SetTelemetryPlugin
?) and then a way to call it (another function?)
@@ -257,8 +257,8 @@ enum StopReason { | |||
}; | |||
|
|||
/// Command Return Status Types. | |||
enum ReturnStatus { | |||
eReturnStatusInvalid, | |||
enum ReturnStatus : int { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How does this relate to the rest of the patch?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is needed to serialize the ReturnStatus from a command.
lldb/source/Core/Telemetry.cpp
Outdated
static std::string | ||
ExitDescToString(const llvm::telemetry::ExitDescription *desc) { | ||
return ("ExitCode:" + desc->ExitCode) + | ||
(" ExixitDescription: " + desc->Description); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(" ExixitDescription: " + desc->Description); | |
(" ExitDescription: " + desc->Description); |
lldb/source/Core/Telemetry.cpp
Outdated
return std::to_string((stats.End.value() - stats.Start).count()) + | ||
"(nanosec)"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
return std::to_string((stats.End.value() - stats.Start).count()) + | |
"(nanosec)"; | |
return llvm::formatv("{0:ns}", stats.End.value() - stats.Start).str(); |
(or maybe some other unit (ms/us) -- how small do we expect these to get)?
dbef2be
to
f85900d
Compare
Provide some concrete implementation for llvm/Telemetry in lldb/Telemetry
(Dependent on PR/102323