200 строки
5.7 KiB
C++
200 строки
5.7 KiB
C++
#pragma once
|
|
|
|
#include <vcpkg/base/fwd/files.h>
|
|
|
|
#include <vcpkg/base/stringview.h>
|
|
|
|
#include <atomic>
|
|
#include <map>
|
|
#include <mutex>
|
|
#include <set>
|
|
#include <string>
|
|
|
|
namespace vcpkg
|
|
{
|
|
enum class DefineMetric
|
|
{
|
|
AssetSource,
|
|
BinaryCachingAws,
|
|
BinaryCachingAzBlob,
|
|
BinaryCachingCos,
|
|
BinaryCachingDefault,
|
|
BinaryCachingFiles,
|
|
BinaryCachingGcs,
|
|
BinaryCachingHttp,
|
|
BinaryCachingNuget,
|
|
BinaryCachingSource,
|
|
BinaryCachingUpkg,
|
|
ErrorVersioningDisabled,
|
|
ErrorVersioningNoBaseline,
|
|
GitHubRepository,
|
|
ManifestBaseline,
|
|
ManifestOverrides,
|
|
ManifestVersionConstraint,
|
|
RegistriesErrorCouldNotFindBaseline,
|
|
RegistriesErrorNoVersionsAtCommit,
|
|
VcpkgBinarySources,
|
|
VcpkgDefaultBinaryCache,
|
|
VcpkgNugetRepository,
|
|
VersioningErrorBaseline,
|
|
VersioningErrorVersion, // no longer used
|
|
X_VcpkgRegistriesCache,
|
|
X_WriteNugetPackagesConfig,
|
|
COUNT // always keep COUNT last
|
|
};
|
|
|
|
struct DefineMetricEntry
|
|
{
|
|
DefineMetric metric;
|
|
StringLiteral name;
|
|
};
|
|
|
|
extern const DefineMetricEntry all_define_metrics[static_cast<size_t>(DefineMetric::COUNT)];
|
|
|
|
enum class StringMetric
|
|
{
|
|
AcquiredArtifacts,
|
|
ActivatedArtifacts,
|
|
CommandArgs,
|
|
CommandContext,
|
|
CommandName,
|
|
DeploymentKind,
|
|
DetectedCiEnvironment,
|
|
DevDeviceId,
|
|
CiProjectId,
|
|
CiOwnerId,
|
|
InstallPlan_1,
|
|
ListFile,
|
|
ProcessTree,
|
|
RegistriesDefaultRegistryKind,
|
|
RegistriesKindsUsed,
|
|
Title,
|
|
UserMac,
|
|
VcpkgVersion,
|
|
Warning,
|
|
COUNT // always keep COUNT last
|
|
};
|
|
|
|
struct StringMetricEntry
|
|
{
|
|
StringMetric metric;
|
|
StringLiteral name;
|
|
StringLiteral preregister_value; // mock values
|
|
};
|
|
|
|
extern const StringMetricEntry all_string_metrics[static_cast<size_t>(StringMetric::COUNT)];
|
|
|
|
enum class BoolMetric
|
|
{
|
|
DetectedContainer,
|
|
DependencyGraphSuccess,
|
|
FeatureFlagBinaryCaching,
|
|
FeatureFlagCompilerTracking,
|
|
FeatureFlagDependencyGraph,
|
|
FeatureFlagManifests,
|
|
FeatureFlagRegistries,
|
|
FeatureFlagVersions,
|
|
InstallManifestMode,
|
|
OptionOverlayPorts,
|
|
COUNT // always keep COUNT last
|
|
};
|
|
|
|
struct BoolMetricEntry
|
|
{
|
|
BoolMetric metric;
|
|
StringLiteral name;
|
|
};
|
|
|
|
extern const BoolMetricEntry all_bool_metrics[static_cast<size_t>(BoolMetric::COUNT)];
|
|
|
|
// Batches metrics changes so they can be submitted under a single lock acquisition or
|
|
// in a single JSON payload.
|
|
struct MetricsSubmission
|
|
{
|
|
void track_elapsed_us(double value);
|
|
void track_buildtime(StringView name, double value);
|
|
void track_define(DefineMetric metric);
|
|
void track_string(StringMetric metric, StringView value);
|
|
void track_bool(BoolMetric metric, bool value);
|
|
void merge(MetricsSubmission&& other);
|
|
|
|
double elapsed_us = 0.0;
|
|
std::map<std::string, double, std::less<>> buildtimes;
|
|
std::set<DefineMetric> defines;
|
|
std::map<StringMetric, std::string> strings;
|
|
std::map<BoolMetric, bool> bools;
|
|
};
|
|
|
|
// Collects metrics, potentially from multiple threads.
|
|
// Member functions of this type are safe to call from multiple threads, and will
|
|
// be observed in a total order.
|
|
struct MetricsCollector
|
|
{
|
|
MetricsCollector() = default;
|
|
MetricsCollector(const MetricsCollector&) = delete;
|
|
MetricsCollector& operator=(const MetricsCollector&) = delete;
|
|
~MetricsCollector() = default;
|
|
|
|
// Track
|
|
void track_elapsed_us(double value);
|
|
void track_buildtime(StringView name, double value);
|
|
void track_define(DefineMetric metric);
|
|
void track_string(StringMetric metric, StringView value);
|
|
void track_bool(BoolMetric metric, bool value);
|
|
void track_submission(MetricsSubmission&& submission_);
|
|
|
|
// Consume
|
|
MetricsSubmission get_submission() const;
|
|
|
|
private:
|
|
mutable std::mutex mtx;
|
|
MetricsSubmission submission;
|
|
};
|
|
|
|
MetricsCollector& get_global_metrics_collector() noexcept; // Meyers singleton
|
|
|
|
struct MetricsUserConfig
|
|
{
|
|
std::string user_id;
|
|
std::string user_time;
|
|
std::string user_mac;
|
|
|
|
std::string last_completed_survey;
|
|
|
|
void to_string(std::string&) const;
|
|
std::string to_string() const;
|
|
void try_write(const Filesystem& fs) const;
|
|
|
|
// If *this is missing data normally provided by the system, fill it in;
|
|
// otherwise, no effects.
|
|
// Returns whether any values needed to be modified.
|
|
bool fill_in_system_values();
|
|
};
|
|
|
|
MetricsUserConfig try_parse_metrics_user(StringView content);
|
|
MetricsUserConfig try_read_metrics_user(const ReadOnlyFilesystem& fs);
|
|
|
|
struct MetricsSessionData
|
|
{
|
|
std::string submission_time;
|
|
std::string os_version;
|
|
std::string session_id;
|
|
std::string parent_process_list;
|
|
|
|
static MetricsSessionData from_system();
|
|
};
|
|
|
|
std::string format_metrics_payload(const MetricsUserConfig& user,
|
|
const MetricsSessionData& session,
|
|
const MetricsSubmission& submission);
|
|
|
|
extern std::atomic<bool> g_metrics_enabled;
|
|
extern std::atomic<bool> g_should_print_metrics;
|
|
extern std::atomic<bool> g_should_send_metrics;
|
|
|
|
void flush_global_metrics(const Filesystem&);
|
|
#if defined(_WIN32)
|
|
void winhttp_upload_metrics(StringView payload);
|
|
#endif // ^^^ _WIN32
|
|
}
|