blob: 0cf60f0c24fa905498734472b5cff1497fa85342 [file] [log] [blame]
/*
* Copyright 2012 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
// Author: morlovich@google.com (Maksim Orlovich)
#include "net/instaweb/http/public/url_async_fetcher_stats.h"
#include "base/logging.h"
#include "net/instaweb/http/public/async_fetch.h"
#include "pagespeed/kernel/base/statistics.h"
#include "pagespeed/kernel/base/string.h"
#include "pagespeed/kernel/base/string_util.h"
#include "pagespeed/kernel/base/timer.h"
#include "pagespeed/kernel/http/response_headers.h"
namespace {
const int kFetchLatencyUsHistogramMaxValue = 500 * 1000;
const char kFetchLatencyUsHistogram[] = "_fetch_latency_us";
const char kFetches[] = "_fetches";
const char kBytesFetched[] = "_bytes_fetched";
const char kApproxHeaderBytesFetched[] = "_approx_header_bytes_fetched";
} // namespace
namespace net_instaweb {
class UrlAsyncFetcherStats::StatsAsyncFetch : public SharedAsyncFetch {
public:
StatsAsyncFetch(UrlAsyncFetcherStats* stats_fetcher,
AsyncFetch* base_fetch)
: SharedAsyncFetch(base_fetch),
stats_fetcher_(stats_fetcher),
size_(0) {
start_time_us_ = stats_fetcher_->timer_->NowUs();
}
virtual ~StatsAsyncFetch() {
}
virtual void HandleHeadersComplete() {
stats_fetcher_->approx_header_bytes_fetched_->Add(
response_headers()->SizeEstimate());
SharedAsyncFetch::HandleHeadersComplete();
}
virtual void HandleDone(bool success) {
int64 end_time_us = stats_fetcher_->timer_->NowUs();
stats_fetcher_->fetch_latency_us_histogram_->Add(
end_time_us - start_time_us_);
stats_fetcher_->fetches_->Add(1);
stats_fetcher_->bytes_fetched_->Add(size_);
SharedAsyncFetch::HandleDone(success);
delete this;
}
virtual bool HandleWrite(const StringPiece& content,
MessageHandler* handler) {
size_ += content.size();
return SharedAsyncFetch::HandleWrite(content, handler);
}
private:
UrlAsyncFetcherStats* stats_fetcher_;
int64 start_time_us_;
int64 size_;
DISALLOW_COPY_AND_ASSIGN(StatsAsyncFetch);
};
UrlAsyncFetcherStats::UrlAsyncFetcherStats(StringPiece prefix,
UrlAsyncFetcher* base_fetcher,
Timer* timer,
Statistics* statistics)
: base_fetcher_(base_fetcher),
timer_(timer),
fetch_latency_us_histogram_(statistics->GetHistogram(
StrCat(prefix, kFetchLatencyUsHistogram))),
fetches_(statistics->GetVariable(StrCat(prefix, kFetches))),
bytes_fetched_(statistics->GetVariable(StrCat(prefix, kBytesFetched))),
approx_header_bytes_fetched_(
statistics->GetVariable(StrCat(prefix, kApproxHeaderBytesFetched))) {
fetch_latency_us_histogram_->SetMaxValue(kFetchLatencyUsHistogramMaxValue);
DCHECK(!base_fetcher->fetch_with_gzip())
<< "A fetcher wrapped by UrlAsyncFetcherStats should not be handling "
<< "gzip itself, but rather letting UrlAsyncFetcherStats handle it";
}
UrlAsyncFetcherStats::~UrlAsyncFetcherStats() {
}
void UrlAsyncFetcherStats::InitStats(StringPiece prefix,
Statistics* statistics) {
Histogram* fetch_latency_us_histogram =
statistics->AddHistogram(StrCat(prefix, kFetchLatencyUsHistogram));
fetch_latency_us_histogram->SetMaxValue(kFetchLatencyUsHistogramMaxValue);
statistics->AddVariable(StrCat(prefix, kFetches));
statistics->AddVariable(StrCat(prefix, kBytesFetched));
statistics->AddVariable(StrCat(prefix, kApproxHeaderBytesFetched));
}
bool UrlAsyncFetcherStats::SupportsHttps() const {
return base_fetcher_->SupportsHttps();
}
void UrlAsyncFetcherStats::Fetch(const GoogleString& url,
MessageHandler* message_handler,
AsyncFetch* fetch) {
fetch = EnableInflation(fetch);
base_fetcher_->Fetch(url, message_handler, new StatsAsyncFetch(this, fetch));
}
int64 UrlAsyncFetcherStats::timeout_ms() {
return base_fetcher_->timeout_ms();
}
void UrlAsyncFetcherStats::ShutDown() {
base_fetcher_->ShutDown();
}
} // namespace net_instaweb