Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(239)

Unified Diff: components/feature_engagement_tracker/internal/stats.cc

Issue 2911123003: Metrics for feature engagement tracker. (Closed)
Patch Set: Created 3 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « components/feature_engagement_tracker/internal/stats.h ('k') | tools/metrics/actions/actions.xml » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: components/feature_engagement_tracker/internal/stats.cc
diff --git a/components/feature_engagement_tracker/internal/stats.cc b/components/feature_engagement_tracker/internal/stats.cc
new file mode 100644
index 0000000000000000000000000000000000000000..a3e3e2ce0ab3e874cbfa161a29f5ab1d7f017591
--- /dev/null
+++ b/components/feature_engagement_tracker/internal/stats.cc
@@ -0,0 +1,192 @@
+// Copyright 2017 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 "components/feature_engagement_tracker/internal/stats.h"
+
+#include <string>
+
+#include "base/metrics/histogram_functions.h"
+#include "base/metrics/histogram_macros.h"
+#include "base/metrics/user_metrics.h"
+#include "components/feature_engagement_tracker/public/feature_list.h"
+
+namespace feature_engagement_tracker {
+namespace stats {
+namespace {
+
+// Histogram suffixes for database metrics, must match the ones in
+// histograms.xml.
+const char kEventStoreSuffix[] = "EventStore";
+const char kAvailabilityStoreSuffix[] = "AvailabilityStore";
+
+// Helper function to log a TriggerHelpUIResult.
+void LogTriggerHelpUIResult(const std::string& name,
+ TriggerHelpUIResult result) {
+ // Must not use histograms macros here because we pass in the histogram name.
+ base::UmaHistogramEnumeration(name, result, TriggerHelpUIResult::COUNT);
+}
+
+} // namespace
+
+std::string ToDbHistogramSuffix(StoreType type) {
+ switch (type) {
+ case StoreType::EVENTS_STORE:
+ return std::string(kEventStoreSuffix);
+ case StoreType::AVAILABILITY_STORE:
+ return std::string(kAvailabilityStoreSuffix);
+ default:
+ NOTREACHED();
+ return std::string();
+ }
+}
+
+void RecordNotifyEvent(const std::string& event_name,
+ const Configuration* config,
+ bool is_model_ready) {
+ DCHECK(!event_name.empty());
+ DCHECK(config);
+
+ // Find which feature this event belongs to.
+ const Configuration::ConfigMap& features = config->GetRegisteredFeatures();
+ std::string feature_name;
+ for (const auto& element : features) {
+ const base::Feature* feature = element.first;
+ const FeatureConfig& feature_config = element.second;
+
+ // Track used event separately.
+ if (feature_config.used.name == event_name) {
+ feature_name = feature->name;
+ DCHECK(!feature_name.empty());
+ std::string used_event_action = "InProductHelp.NotifyUsedEvent.";
+ used_event_action.append(feature_name);
+ base::RecordComputedAction(used_event_action);
+ break;
+ }
+
+ // Find if the |event_name| matches any configuration.
+ for (const auto& event : feature_config.event_configs) {
+ if (event.name == event_name) {
+ feature_name = feature->name;
+ break;
+ }
+ }
+ if (feature_config.trigger.name == event_name) {
+ feature_name = feature->name;
+ break;
+ }
+ }
+
+ // Do nothing if no events in the configuration matches the |event_name|.
+ if (feature_name.empty())
+ return;
+
+ std::string event_action = "InProductHelp.NotifyEvent.";
+ event_action.append(feature_name);
+ base::RecordComputedAction(event_action);
+
+ std::string event_histogram = "InProductHelp.NotifyEventReadyState.";
+ event_histogram.append(feature_name);
+ base::UmaHistogramBoolean(event_histogram, is_model_ready);
+}
+
+void RecordShouldTriggerHelpUI(const base::Feature& feature,
+ const ConditionValidator::Result& result) {
+ // Records the user action.
+ std::string name = "InProductHelp.ShouldTriggerHelpUI.";
+ name.append(feature.name);
+ base::RecordComputedAction(name);
+
+ // Total count histogram, used to compute the percentage of each failure type.
+ if (result.NoErrors()) {
+ LogTriggerHelpUIResult(name, TriggerHelpUIResult::SUCCESS);
+ } else {
+ LogTriggerHelpUIResult(name, TriggerHelpUIResult::FAILURE);
+ }
+
+ // Histogram about the failure reasons.
+ if (!result.event_model_ready_ok)
+ LogTriggerHelpUIResult(name, TriggerHelpUIResult::FAILURE_MODEL_NOT_READY);
+ if (!result.currently_showing_ok) {
+ LogTriggerHelpUIResult(name,
+ TriggerHelpUIResult::FAILURE_CURRENTLY_SHOWING);
+ }
+ if (!result.feature_enabled_ok) {
+ LogTriggerHelpUIResult(name, TriggerHelpUIResult::FAILURE_FEATURE_DISABLED);
+ }
+ if (!result.config_ok) {
+ LogTriggerHelpUIResult(name, TriggerHelpUIResult::FAILURE_CONFIG_INVALID);
+ }
+ if (!result.used_ok) {
+ LogTriggerHelpUIResult(
+ name, TriggerHelpUIResult::FAILURE_USED_PRECONDITION_UNMET);
+ }
+ if (!result.trigger_ok) {
+ LogTriggerHelpUIResult(
+ name, TriggerHelpUIResult::FAILURE_TRIGGER_PRECONDITION_UNMET);
+ }
+ if (!result.preconditions_ok) {
+ LogTriggerHelpUIResult(
+ name, TriggerHelpUIResult::FAILURE_OTHER_PRECONDITION_UNMET);
+ }
+ if (!result.session_rate_ok) {
+ LogTriggerHelpUIResult(name, TriggerHelpUIResult::FAILURE_SESSION_RATE);
+ }
+ if (!result.availability_model_ready_ok) {
+ LogTriggerHelpUIResult(
+ name, TriggerHelpUIResult::FAILURE_AVAILABILITY_MODEL_NOT_READY);
+ }
+ if (!result.availability_ok) {
+ LogTriggerHelpUIResult(
+ name, TriggerHelpUIResult::FAILURE_AVAILABILITY_PRECONDITION_UNMET);
+ }
+}
+
+void RecordUserDismiss() {
+ base::RecordAction(base::UserMetricsAction("InProductHelp.Dismissed"));
+}
+
+void RecordDbUpdate(bool success, StoreType type) {
+ std::string histogram_name =
+ "InProductHelp.Db.Update." + ToDbHistogramSuffix(type);
+ base::UmaHistogramBoolean(histogram_name, success);
+}
+
+void RecordDbInitEvent(bool success, StoreType type) {
+ std::string histogram_name =
+ "InProductHelp.Db.Init." + ToDbHistogramSuffix(type);
+ base::UmaHistogramBoolean(histogram_name, success);
+}
+
+void RecordEventDbLoadEvent(bool success, const std::vector<Event>& events) {
+ std::string histogram_name =
+ "InProductHelp.Db.Load." + ToDbHistogramSuffix(StoreType::EVENTS_STORE);
+ base::UmaHistogramBoolean(histogram_name, success);
+ UMA_HISTOGRAM_BOOLEAN("InProductHelp.Db.Load", success);
+
+ if (!success)
+ return;
+
+ // Tracks total number of events records when the database is successfully
+ // loaded.
+ int event_count = 0;
+ for (const auto& event : events)
+ event_count += event.events_size();
+ UMA_HISTOGRAM_COUNTS_1000("InProductHelp.Db.TotalEvents", event_count);
+}
+
+void RecordAvailabilityDbLoadEvent(bool success) {
+ std::string histogram_name =
+ "InProductHelp.Db.Load." +
+ ToDbHistogramSuffix(StoreType::AVAILABILITY_STORE);
+ base::UmaHistogramBoolean(histogram_name, success);
+ UMA_HISTOGRAM_BOOLEAN("InProductHelp.Db.Load", success);
+}
+
+void RecordConfigParsingEvent(ConfigParsingEvent event) {
+ UMA_HISTOGRAM_ENUMERATION("InProductHelp.Config.ParsingEvent", event,
+ ConfigParsingEvent::COUNT);
+}
+
+} // namespace stats
+} // namespace feature_engagement_tracker
« no previous file with comments | « components/feature_engagement_tracker/internal/stats.h ('k') | tools/metrics/actions/actions.xml » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698