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

Side by Side Diff: components/ukm/ukm_service.cc

Issue 2722983006: Add UKM initial_url and session_id fields. (Closed)
Patch Set: fix android build take 2 Created 3 years, 9 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 unified diff | Download patch
« no previous file with comments | « components/ukm/ukm_service.h ('k') | components/ukm/ukm_service_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2017 The Chromium Authors. All rights reserved. 1 // Copyright 2017 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "components/ukm/ukm_service.h" 5 #include "components/ukm/ukm_service.h"
6 6
7 #include <memory> 7 #include <memory>
8 #include <string> 8 #include <string>
9 #include <utility> 9 #include <utility>
10 10
11 #include "base/bind.h" 11 #include "base/bind.h"
12 #include "base/feature_list.h" 12 #include "base/feature_list.h"
13 #include "base/memory/ptr_util.h" 13 #include "base/memory/ptr_util.h"
14 #include "base/metrics/field_trial.h" 14 #include "base/metrics/field_trial.h"
15 #include "base/metrics/field_trial_params.h"
15 #include "base/metrics/histogram_macros.h" 16 #include "base/metrics/histogram_macros.h"
16 #include "base/rand_util.h" 17 #include "base/rand_util.h"
17 #include "base/strings/string_number_conversions.h" 18 #include "base/strings/string_number_conversions.h"
18 #include "base/time/time.h" 19 #include "base/time/time.h"
19 #include "components/metrics/metrics_log.h" 20 #include "components/metrics/metrics_log.h"
20 #include "components/metrics/metrics_log_uploader.h" 21 #include "components/metrics/metrics_log_uploader.h"
21 #include "components/metrics/metrics_service_client.h" 22 #include "components/metrics/metrics_service_client.h"
22 #include "components/metrics/proto/ukm/entry.pb.h" 23 #include "components/metrics/proto/ukm/entry.pb.h"
23 #include "components/metrics/proto/ukm/report.pb.h" 24 #include "components/metrics/proto/ukm/report.pb.h"
24 #include "components/metrics/proto/ukm/source.pb.h" 25 #include "components/metrics/proto/ukm/source.pb.h"
25 #include "components/prefs/pref_registry_simple.h" 26 #include "components/prefs/pref_registry_simple.h"
26 #include "components/prefs/pref_service.h" 27 #include "components/prefs/pref_service.h"
27 #include "components/ukm/metrics_reporting_scheduler.h" 28 #include "components/ukm/metrics_reporting_scheduler.h"
28 #include "components/ukm/persisted_logs_metrics_impl.h" 29 #include "components/ukm/persisted_logs_metrics_impl.h"
29 #include "components/ukm/ukm_entry.h" 30 #include "components/ukm/ukm_entry.h"
30 #include "components/ukm/ukm_entry_builder.h" 31 #include "components/ukm/ukm_entry_builder.h"
31 #include "components/ukm/ukm_pref_names.h" 32 #include "components/ukm/ukm_pref_names.h"
32 #include "components/ukm/ukm_source.h" 33 #include "components/ukm/ukm_source.h"
33 #include "components/variations/variations_associated_data.h"
34 34
35 namespace ukm { 35 namespace ukm {
36 36
37 namespace { 37 namespace {
38 38
39 constexpr char kMimeType[] = "application/vnd.chrome.ukm"; 39 constexpr char kMimeType[] = "application/vnd.chrome.ukm";
40 40
41 // The UKM server's URL. 41 // The UKM server's URL.
42 constexpr char kDefaultServerUrl[] = "https://clients4.google.com/ukm"; 42 constexpr char kDefaultServerUrl[] = "https://clients4.google.com/ukm";
43 43
(...skipping 20 matching lines...) Expand all
64 // Maximum number of Sources we'll keep in memory before discarding any 64 // Maximum number of Sources we'll keep in memory before discarding any
65 // new ones being added. 65 // new ones being added.
66 const size_t kMaxSources = 500; 66 const size_t kMaxSources = 500;
67 67
68 // Maximum number of Entries we'll keep in memory before discarding any 68 // Maximum number of Entries we'll keep in memory before discarding any
69 // new ones being added. 69 // new ones being added.
70 const size_t kMaxEntries = 5000; 70 const size_t kMaxEntries = 5000;
71 71
72 std::string GetServerUrl() { 72 std::string GetServerUrl() {
73 std::string server_url = 73 std::string server_url =
74 variations::GetVariationParamValueByFeature(kUkmFeature, "ServerUrl"); 74 base::GetFieldTrialParamValueByFeature(kUkmFeature, "ServerUrl");
75 if (!server_url.empty()) 75 if (!server_url.empty())
76 return server_url; 76 return server_url;
77 return kDefaultServerUrl; 77 return kDefaultServerUrl;
78 } 78 }
79 79
80 bool ShouldRecordInitialUrl() {
81 return base::GetFieldTrialParamByFeatureAsBool(kUkmFeature,
82 "RecordInitialUrl", false);
83 }
84
85 bool ShouldRecordSessionId() {
86 return base::GetFieldTrialParamByFeatureAsBool(kUkmFeature, "RecordSessionId",
87 false);
88 }
89
80 // Generates a new client id and stores it in prefs. 90 // Generates a new client id and stores it in prefs.
81 uint64_t GenerateClientId(PrefService* pref_service) { 91 uint64_t GenerateClientId(PrefService* pref_service) {
82 uint64_t client_id = 0; 92 uint64_t client_id = 0;
83 while (!client_id) 93 while (!client_id)
84 client_id = base::RandUint64(); 94 client_id = base::RandUint64();
85 pref_service->SetInt64(prefs::kUkmClientId, client_id); 95 pref_service->SetInt64(prefs::kUkmClientId, client_id);
96
97 // Also reset the session id counter.
98 pref_service->SetInteger(prefs::kUkmSessionId, 0);
86 return client_id; 99 return client_id;
87 } 100 }
88 101
89 uint64_t LoadOrGenerateClientId(PrefService* pref_service) { 102 uint64_t LoadOrGenerateClientId(PrefService* pref_service) {
90 uint64_t client_id = pref_service->GetInt64(prefs::kUkmClientId); 103 uint64_t client_id = pref_service->GetInt64(prefs::kUkmClientId);
91 if (!client_id) 104 if (!client_id)
92 client_id = GenerateClientId(pref_service); 105 client_id = GenerateClientId(pref_service);
93 return client_id; 106 return client_id;
94 } 107 }
95 108
109 int32_t LoadSessionId(PrefService* pref_service) {
110 int32_t session_id = pref_service->GetInteger(prefs::kUkmSessionId);
111 ++session_id; // increment session id, once per session
112 pref_service->SetInteger(prefs::kUkmSessionId, session_id);
113 return session_id;
114 }
115
96 enum class DroppedDataReason { 116 enum class DroppedDataReason {
97 NOT_DROPPED = 0, 117 NOT_DROPPED = 0,
98 RECORDING_DISABLED = 1, 118 RECORDING_DISABLED = 1,
99 MAX_HIT = 2, 119 MAX_HIT = 2,
100 NUM_DROPPED_DATA_REASONS 120 NUM_DROPPED_DATA_REASONS
101 }; 121 };
102 122
103 void RecordDroppedSource(DroppedDataReason reason) { 123 void RecordDroppedSource(DroppedDataReason reason) {
104 UMA_HISTOGRAM_ENUMERATION( 124 UMA_HISTOGRAM_ENUMERATION(
105 "UKM.Sources.Dropped", static_cast<int>(reason), 125 "UKM.Sources.Dropped", static_cast<int>(reason),
106 static_cast<int>(DroppedDataReason::NUM_DROPPED_DATA_REASONS)); 126 static_cast<int>(DroppedDataReason::NUM_DROPPED_DATA_REASONS));
107 } 127 }
108 128
109 void RecordDroppedEntry(DroppedDataReason reason) { 129 void RecordDroppedEntry(DroppedDataReason reason) {
110 UMA_HISTOGRAM_ENUMERATION( 130 UMA_HISTOGRAM_ENUMERATION(
111 "UKM.Entries.Dropped", static_cast<int>(reason), 131 "UKM.Entries.Dropped", static_cast<int>(reason),
112 static_cast<int>(DroppedDataReason::NUM_DROPPED_DATA_REASONS)); 132 static_cast<int>(DroppedDataReason::NUM_DROPPED_DATA_REASONS));
113 } 133 }
114 134
115 } // namespace 135 } // namespace
116 136
117 const base::Feature kUkmFeature = {"Ukm", base::FEATURE_DISABLED_BY_DEFAULT}; 137 const base::Feature kUkmFeature = {"Ukm", base::FEATURE_DISABLED_BY_DEFAULT};
118 138
119 UkmService::UkmService(PrefService* pref_service, 139 UkmService::UkmService(PrefService* pref_service,
120 metrics::MetricsServiceClient* client) 140 metrics::MetricsServiceClient* client)
121 : pref_service_(pref_service), 141 : pref_service_(pref_service),
122 recording_enabled_(false), 142 recording_enabled_(false),
143 client_id_(0),
144 session_id_(0),
123 client_(client), 145 client_(client),
124 persisted_logs_(std::unique_ptr<ukm::PersistedLogsMetricsImpl>( 146 persisted_logs_(std::unique_ptr<ukm::PersistedLogsMetricsImpl>(
125 new ukm::PersistedLogsMetricsImpl()), 147 new ukm::PersistedLogsMetricsImpl()),
126 pref_service, 148 pref_service,
127 prefs::kUkmPersistedLogs, 149 prefs::kUkmPersistedLogs,
128 kMinPersistedLogs, 150 kMinPersistedLogs,
129 kMinPersistedBytes, 151 kMinPersistedBytes,
130 kMaxLogRetransmitSize), 152 kMaxLogRetransmitSize),
131 initialize_started_(false), 153 initialize_started_(false),
132 initialize_complete_(false), 154 initialize_complete_(false),
(...skipping 18 matching lines...) Expand all
151 for (auto& provider : metrics_providers_) 173 for (auto& provider : metrics_providers_)
152 provider->Init(); 174 provider->Init();
153 } 175 }
154 176
155 UkmService::~UkmService() { 177 UkmService::~UkmService() {
156 DisableReporting(); 178 DisableReporting();
157 } 179 }
158 180
159 void UkmService::Initialize() { 181 void UkmService::Initialize() {
160 DCHECK(thread_checker_.CalledOnValidThread()); 182 DCHECK(thread_checker_.CalledOnValidThread());
183 DCHECK(!initialize_started_);
161 DVLOG(1) << "UkmService::Initialize"; 184 DVLOG(1) << "UkmService::Initialize";
162 initialize_started_ = true; 185 initialize_started_ = true;
163 186
164 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( 187 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
165 FROM_HERE, 188 FROM_HERE,
166 base::Bind(&UkmService::StartInitTask, self_ptr_factory_.GetWeakPtr()), 189 base::Bind(&UkmService::StartInitTask, self_ptr_factory_.GetWeakPtr()),
167 base::TimeDelta::FromSeconds(kInitializationDelaySeconds)); 190 base::TimeDelta::FromSeconds(kInitializationDelaySeconds));
168 } 191 }
169 192
170 void UkmService::EnableRecording() { 193 void UkmService::EnableRecording() {
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
237 260
238 void UkmService::Purge() { 261 void UkmService::Purge() {
239 DCHECK(thread_checker_.CalledOnValidThread()); 262 DCHECK(thread_checker_.CalledOnValidThread());
240 DVLOG(1) << "UkmService::Purge"; 263 DVLOG(1) << "UkmService::Purge";
241 264
242 persisted_logs_.Purge(); 265 persisted_logs_.Purge();
243 sources_.clear(); 266 sources_.clear();
244 entries_.clear(); 267 entries_.clear();
245 } 268 }
246 269
270 // TODO(bmcquade): rename this to something more generic, like
271 // ResetClientState. Consider resetting all prefs here.
247 void UkmService::ResetClientId() { 272 void UkmService::ResetClientId() {
248 client_id_ = GenerateClientId(pref_service_); 273 client_id_ = GenerateClientId(pref_service_);
274 session_id_ = LoadSessionId(pref_service_);
249 } 275 }
250 276
251 void UkmService::RegisterMetricsProvider( 277 void UkmService::RegisterMetricsProvider(
252 std::unique_ptr<metrics::MetricsProvider> provider) { 278 std::unique_ptr<metrics::MetricsProvider> provider) {
253 metrics_providers_.push_back(std::move(provider)); 279 metrics_providers_.push_back(std::move(provider));
254 } 280 }
255 281
256 // static 282 // static
257 void UkmService::RegisterPrefs(PrefRegistrySimple* registry) { 283 void UkmService::RegisterPrefs(PrefRegistrySimple* registry) {
258 registry->RegisterInt64Pref(prefs::kUkmClientId, 0); 284 registry->RegisterInt64Pref(prefs::kUkmClientId, 0);
285 registry->RegisterIntegerPref(prefs::kUkmSessionId, 0);
259 registry->RegisterListPref(prefs::kUkmPersistedLogs); 286 registry->RegisterListPref(prefs::kUkmPersistedLogs);
260 } 287 }
261 288
262 void UkmService::StartInitTask() { 289 void UkmService::StartInitTask() {
263 DCHECK(thread_checker_.CalledOnValidThread()); 290 DCHECK(thread_checker_.CalledOnValidThread());
264 DVLOG(1) << "UkmService::StartInitTask"; 291 DVLOG(1) << "UkmService::StartInitTask";
265 client_id_ = LoadOrGenerateClientId(pref_service_); 292 client_id_ = LoadOrGenerateClientId(pref_service_);
293 session_id_ = LoadSessionId(pref_service_);
266 client_->InitializeSystemProfileMetrics(base::Bind( 294 client_->InitializeSystemProfileMetrics(base::Bind(
267 &UkmService::FinishedInitTask, self_ptr_factory_.GetWeakPtr())); 295 &UkmService::FinishedInitTask, self_ptr_factory_.GetWeakPtr()));
268 } 296 }
269 297
270 void UkmService::FinishedInitTask() { 298 void UkmService::FinishedInitTask() {
271 DCHECK(thread_checker_.CalledOnValidThread()); 299 DCHECK(thread_checker_.CalledOnValidThread());
272 DVLOG(1) << "UkmService::FinishedInitTask"; 300 DVLOG(1) << "UkmService::FinishedInitTask";
273 initialize_complete_ = true; 301 initialize_complete_ = true;
274 scheduler_->InitTaskComplete(); 302 scheduler_->InitTaskComplete();
275 } 303 }
(...skipping 11 matching lines...) Expand all
287 DCHECK(thread_checker_.CalledOnValidThread()); 315 DCHECK(thread_checker_.CalledOnValidThread());
288 DVLOG(1) << "UkmService::BuildAndStoreLog"; 316 DVLOG(1) << "UkmService::BuildAndStoreLog";
289 317
290 // Suppress generating a log if we have no new data to include. 318 // Suppress generating a log if we have no new data to include.
291 // TODO(zhenw): add a histogram here to debug if this case is hitting a lot. 319 // TODO(zhenw): add a histogram here to debug if this case is hitting a lot.
292 if (sources_.empty() && entries_.empty()) 320 if (sources_.empty() && entries_.empty())
293 return; 321 return;
294 322
295 Report report; 323 Report report;
296 report.set_client_id(client_id_); 324 report.set_client_id(client_id_);
325 if (ShouldRecordSessionId())
326 report.set_session_id(session_id_);
297 327
298 for (const auto& source : sources_) { 328 for (const auto& source : sources_) {
299 Source* proto_source = report.add_sources(); 329 Source* proto_source = report.add_sources();
300 source->PopulateProto(proto_source); 330 source->PopulateProto(proto_source);
331 if (!ShouldRecordInitialUrl())
332 proto_source->clear_initial_url();
301 } 333 }
302 for (const auto& entry : entries_) { 334 for (const auto& entry : entries_) {
303 Entry* proto_entry = report.add_entries(); 335 Entry* proto_entry = report.add_entries();
304 entry->PopulateProto(proto_entry); 336 entry->PopulateProto(proto_entry);
305 } 337 }
306 338
307 UMA_HISTOGRAM_COUNTS_1000("UKM.Sources.SerializedCount", sources_.size()); 339 UMA_HISTOGRAM_COUNTS_1000("UKM.Sources.SerializedCount", sources_.size());
308 UMA_HISTOGRAM_COUNTS_1000("UKM.Entries.SerializedCount", entries_.size()); 340 UMA_HISTOGRAM_COUNTS_1000("UKM.Entries.SerializedCount", entries_.size());
309 sources_.clear(); 341 sources_.clear();
310 entries_.clear(); 342 entries_.clear();
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after
416 return; 448 return;
417 } 449 }
418 450
419 // Update the pre-existing source if there is any. This happens when the 451 // Update the pre-existing source if there is any. This happens when the
420 // initial URL is different from the committed URL for the same source, e.g., 452 // initial URL is different from the committed URL for the same source, e.g.,
421 // when there is redirection. 453 // when there is redirection.
422 for (auto& source : sources_) { 454 for (auto& source : sources_) {
423 if (source_id != source->id()) 455 if (source_id != source->id())
424 continue; 456 continue;
425 457
426 source->set_url(url); 458 source->UpdateUrl(url);
427 return; 459 return;
428 } 460 }
429 461
430 if (sources_.size() >= kMaxSources) { 462 if (sources_.size() >= kMaxSources) {
431 RecordDroppedSource(DroppedDataReason::MAX_HIT); 463 RecordDroppedSource(DroppedDataReason::MAX_HIT);
432 return; 464 return;
433 } 465 }
434 std::unique_ptr<UkmSource> source = base::MakeUnique<UkmSource>(); 466 std::unique_ptr<UkmSource> source = base::MakeUnique<UkmSource>();
435 source->set_id(source_id); 467 source->set_id(source_id);
436 source->set_url(url); 468 source->set_url(url);
437 sources_.push_back(std::move(source)); 469 sources_.push_back(std::move(source));
438 } 470 }
439 471
440 void UkmService::AddEntry(std::unique_ptr<UkmEntry> entry) { 472 void UkmService::AddEntry(std::unique_ptr<UkmEntry> entry) {
441 DCHECK(thread_checker_.CalledOnValidThread()); 473 DCHECK(thread_checker_.CalledOnValidThread());
442 474
443 if (!recording_enabled_) { 475 if (!recording_enabled_) {
444 RecordDroppedEntry(DroppedDataReason::RECORDING_DISABLED); 476 RecordDroppedEntry(DroppedDataReason::RECORDING_DISABLED);
445 return; 477 return;
446 } 478 }
447 if (entries_.size() >= kMaxEntries) { 479 if (entries_.size() >= kMaxEntries) {
448 RecordDroppedEntry(DroppedDataReason::MAX_HIT); 480 RecordDroppedEntry(DroppedDataReason::MAX_HIT);
449 return; 481 return;
450 } 482 }
451 483
452 entries_.push_back(std::move(entry)); 484 entries_.push_back(std::move(entry));
453 } 485 }
454 486
455 } // namespace ukm 487 } // namespace ukm
OLDNEW
« no previous file with comments | « components/ukm/ukm_service.h ('k') | components/ukm/ukm_service_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698