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

Side by Side Diff: chrome/browser/performance_monitor/database.cc

Issue 10915318: Revert 157168 - Add guards to metric values; erase bad events/metrics from db (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: Created 8 years, 3 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 | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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 "chrome/browser/performance_monitor/database.h" 5 #include "chrome/browser/performance_monitor/database.h"
6 6
7 #include "base/file_path.h" 7 #include "base/file_path.h"
8 #include "base/file_util.h" 8 #include "base/file_util.h"
9 #include "base/json/json_reader.h" 9 #include "base/json/json_reader.h"
10 #include "base/json/json_writer.h" 10 #include "base/json/json_writer.h"
11 #include "base/logging.h" 11 #include "base/logging.h"
12 #include "base/path_service.h" 12 #include "base/path_service.h"
13 #include "base/stl_util.h" 13 #include "base/stl_util.h"
14 #include "base/string_number_conversions.h" 14 #include "base/string_number_conversions.h"
15 #include "base/time.h" 15 #include "base/time.h"
16 #include "base/utf_string_conversions.h" 16 #include "base/utf_string_conversions.h"
17 #include "chrome/browser/performance_monitor/key_builder.h" 17 #include "chrome/browser/performance_monitor/key_builder.h"
18 #include "chrome/common/chrome_paths.h" 18 #include "chrome/common/chrome_paths.h"
19 #include "content/public/browser/browser_thread.h" 19 #include "content/public/browser/browser_thread.h"
20 #include "third_party/leveldatabase/src/include/leveldb/db.h" 20 #include "third_party/leveldatabase/src/include/leveldb/db.h"
21 #include "third_party/leveldatabase/src/include/leveldb/iterator.h"
22 #include "third_party/leveldatabase/src/include/leveldb/write_batch.h"
23 21
24 namespace performance_monitor { 22 namespace performance_monitor {
25 namespace { 23 namespace {
26 const char kDbDir[] = "Performance Monitor Databases"; 24 const char kDbDir[] = "Performance Monitor Databases";
27 const char kRecentDb[] = "Recent Metrics"; 25 const char kRecentDb[] = "Recent Metrics";
28 const char kMaxValueDb[] = "Max Value Metrics"; 26 const char kMaxValueDb[] = "Max Value Metrics";
29 const char kEventDb[] = "Events"; 27 const char kEventDb[] = "Events";
30 const char kStateDb[] = "Configuration"; 28 const char kStateDb[] = "Configuration";
31 const char kActiveIntervalDb[] = "Active Interval"; 29 const char kActiveIntervalDb[] = "Active Interval";
32 const char kMetricDb[] = "Metrics"; 30 const char kMetricDb[] = "Metrics";
(...skipping 12 matching lines...) Expand all
45 base::Time::FromInternalValue(end_time_int)); 43 base::Time::FromInternalValue(end_time_int));
46 } 44 }
47 45
48 double StringToDouble(const std::string& s) { 46 double StringToDouble(const std::string& s) {
49 double value = 0.0; 47 double value = 0.0;
50 if (!base::StringToDouble(s, &value)) 48 if (!base::StringToDouble(s, &value))
51 LOG(ERROR) << "Failed to convert " << s << " to double."; 49 LOG(ERROR) << "Failed to convert " << s << " to double.";
52 return value; 50 return value;
53 } 51 }
54 52
55 // Returns an event from the given JSON string; the scoped_ptr will be NULL if
56 // we are unable to properly parse the JSON.
57 scoped_ptr<Event> EventFromJSON(const std::string& data) {
58 Value* value = base::JSONReader::Read(data);
59 DictionaryValue* dict = NULL;
60 if (!value || !value->GetAsDictionary(&dict))
61 return scoped_ptr<Event>();
62
63 return Event::FromValue(scoped_ptr<DictionaryValue>(dict));
64 }
65
66 } // namespace 53 } // namespace
67 54
68 const char Database::kDatabaseSequenceToken[] = 55 const char Database::kDatabaseSequenceToken[] =
69 "_performance_monitor_db_sequence_token_"; 56 "_performance_monitor_db_sequence_token_";
70 57
71 TimeRange::TimeRange() { 58 TimeRange::TimeRange() {
72 } 59 }
73 60
74 TimeRange::TimeRange(base::Time start_time, base::Time end_time) 61 TimeRange::TimeRange(base::Time start_time, base::Time end_time)
75 : start(start_time), 62 : start(start_time),
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
151 138
152 Database::EventVector Database::GetEvents(EventType type, 139 Database::EventVector Database::GetEvents(EventType type,
153 const base::Time& start, 140 const base::Time& start,
154 const base::Time& end) { 141 const base::Time& end) {
155 CHECK(!content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); 142 CHECK(!content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
156 EventVector events; 143 EventVector events;
157 std::string start_key = 144 std::string start_key =
158 key_builder_->CreateEventKey(start, EVENT_UNDEFINED); 145 key_builder_->CreateEventKey(start, EVENT_UNDEFINED);
159 std::string end_key = 146 std::string end_key =
160 key_builder_->CreateEventKey(end, EVENT_NUMBER_OF_EVENTS); 147 key_builder_->CreateEventKey(end, EVENT_NUMBER_OF_EVENTS);
161 leveldb::WriteBatch invalid_entries;
162 scoped_ptr<leveldb::Iterator> it(event_db_->NewIterator(read_options_)); 148 scoped_ptr<leveldb::Iterator> it(event_db_->NewIterator(read_options_));
163 for (it->Seek(start_key); 149 for (it->Seek(start_key);
164 it->Valid() && it->key().ToString() <= end_key; 150 it->Valid() && it->key().ToString() <= end_key;
165 it->Next()) { 151 it->Next()) {
166 if (type != EVENT_UNDEFINED) { 152 if (type != EVENT_UNDEFINED) {
167 EventType key_type = 153 EventType key_type =
168 key_builder_->EventKeyToEventType(it->key().ToString()); 154 key_builder_->EventKeyToEventType(it->key().ToString());
169 if (key_type != type) 155 if (key_type != type)
170 continue; 156 continue;
171 } 157 }
172 scoped_ptr<Event> event = EventFromJSON(it->value().ToString()); 158 base::DictionaryValue* dict = NULL;
173 if (!event.get()) { 159 if (!base::JSONReader::Read(
174 invalid_entries.Delete(it->key()); 160 it->value().ToString())->GetAsDictionary(&dict)) {
175 LOG(ERROR) << "Found invalid event in the database. JSON: '" 161 LOG(ERROR) << "Unable to convert database event to JSON.";
176 << it->value().ToString()
177 << "'. Erasing event from the database.";
178 continue; 162 continue;
179 } 163 }
164 scoped_ptr<Event> event =
165 Event::FromValue(scoped_ptr<base::DictionaryValue>(dict));
166 if (!event.get())
167 continue;
180 events.push_back(linked_ptr<Event>(event.release())); 168 events.push_back(linked_ptr<Event>(event.release()));
181 } 169 }
182 event_db_->Write(write_options_, &invalid_entries);
183 return events; 170 return events;
184 } 171 }
185 172
186 Database::EventTypeSet Database::GetEventTypes(const base::Time& start, 173 Database::EventTypeSet Database::GetEventTypes(const base::Time& start,
187 const base::Time& end) { 174 const base::Time& end) {
188 CHECK(!content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); 175 CHECK(!content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
189 EventTypeSet results; 176 EventTypeSet results;
190 std::string start_key = 177 std::string start_key =
191 key_builder_->CreateEventKey(start, EVENT_UNDEFINED); 178 key_builder_->CreateEventKey(start, EVENT_UNDEFINED);
192 std::string end_key = 179 std::string end_key =
193 key_builder_->CreateEventKey(end, EVENT_NUMBER_OF_EVENTS); 180 key_builder_->CreateEventKey(end, EVENT_NUMBER_OF_EVENTS);
194 scoped_ptr<leveldb::Iterator> it(event_db_->NewIterator(read_options_)); 181 scoped_ptr<leveldb::Iterator> it(event_db_->NewIterator(read_options_));
195 for (it->Seek(start_key); 182 for (it->Seek(start_key);
196 it->Valid() && it->key().ToString() <= end_key; 183 it->Valid() && it->key().ToString() <= end_key;
197 it->Next()) { 184 it->Next()) {
198 EventType key_type = 185 EventType key_type =
199 key_builder_->EventKeyToEventType(it->key().ToString()); 186 key_builder_->EventKeyToEventType(it->key().ToString());
200 results.insert(key_type); 187 results.insert(key_type);
201 } 188 }
202 return results; 189 return results;
203 } 190 }
204 191
205 bool Database::AddMetric(const std::string& activity, 192 bool Database::AddMetric(const std::string& activity,
206 const Metric& metric) { 193 MetricType metric,
194 const std::string& value) {
207 CHECK(!content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); 195 CHECK(!content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
208 if (!metric.IsValid()) {
209 LOG(ERROR) << "Metric to be added is invalid. Type: " << metric.type
210 << ", Time: " << metric.time.ToInternalValue()
211 << ", Value: " << metric.value << ". Ignoring.";
212 return false;
213 }
214
215 UpdateActiveInterval(); 196 UpdateActiveInterval();
197 base::Time timestamp = clock_->GetTime();
216 std::string recent_key = 198 std::string recent_key =
217 key_builder_->CreateRecentKey(metric.time, metric.type, activity); 199 key_builder_->CreateRecentKey(timestamp, metric, activity);
218 std::string metric_key = 200 std::string metric_key =
219 key_builder_->CreateMetricKey(metric.time, metric.type, activity); 201 key_builder_->CreateMetricKey(timestamp, metric, activity);
220 std::string recent_map_key = 202 std::string recent_map_key =
221 key_builder_->CreateRecentMapKey(metric.type, activity); 203 key_builder_->CreateRecentMapKey(metric, activity);
222 // Use recent_map_ to quickly find the key that must be removed. 204 // Use recent_map_ to quickly find the key that must be removed.
223 RecentMap::iterator old_it = recent_map_.find(recent_map_key); 205 RecentMap::iterator old_it = recent_map_.find(recent_map_key);
224 if (old_it != recent_map_.end()) 206 if (old_it != recent_map_.end())
225 recent_db_->Delete(write_options_, old_it->second); 207 recent_db_->Delete(write_options_, old_it->second);
226 recent_map_[recent_map_key] = recent_key; 208 recent_map_[recent_map_key] = recent_key;
227 leveldb::Status recent_status = 209 leveldb::Status recent_status =
228 recent_db_->Put(write_options_, recent_key, metric.ValueAsString()); 210 recent_db_->Put(write_options_, recent_key, value);
229 leveldb::Status metric_status = 211 leveldb::Status metric_status =
230 metric_db_->Put(write_options_, metric_key, metric.ValueAsString()); 212 metric_db_->Put(write_options_, metric_key, value);
231 213
232 bool max_value_success = 214 bool max_value_success = UpdateMaxValue(activity, metric, value);
233 UpdateMaxValue(activity, metric.type, metric.ValueAsString());
234 return recent_status.ok() && metric_status.ok() && max_value_success; 215 return recent_status.ok() && metric_status.ok() && max_value_success;
235 } 216 }
236 217
237 bool Database::UpdateMaxValue(const std::string& activity, 218 bool Database::UpdateMaxValue(const std::string& activity,
238 MetricType metric, 219 MetricType metric,
239 const std::string& value) { 220 const std::string& value) {
240 std::string max_value_key( 221 std::string max_value_key(
241 key_builder_->CreateMaxValueKey(metric, activity)); 222 key_builder_->CreateMaxValueKey(metric, activity));
242 bool has_key = ContainsKey(max_value_map_, max_value_key); 223 bool has_key = ContainsKey(max_value_map_, max_value_key);
243 if ((has_key && StringToDouble(value) > max_value_map_[max_value_key]) || 224 if ((has_key && StringToDouble(value) > max_value_map_[max_value_key]) ||
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after
333 CHECK(!content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); 314 CHECK(!content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
334 std::string recent_map_key = 315 std::string recent_map_key =
335 key_builder_->CreateRecentMapKey(metric_type, activity); 316 key_builder_->CreateRecentMapKey(metric_type, activity);
336 if (!ContainsKey(recent_map_, recent_map_key)) 317 if (!ContainsKey(recent_map_, recent_map_key))
337 return false; 318 return false;
338 std::string recent_key = recent_map_[recent_map_key]; 319 std::string recent_key = recent_map_[recent_map_key];
339 320
340 std::string result; 321 std::string result;
341 leveldb::Status status = recent_db_->Get(read_options_, recent_key, &result); 322 leveldb::Status status = recent_db_->Get(read_options_, recent_key, &result);
342 if (status.ok()) 323 if (status.ok())
343 *metric = Metric(metric_type, 324 *metric = Metric(key_builder_->SplitRecentKey(recent_key).time, result);
344 key_builder_->SplitRecentKey(recent_key).time,
345 result);
346 return status.ok(); 325 return status.ok();
347 } 326 }
348 327
349 Database::MetricVector Database::GetStatsForActivityAndMetric( 328 Database::MetricVector Database::GetStatsForActivityAndMetric(
350 const std::string& activity, 329 const std::string& activity,
351 MetricType metric_type, 330 MetricType metric_type,
352 const base::Time& start, 331 const base::Time& start,
353 const base::Time& end) { 332 const base::Time& end) {
354 CHECK(!content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); 333 CHECK(!content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
355 MetricVector results; 334 MetricVector results;
356 std::string start_key = 335 std::string start_key =
357 key_builder_->CreateMetricKey(start, metric_type, activity); 336 key_builder_->CreateMetricKey(start, metric_type, activity);
358 std::string end_key = 337 std::string end_key =
359 key_builder_->CreateMetricKey(end, metric_type, activity); 338 key_builder_->CreateMetricKey(end, metric_type, activity);
360 leveldb::WriteBatch invalid_entries;
361 scoped_ptr<leveldb::Iterator> it(metric_db_->NewIterator(read_options_)); 339 scoped_ptr<leveldb::Iterator> it(metric_db_->NewIterator(read_options_));
362 for (it->Seek(start_key); 340 for (it->Seek(start_key);
363 it->Valid() && it->key().ToString() <= end_key; 341 it->Valid() && it->key().ToString() <= end_key;
364 it->Next()) { 342 it->Next()) {
365 MetricKey split_key = 343 MetricKey split_key =
366 key_builder_->SplitMetricKey(it->key().ToString()); 344 key_builder_->SplitMetricKey(it->key().ToString());
367 if (split_key.activity == activity) { 345 if (split_key.activity == activity)
368 Metric metric(metric_type, split_key.time, it->value().ToString()); 346 results.push_back(Metric(split_key.time, it->value().ToString()));
369 if (!metric.IsValid()) {
370 invalid_entries.Delete(it->key());
371 LOG(ERROR) << "Found bad metric in the database. Type: "
372 << metric.type << ", Time: " << metric.time.ToInternalValue()
373 << ", Value: " << metric.value
374 << ". Erasing metric from database.";
375 continue;
376 }
377 results.push_back(metric);
378 }
379 } 347 }
380 metric_db_->Write(write_options_, &invalid_entries);
381 return results; 348 return results;
382 } 349 }
383 350
384 Database::MetricVectorMap Database::GetStatsForMetricByActivity( 351 Database::MetricVectorMap Database::GetStatsForMetricByActivity(
385 MetricType metric_type, 352 MetricType metric_type,
386 const base::Time& start, 353 const base::Time& start,
387 const base::Time& end) { 354 const base::Time& end) {
388 CHECK(!content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); 355 CHECK(!content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
389 MetricVectorMap results; 356 MetricVectorMap results;
390 std::string start_key = 357 std::string start_key =
391 key_builder_->CreateMetricKey(start, metric_type, std::string()); 358 key_builder_->CreateMetricKey(start, metric_type, std::string());
392 std::string end_key = 359 std::string end_key =
393 key_builder_->CreateMetricKey(end, metric_type, std::string()); 360 key_builder_->CreateMetricKey(end, metric_type, std::string());
394 leveldb::WriteBatch invalid_entries;
395 scoped_ptr<leveldb::Iterator> it(metric_db_->NewIterator(read_options_)); 361 scoped_ptr<leveldb::Iterator> it(metric_db_->NewIterator(read_options_));
396 for (it->Seek(start_key); 362 for (it->Seek(start_key);
397 it->Valid() && it->key().ToString() <= end_key; 363 it->Valid() && it->key().ToString() <= end_key;
398 it->Next()) { 364 it->Next()) {
399 MetricKey split_key = key_builder_->SplitMetricKey(it->key().ToString()); 365 MetricKey split_key = key_builder_->SplitMetricKey(it->key().ToString());
400 if (!results[split_key.activity].get()) { 366 if (!results[split_key.activity].get()) {
401 results[split_key.activity] = 367 results[split_key.activity] =
402 linked_ptr<MetricVector >(new MetricVector()); 368 linked_ptr<MetricVector >(new MetricVector());
403 } 369 }
404 Metric metric(metric_type, split_key.time, it->value().ToString()); 370 results[split_key.activity]->push_back(
405 if (!metric.IsValid()) { 371 Metric(split_key.time, it->value().ToString()));
406 invalid_entries.Delete(it->key());
407 LOG(ERROR) << "Found bad metric in the database. Type: "
408 << metric.type << ", Time: " << metric.time.ToInternalValue()
409 << ", Value: " << metric.value
410 << ". Erasing metric from database.";
411 continue;
412 }
413 results[split_key.activity]->push_back(metric);
414 } 372 }
415 metric_db_->Write(write_options_, &invalid_entries);
416 return results; 373 return results;
417 } 374 }
418 375
419 Database::Database(const FilePath& path) 376 Database::Database(const FilePath& path)
420 : key_builder_(new KeyBuilder()), 377 : key_builder_(new KeyBuilder()),
421 path_(path), 378 path_(path),
422 read_options_(leveldb::ReadOptions()), 379 read_options_(leveldb::ReadOptions()),
423 write_options_(leveldb::WriteOptions()) { 380 write_options_(leveldb::WriteOptions()) {
424 InitDBs(); 381 InitDBs();
425 LoadRecents(); 382 LoadRecents();
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after
525 start_time_key_ = key_builder_->CreateActiveIntervalKey(current_time); 482 start_time_key_ = key_builder_->CreateActiveIntervalKey(current_time);
526 end_time = start_time_key_; 483 end_time = start_time_key_;
527 } else { 484 } else {
528 end_time = key_builder_->CreateActiveIntervalKey(clock_->GetTime()); 485 end_time = key_builder_->CreateActiveIntervalKey(clock_->GetTime());
529 } 486 }
530 last_update_time_ = current_time; 487 last_update_time_ = current_time;
531 active_interval_db_->Put(write_options_, start_time_key_, end_time); 488 active_interval_db_->Put(write_options_, start_time_key_, end_time);
532 } 489 }
533 490
534 } // namespace performance_monitor 491 } // namespace performance_monitor
OLDNEW
« no previous file with comments | « chrome/browser/performance_monitor/database.h ('k') | chrome/browser/performance_monitor/database_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698