diff options
author | ttuttle@chromium.org <ttuttle@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-03-18 23:52:02 +0000 |
---|---|---|
committer | ttuttle@chromium.org <ttuttle@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-03-18 23:52:02 +0000 |
commit | 45de676a514b6e217b9dee01a02ca6acf45c91f7 (patch) | |
tree | 1f90f90658bf08b57c4b21070c672d8e55b360ce /components/domain_reliability/context.cc | |
parent | dfa5b95c3816f8416ac519f6bbab9e13237273a5 (diff) | |
download | chromium_src-45de676a514b6e217b9dee01a02ca6acf45c91f7.zip chromium_src-45de676a514b6e217b9dee01a02ca6acf45c91f7.tar.gz chromium_src-45de676a514b6e217b9dee01a02ca6acf45c91f7.tar.bz2 |
Domain Reliability / Navigation Error Logging, part 1
This is just the logging portion of Domain Reliability; the uploading
and configuration parts will come later.
BUG=
Review URL: https://codereview.chromium.org/132283009
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@257815 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'components/domain_reliability/context.cc')
-rw-r--r-- | components/domain_reliability/context.cc | 206 |
1 files changed, 206 insertions, 0 deletions
diff --git a/components/domain_reliability/context.cc b/components/domain_reliability/context.cc new file mode 100644 index 0000000..5a69689 --- /dev/null +++ b/components/domain_reliability/context.cc @@ -0,0 +1,206 @@ +// Copyright 2014 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/domain_reliability/context.h" + +#include <algorithm> + +#include "base/bind.h" +#include "base/json/json_writer.h" +#include "base/logging.h" +#include "base/values.h" +#include "net/url_request/url_request_context_getter.h" + +using base::DictionaryValue; +using base::ListValue; +using base::Value; + +namespace domain_reliability { + +namespace { +const char* kReporter = "chrome"; +typedef std::deque<DomainReliabilityBeacon> BeaconDeque; +typedef BeaconDeque::iterator BeaconIterator; +typedef BeaconDeque::const_iterator BeaconConstIterator; +} // namespace + +const int DomainReliabilityContext::kMaxQueuedBeacons = 150; + +DomainReliabilityContext::DomainReliabilityContext( + MockableTime* time, + scoped_ptr<const DomainReliabilityConfig> config) + : config_(config.Pass()), + time_(time), + beacon_count_(0), + weak_factory_(this) { + InitializeResourceStates(); +} + +DomainReliabilityContext::~DomainReliabilityContext() {} + +void DomainReliabilityContext::AddBeacon( + const DomainReliabilityBeacon& beacon, + const GURL& url) { + int index = config_->GetResourceIndexForUrl(url); + if (index < 0) + return; + DCHECK_GT(states_.size(), static_cast<size_t>(index)); + + ResourceState* state = states_[index]; + bool success = beacon.http_response_code >= 200 && + beacon.http_response_code < 400; + if (success) + ++state->successful_requests; + else + ++state->failed_requests; + + VLOG(1) << "Received Beacon: " + << state->config->name << " " + << beacon.status << " " + << beacon.chrome_error << " " + << beacon.http_response_code << " " + << beacon.server_ip << " " + << beacon.elapsed.InMilliseconds() << "ms"; + + if (state->config->DecideIfShouldReportRequest(success)) { + state->beacons.push_back(beacon); + ++beacon_count_; + if (beacon_count_ > kMaxQueuedBeacons) + RemoveOldestBeacon(); + } +} + +void DomainReliabilityContext::GetQueuedDataForTesting( + int resource_index, + std::vector<DomainReliabilityBeacon>* beacons_out, + int* successful_requests_out, + int* failed_requests_out) const { + DCHECK_LE(0, resource_index); + DCHECK_GT(static_cast<int>(states_.size()), resource_index); + const ResourceState& state = *states_[resource_index]; + if (beacons_out) { + beacons_out->resize(state.beacons.size()); + std::copy(state.beacons.begin(), state.beacons.end(), beacons_out->begin()); + } + if (successful_requests_out) + *successful_requests_out = state.successful_requests; + if (failed_requests_out) + *failed_requests_out = state.failed_requests; +} + +DomainReliabilityContext::ResourceState::ResourceState( + DomainReliabilityContext* context, + const DomainReliabilityConfig::Resource* config) + : context(context), + config(config), + successful_requests(0), + failed_requests(0) {} + +DomainReliabilityContext::ResourceState::~ResourceState() {} + +scoped_ptr<Value> DomainReliabilityContext::ResourceState::ToValue( + base::TimeTicks upload_time) const { + ListValue* beacons_value = new ListValue(); + for (BeaconConstIterator it = beacons.begin(); it != beacons.end(); ++it) + beacons_value->Append(it->ToValue(upload_time)); + + DictionaryValue* resource_value = new DictionaryValue(); + resource_value->SetString("resource_name", config->name); + resource_value->SetInteger("successful_requests", successful_requests); + resource_value->SetInteger("failed_requests", failed_requests); + resource_value->Set("beacons", beacons_value); + + return scoped_ptr<Value>(resource_value); +} + +void DomainReliabilityContext::ResourceState::MarkUpload() { + uploading_beacons_size = beacons.size(); + uploading_successful_requests = successful_requests; + uploading_failed_requests = failed_requests; +} + +void DomainReliabilityContext::ResourceState::CommitUpload() { + BeaconIterator begin = beacons.begin(); + BeaconIterator end = begin + uploading_beacons_size; + beacons.erase(begin, end); + successful_requests -= uploading_successful_requests; + failed_requests -= uploading_failed_requests; +} + +bool DomainReliabilityContext::ResourceState::GetOldestBeaconStart( + base::TimeTicks* oldest_start_out) const { + if (beacons.empty()) + return false; + + *oldest_start_out = beacons[0].start_time; + return true; +} + +void DomainReliabilityContext::ResourceState::RemoveOldestBeacon() { + DCHECK(!beacons.empty()); + beacons.erase(beacons.begin()); + // If that just removed a beacon counted in uploading_beacons_size, decrement + // that. + if (uploading_beacons_size > 0) + --uploading_beacons_size; +} + +void DomainReliabilityContext::InitializeResourceStates() { + ScopedVector<DomainReliabilityConfig::Resource>::const_iterator it; + for (it = config_->resources.begin(); it != config_->resources.end(); ++it) + states_.push_back(new ResourceState(this, *it)); +} + +scoped_ptr<const Value> DomainReliabilityContext::CreateReport( + base::TimeTicks upload_time) const { + ListValue* resources_value = new ListValue(); + for (ResourceStateIterator it = states_.begin(); it != states_.end(); ++it) + resources_value->Append((*it)->ToValue(upload_time).release()); + + DictionaryValue* report_value = new DictionaryValue(); + report_value->SetString("reporter", kReporter); + report_value->Set("resource_reports", resources_value); + + return scoped_ptr<const Value>(report_value); +} + +void DomainReliabilityContext::MarkUpload() { + for (ResourceStateIterator it = states_.begin(); it != states_.end(); ++it) + (*it)->MarkUpload(); + uploading_beacon_count_ = beacon_count_; +} + +void DomainReliabilityContext::CommitUpload() { + for (ResourceStateIterator it = states_.begin(); it != states_.end(); ++it) + (*it)->CommitUpload(); + beacon_count_ -= uploading_beacon_count_; +} + +void DomainReliabilityContext::RemoveOldestBeacon() { + DCHECK_LT(0, beacon_count_); + + base::TimeTicks min_time; + ResourceState* min_resource = NULL; + for (ResourceStateIterator it = states_.begin(); it != states_.end(); ++it) { + base::TimeTicks oldest; + if ((*it)->GetOldestBeaconStart(&oldest)) { + if (!min_resource || oldest < min_time) { + min_time = oldest; + min_resource = *it; + } + } + } + DCHECK(min_resource); + + VLOG(1) << "Removing oldest beacon from " << min_resource->config->name; + + min_resource->RemoveOldestBeacon(); + --beacon_count_; + // If that just removed a beacon counted in uploading_beacon_count_, decrement + // that. + if (uploading_beacon_count_ > 0) + --uploading_beacon_count_; +} + +} // namespace domain_reliability |