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

Side by Side Diff: components/rappor/rappor_service.cc

Issue 49753002: RAPPOR implementation (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 6 years, 11 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
OLDNEW
(Empty)
1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "components/rappor/rappor_service.h"
6
7 #include <cstdlib>
Alexei Svitkine (slow) 2014/01/24 22:09:03 Why is this needed?
Steven Holte 2014/01/24 23:26:58 Removed
8
9 #include "base/base64.h"
10 #include "base/hash.h"
11 #include "base/metrics/field_trial.h"
12 #include "base/prefs/pref_registry_simple.h"
13 #include "base/prefs/pref_service.h"
14 #include "base/rand_util.h"
15 #include "base/stl_util.h"
16 #include "components/rappor/proto/rappor_metric.pb.h"
17 #include "components/rappor/rappor_pref_names.h"
18 #include "components/variations/variations_associated_data.h"
19 #include "url/gurl.h"
20
21 namespace {
22
23 // Seconds before the initial log is generated.
24 const int kInitialLogIntervalSeconds = 15;
25 // Interval between ongoing logs.
26 const int kLogIntervalSeconds = 30 * 60;
27
28 const char kMimeType[] = "application/vnd.chrome.rappor";
29
30 // Constants for the RAPPOR rollout field trial.
31 const char kRapporRolloutFieldTrialName[] = "RapporRollout";
32
33 // Constant for the finch parameter name for the server URL
34 const char kRapporRolloutServerUrlParam[] = "ServerUrl";
35
36 GURL GetServerUrl() {
37 return GURL(chrome_variations::GetVariationParamValue(
38 kRapporRolloutFieldTrialName,
39 kRapporRolloutServerUrlParam));
40 }
41
42 } // namespace
43
44 namespace rappor {
45
46 RapporService::RapporService() {}
47
48 RapporService::~RapporService() {}
49
50 void RapporService::Start(PrefService* pref_service,
51 net::URLRequestContextGetter* request_context) {
52 GURL server_url = GetServerUrl();
53 if (!server_url.is_valid())
54 return;
55 DCHECK(!uploader_);
56 GetSecret(pref_service);
57 uploader_.reset(new LogUploader(server_url, kMimeType, request_context));
58 log_rotation_timer_.Start(
59 FROM_HERE,
60 base::TimeDelta::FromSeconds(kInitialLogIntervalSeconds),
61 this,
62 &RapporService::OnLogInterval);
63 }
64
65 void RapporService::OnLogInterval() {
66 DCHECK(uploader_);
67 RapporReports reports;
68 LogMetrics(&reports);
69 if (reports.report_size() > 0) {
70 std::string log_text;
71 bool success = reports.SerializeToString(&log_text);
72 DCHECK(success);
73 uploader_->QueueLog(log_text);
74 }
75 log_rotation_timer_.Start(FROM_HERE,
76 base::TimeDelta::FromSeconds(kLogIntervalSeconds),
77 this,
78 &RapporService::OnLogInterval);
79 }
80
81 // static
82 void RapporService::RegisterPrefs(PrefRegistrySimple* registry) {
83 registry->RegisterStringPref(prefs::kRapporSecret, std::string());
84 }
85
86 void RapporService::GetSecret(PrefService* pref_service) {
87 if (!secret_.empty())
88 return;
89 std::string secret_base64 =
90 pref_service->GetString(prefs::kRapporSecret);
91 if (!secret_base64.empty()) {
92 bool decoded = base::Base64Decode(secret_base64, &secret_);
93 if (decoded)
94 return;
95 // If the preference fails to decode, it must be corrupt, so continue as
96 // though it didn't exist yet and generate a new one.
97 }
98
99 secret_ = base::RandBytesAsString(128);
100 base::Base64Encode(secret_, &secret_base64);
101 pref_service->SetString(prefs::kRapporSecret, secret_base64);
102 }
103
104 void RapporService::LogMetric(const RapporMetric& metric,
105 RapporReports::Report* report) {
106 report->set_name_hash(base::Hash(metric.parameters()->rappor_name));
Alexei Svitkine (slow) 2014/01/24 22:09:03 I wouldn't use base::Hash() here - I think that on
Steven Holte 2014/01/24 23:26:58 Good catch! I thought I'd already had this set to
107 ByteVector bytes = metric.GetReport(secret_);
108 std::string byte_string(bytes.begin(), bytes.end());
109 report->set_bits(byte_string);
110 }
111
112 void RapporService::LogMetrics(RapporReports* reports) {
113 base::AutoLock auto_lock(lock_);
114
115 for (std::map<std::string, RapporMetric*>::iterator it = metrics_map_.begin();
116 metrics_map_.end() != it;
117 ++it) {
118 const RapporMetric* metric = it->second;
119 DCHECK_EQ(it->first, metric->parameters()->rappor_name);
120 RapporReports::Report* report = reports->add_report();
121 LogMetric(*metric, report);
122 }
123 STLDeleteContainerPairSecondPointers(
124 metrics_map_.begin(), metrics_map_.end());
125 metrics_map_.clear();
126 }
127
128 void RapporService::RecordSamples(const RapporParameters& parameters,
129 const std::vector<std::string>& samples) {
130 if (!GetServerUrl().is_valid())
131 return;
132 RecordSamplesInternal(parameters, samples);
133 }
134
135 void RapporService::RecordUrl(const RapporParameters& parameters,
136 const GURL& url) {
137 if (!GetServerUrl().is_valid())
138 return;
139 std::vector<std::string> samples;
140 samples.push_back(url.spec());
141 samples.push_back(url.host());
142 // TODO(holte): break up host more
143 samples.push_back(url.query());
144 samples.push_back(url.path());
145 RecordSamplesInternal(parameters, samples);
146 }
147
148 void RapporService::RecordSamplesInternal(
149 const RapporParameters& parameters,
150 const std::vector<std::string>& samples) {
151 base::AutoLock auto_lock(lock_);
152
153 RapporMetric* metric = LookupMetric(parameters);
154 metric->AddSamples(samples);
155 }
156
157 RapporMetric* RapporService::LookupMetric(
158 const RapporParameters& parameters) {
159 std::map<std::string, RapporMetric*>::iterator it =
160 metrics_map_.find(parameters.rappor_name);
161 if (metrics_map_.end() != it) {
162 RapporMetric* metric = it->second;
163 DCHECK_EQ(parameters.ToString(), metric->parameters()->ToString());
164 return metric;
165 }
166
167 RapporMetric* new_metric = new RapporMetric(parameters);
168 metrics_map_[parameters.rappor_name] = new_metric;
169 return new_metric;
170 }
171
172 } // namespace rappor
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698