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

Unified Diff: chrome/browser/performance_monitor/database.cc

Issue 10907121: Add guards to metric values; erase bad events/metrics from db (Closed) Base URL: http://git.chromium.org/chromium/src.git@dc_use_units
Patch Set: Yoz's requests 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 side-by-side diff with in-line comments
Download patch
Index: chrome/browser/performance_monitor/database.cc
diff --git a/chrome/browser/performance_monitor/database.cc b/chrome/browser/performance_monitor/database.cc
index 27108e319b010b9969c25573ba90bc199a644942..d8a61921a7bd51a1a3e005f16c7d9a39fc3b126c 100644
--- a/chrome/browser/performance_monitor/database.cc
+++ b/chrome/browser/performance_monitor/database.cc
@@ -18,6 +18,8 @@
#include "chrome/common/chrome_paths.h"
#include "content/public/browser/browser_thread.h"
#include "third_party/leveldatabase/src/include/leveldb/db.h"
+#include "third_party/leveldatabase/src/include/leveldb/iterator.h"
+#include "third_party/leveldatabase/src/include/leveldb/write_batch.h"
namespace performance_monitor {
namespace {
@@ -50,6 +52,17 @@ double StringToDouble(const std::string& s) {
return value;
}
+// Returns an event from the given JSON string; the scoped_ptr will be NULL if
+// we are unable to properly parse the JSON.
+scoped_ptr<Event> EventFromJSON(const std::string& data) {
+ Value* value = base::JSONReader::Read(data);
+ DictionaryValue* dict = NULL;
+ if (!value || !value->GetAsDictionary(&dict))
+ return scoped_ptr<Event>();
+
+ return Event::FromValue(scoped_ptr<DictionaryValue>(dict));
+}
+
} // namespace
const char Database::kDatabaseSequenceToken[] =
@@ -145,6 +158,7 @@ Database::EventVector Database::GetEvents(EventType type,
key_builder_->CreateEventKey(start, EVENT_UNDEFINED);
std::string end_key =
key_builder_->CreateEventKey(end, EVENT_NUMBER_OF_EVENTS);
+ leveldb::WriteBatch invalid_entries;
scoped_ptr<leveldb::Iterator> it(event_db_->NewIterator(read_options_));
for (it->Seek(start_key);
it->Valid() && it->key().ToString() <= end_key;
@@ -155,18 +169,16 @@ Database::EventVector Database::GetEvents(EventType type,
if (key_type != type)
continue;
}
- base::DictionaryValue* dict = NULL;
- if (!base::JSONReader::Read(
- it->value().ToString())->GetAsDictionary(&dict)) {
- LOG(ERROR) << "Unable to convert database event to JSON.";
+ scoped_ptr<Event> event = EventFromJSON(it->value().ToString());
+ if (!event.get()) {
+ invalid_entries.Delete(it->key());
+ LOG(ERROR) << "Found invalid event in the database. JSON: '" <<
Yoyo Zhou 2012/09/13 00:09:20 nit: put the << on the next line and align with <<
Devlin 2012/09/13 17:00:24 Done.
+ it->value().ToString() << "'. Erasing event from the database.";
continue;
}
- scoped_ptr<Event> event =
- Event::FromValue(scoped_ptr<base::DictionaryValue>(dict));
- if (!event.get())
- continue;
events.push_back(linked_ptr<Event>(event.release()));
}
+ event_db_->Write(write_options_, &invalid_entries);
return events;
}
@@ -190,28 +202,34 @@ Database::EventTypeSet Database::GetEventTypes(const base::Time& start,
}
bool Database::AddMetric(const std::string& activity,
- MetricType metric,
- const std::string& value) {
+ const Metric& metric) {
CHECK(!content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
+ if (!metric.IsValid()) {
+ LOG(ERROR) << "Metric to be added is invalid. Type: " << metric.type <<
+ ", Time: " << metric.time.ToInternalValue() <<
+ ", Value: " << metric.value << ". Ignoring.";
+ return false;
+ }
+
UpdateActiveInterval();
- base::Time timestamp = clock_->GetTime();
std::string recent_key =
- key_builder_->CreateRecentKey(timestamp, metric, activity);
+ key_builder_->CreateRecentKey(metric.time, metric.type, activity);
std::string metric_key =
- key_builder_->CreateMetricKey(timestamp, metric, activity);
+ key_builder_->CreateMetricKey(metric.time, metric.type, activity);
std::string recent_map_key =
- key_builder_->CreateRecentMapKey(metric, activity);
+ key_builder_->CreateRecentMapKey(metric.type, activity);
// Use recent_map_ to quickly find the key that must be removed.
RecentMap::iterator old_it = recent_map_.find(recent_map_key);
if (old_it != recent_map_.end())
recent_db_->Delete(write_options_, old_it->second);
recent_map_[recent_map_key] = recent_key;
leveldb::Status recent_status =
- recent_db_->Put(write_options_, recent_key, value);
+ recent_db_->Put(write_options_, recent_key, metric.ValueAsString());
leveldb::Status metric_status =
- metric_db_->Put(write_options_, metric_key, value);
+ metric_db_->Put(write_options_, metric_key, metric.ValueAsString());
- bool max_value_success = UpdateMaxValue(activity, metric, value);
+ bool max_value_success =
+ UpdateMaxValue(activity, metric.type, metric.ValueAsString());
return recent_status.ok() && metric_status.ok() && max_value_success;
}
@@ -321,7 +339,9 @@ bool Database::GetRecentStatsForActivityAndMetric(const std::string& activity,
std::string result;
leveldb::Status status = recent_db_->Get(read_options_, recent_key, &result);
if (status.ok())
- *metric = Metric(key_builder_->SplitRecentKey(recent_key).time, result);
+ *metric = Metric(metric_type,
+ key_builder_->SplitRecentKey(recent_key).time,
+ result);
return status.ok();
}
@@ -336,15 +356,26 @@ Database::MetricVector Database::GetStatsForActivityAndMetric(
key_builder_->CreateMetricKey(start, metric_type, activity);
std::string end_key =
key_builder_->CreateMetricKey(end, metric_type, activity);
+ leveldb::WriteBatch invalid_entries;
scoped_ptr<leveldb::Iterator> it(metric_db_->NewIterator(read_options_));
for (it->Seek(start_key);
it->Valid() && it->key().ToString() <= end_key;
it->Next()) {
MetricKey split_key =
key_builder_->SplitMetricKey(it->key().ToString());
- if (split_key.activity == activity)
- results.push_back(Metric(split_key.time, it->value().ToString()));
+ if (split_key.activity == activity) {
+ Metric metric(metric_type, split_key.time, it->value().ToString());
+ if (!metric.IsValid()) {
+ invalid_entries.Delete(it->key());
+ LOG(ERROR) << "Found bad metric in the database. Type: " <<
+ metric.type << ", Time: " << metric.time.ToInternalValue() <<
+ ", Value: " << metric.value << ". Erasing metric from database.";
+ continue;
+ }
+ results.push_back(metric);
+ }
}
+ metric_db_->Write(write_options_, &invalid_entries);
return results;
}
@@ -358,6 +389,7 @@ Database::MetricVectorMap Database::GetStatsForMetricByActivity(
key_builder_->CreateMetricKey(start, metric_type, std::string());
std::string end_key =
key_builder_->CreateMetricKey(end, metric_type, std::string());
+ leveldb::WriteBatch invalid_entries;
scoped_ptr<leveldb::Iterator> it(metric_db_->NewIterator(read_options_));
for (it->Seek(start_key);
it->Valid() && it->key().ToString() <= end_key;
@@ -367,9 +399,17 @@ Database::MetricVectorMap Database::GetStatsForMetricByActivity(
results[split_key.activity] =
linked_ptr<MetricVector >(new MetricVector());
}
- results[split_key.activity]->push_back(
- Metric(split_key.time, it->value().ToString()));
+ Metric metric(metric_type, split_key.time, it->value().ToString());
+ if (!metric.IsValid()) {
+ invalid_entries.Delete(it->key());
+ LOG(ERROR) << "Found bad metric in the database. Type: " <<
+ metric.type << ", Time: " << metric.time.ToInternalValue() <<
+ ", Value: " << metric.value << ". Erasing metric from database.";
+ continue;
+ }
+ results[split_key.activity]->push_back(metric);
}
+ metric_db_->Write(write_options_, &invalid_entries);
return results;
}
« 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