15#include "llvm/ADT/StringRef.h"
16#include "llvm/Support/Error.h"
17#include "llvm/Support/Format.h"
18#include "llvm/Support/RandomNumberGenerator.h"
19#include "llvm/Telemetry/Telemetry.h"
30using namespace llvm::telemetry;
33 return std::chrono::nanoseconds(Point.time_since_epoch()).count();
42 auto timestmap = std::chrono::steady_clock::now().time_since_epoch().count();
44 return llvm::formatv(
"{0}_{1}", uuid.
GetAsString(), timestmap);
48 serializer.write(
"entry_kind",
getKind());
49 serializer.write(
"session_id", SessionId);
60 serializer.write(
"error_msg",
error_msg.value());
66 serializer.write(
"target_uuid",
target_uuid.GetAsString());
72 serializer.write(
"args",
args.value());
74 serializer.write(
"ret_status",
ret_status.value());
76 serializer.write(
"error_data",
error_data.value());
92 serializer.write(
"uuid",
uuid.GetAsString());
93 serializer.write(
"pid",
pid);
94 serializer.write(
"triple",
triple);
101 serializer.write(
"module_uuid",
module_uuid.GetAsString());
102 serializer.write(
"pid",
pid);
105 serializer.write(
"exit_code",
exit_desc->exit_code);
106 serializer.write(
"exit_desc",
exit_desc->description);
116 lldb_entry->SessionId =
m_id;
119 return llvm::Error::success();
123static std::optional<std::chrono::nanoseconds>
126 if (!value->IsValid()) {
128 "Cannot determine {0} from client-telemetry entry", key);
132 return std::chrono::nanoseconds(value->GetUnsignedIntegerValue(0));
137 if (!
m_config->enable_client_telemetry)
148 auto *dict = entry.
GetObjectSP()->GetAsDictionary();
150 llvm::StringRef client_name;
151 if (dict->GetValueForKeyAsString(
"client_name", client_name))
155 "Cannot determine client_name from client-telemetry entry");
157 llvm::StringRef client_data;
158 if (dict->GetValueForKeyAsString(
"client_data", client_data))
162 "Cannot determine client_data from client-telemetry entry");
164 if (
auto maybe_start_time =
GetAsNanosec(dict,
"start_time"))
167 if (
auto maybe_end_time =
GetAsNanosec(dict,
"end_time")) {
169 client_info.
end_time = epoch + *maybe_end_time;
172 llvm::StringRef error_msg;
173 if (dict->GetValueForKeyAsString(
"error", error_msg))
176 if (llvm::Error er = dispatch(&client_info))
178 "Failed to dispatch client telemetry");
185 return llvm::Error::success();
194 return "NoOpTelemetryManager";
204 return llvm::Error::success();
208 static std::unique_ptr<NoOpTelemetryManager> g_ins =
209 std::make_unique<NoOpTelemetryManager>();
219 if (!Config::BuildTimeEnableTelemetry || !
g_instance)
225 if (Config::BuildTimeEnableTelemetry)
#define LLDB_LOG(log,...)
The LLDB_LOG* macros defined below are the way to emit log messages.
#define LLDB_LOG_ERROR(log, error,...)
A class to manage flag bits.
StructuredData::ObjectSP GetObjectSP()
ObjectSP GetValueForKey(llvm::StringRef key) const
Represents UUID's of various sizes.
static UUID Generate(uint32_t num_bytes=16)
Create a random UUID.
std::string GetAsString(llvm::StringRef separator="-") const
llvm::Error dispatch(llvm::telemetry::TelemetryInfo *entry) override
void DispatchClientTelemetry(const lldb_private::StructuredDataImpl &entry, Debugger *debugger) override
virtual llvm::StringRef GetInstanceName() const override
static NoOpTelemetryManager * GetInstance()
llvm::Error preDispatch(llvm::telemetry::TelemetryInfo *entry) override
virtual void DispatchClientTelemetry(const lldb_private::StructuredDataImpl &entry, Debugger *debugger)
static void SetInstance(std::unique_ptr< TelemetryManager > manger)
TelemetryManager(std::unique_ptr< LLDBConfig > config)
llvm::Error preDispatch(llvm::telemetry::TelemetryInfo *entry) override
static TelemetryManager * GetInstance()
static std::unique_ptr< TelemetryManager > g_instance
std::unique_ptr< LLDBConfig > m_config
static std::optional< std::chrono::nanoseconds > GetAsNanosec(StructuredData::Dictionary *dict, llvm::StringRef key)
std::chrono::time_point< std::chrono::steady_clock, std::chrono::nanoseconds > SteadyTimePoint
Defines a convenient type for timestamp of various events.
static uint64_t ToNanosec(const SteadyTimePoint Point)
static std::string MakeUUID()
A class that represents a running process on the host machine.
Log * GetLog(Cat mask)
Retrieve the Log object for the channel associated with the given log enum.
@ eStructuredDataTypeDictionary
void serialize(llvm::telemetry::Serializer &serializer) const override
std::optional< std::string > error_msg
void serialize(llvm::telemetry::Serializer &serializer) const override
std::optional< std::string > original_command
These two fields are not collected by default due to PII risks.
std::string command_name
The command name(eg., "breakpoint set")
std::optional< lldb::ReturnStatus > ret_status
Return status of a command and any error description in case of error.
UUID target_uuid
If the command is/can be associated with a target entry this field contains that target's UUID.
std::optional< std::string > args
uint64_t command_id
A unique ID for a command so the manager can match the start entry with its end entry.
static std::atomic< uint64_t > g_command_id_seed
static uint64_t GetNextID()
std::optional< std::string > error_data
void serialize(llvm::telemetry::Serializer &serializer) const override
void serialize(llvm::telemetry::Serializer &serializer) const override
std::string triple
The triple of this executable module.
bool is_start_entry
If true, this entry was emitted at the beginning of an event (eg., before the executable is set).
UUID uuid
The same as the executable-module's UUID.
lldb::pid_t pid
PID of the process owned by this target.
SteadyTimePoint start_time
Start time of an event.
lldb::user_id_t debugger_id
void serialize(llvm::telemetry::Serializer &serializer) const override
llvm::telemetry::KindType getKind() const override
std::optional< SteadyTimePoint > end_time
End time of an event - may be empty if not meaningful.
std::optional< ExitDescription > exit_desc
void serialize(llvm::telemetry::Serializer &serializer) const override