123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327 |
- // Copyright 2021 The Chromium Authors. All rights reserved.
- // Use of this source code is governed by a BSD-style license that can be
- // found in the LICENSE file.
- #include "chromecast/metrics/metrics_recorder.h"
- #include <stdint.h>
- #include <map>
- #include <string>
- #include <utility>
- #include <vector>
- #include "base/bind.h"
- #include "base/callback_helpers.h"
- #include "base/check.h"
- #include "base/containers/flat_map.h"
- #include "base/logging.h"
- #include "base/memory/ptr_util.h"
- #include "base/memory/ref_counted.h"
- #include "base/notreached.h"
- #include "base/observer_list.h"
- #include "base/synchronization/lock.h"
- #include "base/task/single_thread_task_runner.h"
- #include "base/threading/thread_task_runner_handle.h"
- #include "base/time/time.h"
- #include "chromecast/metrics/cast_event_builder.h"
- #include "net/base/ip_address.h"
- namespace chromecast {
- namespace {
- bool IsLogOn(int verbose_log_level) {
- // TODO(b/135640848): Determine a better way to log metrics for
- // Fuchsia, without producing logspam during development.
- return -verbose_log_level >= logging::GetMinLogLevel() ||
- (DCHECK_IS_ON() && VLOG_IS_ON(verbose_log_level));
- }
- // A no-op dummy event builder, used when MetricsRecorder is nullptr.
- class DummyEventBuilder : public CastEventBuilder {
- public:
- // receiver::CastEventBuilder implementation
- std::string GetName() override { return ""; }
- CastEventBuilder& SetName(const std::string& name) override { return *this; }
- CastEventBuilder& SetTime(const base::TimeTicks& time) override {
- return *this;
- }
- CastEventBuilder& SetTimezoneId(const std::string& timezone_id) override {
- return *this;
- }
- CastEventBuilder& SetAppId(const std::string& app_id) override {
- return *this;
- }
- CastEventBuilder& SetRemoteAppId(const std::string& remote_app_id) override {
- return *this;
- }
- CastEventBuilder& SetSessionId(const std::string& session_id) override {
- return *this;
- }
- CastEventBuilder& SetSdkVersion(const std::string& sdk_version) override {
- return *this;
- }
- CastEventBuilder& SetMplVersion(const std::string& mpl_version) override {
- return *this;
- }
- CastEventBuilder& SetConnectionInfo(
- const std::string& transport_connection_id,
- const std::string& virtual_connection_id) override {
- return *this;
- }
- CastEventBuilder& SetGroupUuid(const std::string& group_uuid) override {
- return *this;
- }
- CastEventBuilder& SetExtraValue(int64_t extra_value) override {
- return *this;
- }
- CastEventBuilder& SetConversationKey(
- const std::string& conversation_key) override {
- return *this;
- }
- CastEventBuilder& SetRequestId(int32_t request_id) override { return *this; }
- CastEventBuilder& SetEventId(const std::string& event_id) override {
- return *this;
- }
- CastEventBuilder& SetAoghRequestId(const std::string& request_id) override {
- return *this;
- }
- CastEventBuilder& SetAoghLocalDeviceId(int64_t local_id) override {
- return *this;
- }
- CastEventBuilder& SetAoghAgentId(const std::string& agent_id) override {
- return *this;
- }
- CastEventBuilder& SetUiVersion(const std::string& ui_version) override {
- return *this;
- }
- CastEventBuilder& SetAuditReport(const std::string& audit_report) override {
- return *this;
- }
- CastEventBuilder& SetDuoCoreVersion(int64_t version) override {
- return *this;
- }
- CastEventBuilder& SetHotwordModelId(const std::string& model_id) override {
- return *this;
- }
- CastEventBuilder& SetDiscoveryAppSubtype(const std::string& app_id) override {
- return *this;
- }
- CastEventBuilder& SetDiscoveryNamespaceSubtype(
- const std::string& namespace_hash) override {
- return *this;
- }
- CastEventBuilder& SetDiscoverySender(
- const net::IPAddressBytes& sender_ip) override {
- return *this;
- }
- CastEventBuilder& SetDiscoveryUnicastFlag(bool uses_unicast) override {
- return *this;
- }
- CastEventBuilder& SetFeatureVector(
- const std::vector<float>& features) override {
- return *this;
- }
- CastEventBuilder& AddMetadata(const std::string& name,
- int64_t value) override {
- return *this;
- }
- CastEventBuilder& SetLaunchFrom(LaunchFrom launch_from) override {
- return *this;
- }
- CastEventBuilder& MergeFrom(
- const ::metrics::CastLogsProto_CastEventProto* event_proto) override {
- return *this;
- }
- ::metrics::CastLogsProto_CastEventProto* Build() override {
- NOTREACHED();
- return nullptr;
- }
- };
- MetricsRecorder* g_instance = nullptr;
- } // namespace
- void RecordEventWithLogPrefix(const std::string& action,
- std::unique_ptr<CastEventBuilder> event_builder,
- int verbose_log_level,
- const std::string& log_prefix) {
- MetricsRecorder* recorder = MetricsRecorder::GetInstance();
- if (recorder && event_builder) {
- recorder->RecordCastEvent(std::move(event_builder));
- }
- if (IsLogOn(verbose_log_level)) {
- VLOG_STREAM(verbose_log_level) << log_prefix << action;
- }
- }
- std::unique_ptr<CastEventBuilder> CreateCastEvent(const std::string& name) {
- MetricsRecorder* recorder = MetricsRecorder::GetInstance();
- if (recorder) {
- return recorder->CreateEventBuilder(name);
- }
- return std::make_unique<DummyEventBuilder>();
- }
- void RecordCastEvent(const std::string& log_name,
- std::unique_ptr<CastEventBuilder> event_builder,
- int verbose_log_level) {
- RecordEventWithLogPrefix(log_name, std::move(event_builder),
- verbose_log_level, "cast event: ");
- }
- void RecordAction(const std::string& action, int verbose_log_level) {
- RecordEventWithLogPrefix(action, CreateCastEvent(action), verbose_log_level,
- "Record action: ");
- }
- void LogAction(const std::string& action, int verbose_log_level) {
- RecordEventWithLogPrefix(action, std::unique_ptr<CastEventBuilder>(),
- verbose_log_level, "Log action: ");
- }
- void RecordHistogramTime(const std::string& name,
- int sample,
- int min,
- int max,
- int num_buckets,
- int verbose_log_level) {
- MetricsRecorder* recorder = MetricsRecorder::GetInstance();
- if (recorder) {
- recorder->RecordHistogramTime(name, sample, min, max, num_buckets);
- }
- if (IsLogOn(verbose_log_level)) {
- VLOG_STREAM(verbose_log_level)
- << "Time histogram: " << name << ", sample=" << sample
- << ", max=" << max << ", min=" << min
- << ", num_buckets=" << num_buckets;
- }
- }
- void RecordHistogramCount(const std::string& name,
- int sample,
- int min,
- int max,
- int num_buckets,
- int verbose_log_level) {
- MetricsRecorder* recorder = MetricsRecorder::GetInstance();
- if (recorder) {
- recorder->RecordHistogramCount(name, sample, min, max, num_buckets);
- }
- if (IsLogOn(verbose_log_level)) {
- VLOG_STREAM(verbose_log_level)
- << "Count histogram: " << name << ", sample=" << sample
- << ", max=" << max << ", min=" << min
- << ", num_buckets=" << num_buckets;
- }
- }
- void RecordHistogramEnum(const std::string& name,
- int sample,
- int boundary,
- int verbose_log_level) {
- MetricsRecorder* recorder = MetricsRecorder::GetInstance();
- if (recorder) {
- recorder->RecordHistogramEnum(name, sample, boundary);
- }
- if (IsLogOn(verbose_log_level)) {
- VLOG_STREAM(verbose_log_level)
- << "Count histogram: " << name << ", sample=" << sample
- << ", boundary=" << boundary;
- }
- }
- struct MetricsRecorder::ObserverList {
- base::ObserverList<Observer>::Unchecked list;
- };
- // static
- void MetricsRecorder::SetInstance(MetricsRecorder* recorder) {
- g_instance = recorder;
- }
- // static
- MetricsRecorder* MetricsRecorder::GetInstance() {
- return g_instance;
- }
- MetricsRecorder::MetricsRecorder()
- : observer_list_(std::make_unique<ObserverList>()) {}
- MetricsRecorder::~MetricsRecorder() = default;
- void MetricsRecorder::NotifyOnPreUpload() {
- for (auto& o : observer_list_->list)
- o.OnPreUpload();
- }
- void MetricsRecorder::AddObserver(Observer* o) {
- DCHECK(o);
- observer_list_->list.AddObserver(o);
- }
- void MetricsRecorder::RemoveObserver(Observer* o) {
- DCHECK(o);
- observer_list_->list.RemoveObserver(o);
- }
- void RecordCastEvent(const std::string& event,
- bool has_extra_value,
- int64_t value,
- MetricsRecorder* metrics_recorder) {
- DCHECK(metrics_recorder);
- auto event_builder = metrics_recorder->CreateEventBuilder(event);
- if (has_extra_value) {
- event_builder->SetExtraValue(value);
- }
- metrics_recorder->RecordCastEvent(std::move(event_builder));
- }
- void RecordCastEventWithMetadata(
- const std::string& event,
- const base::flat_map<std::string, int64_t>& settings_map,
- MetricsRecorder* metrics_recorder) {
- DCHECK(metrics_recorder);
- auto event_builder = metrics_recorder->CreateEventBuilder(event);
- for (const auto& kv_pair : settings_map) {
- event_builder->AddMetadata(kv_pair.first, kv_pair.second);
- }
- metrics_recorder->RecordCastEvent(std::move(event_builder));
- }
- } // namespace chromecast
|