diff --git a/netwerk/protocol/http/SpdySession.cpp b/netwerk/protocol/http/SpdySession.cpp index 958b527c2ca1..58e777eebe3e 100644 --- a/netwerk/protocol/http/SpdySession.cpp +++ b/netwerk/protocol/http/SpdySession.cpp @@ -136,7 +136,7 @@ SpdySession::~SpdySession() mStreamTransactionHash.Enumerate(Shutdown, this); Telemetry::Accumulate(Telemetry::SPDY_PARALLEL_STREAMS, mConcurrentHighWater); - Telemetry::Accumulate(Telemetry::SPDY_TOTAL_STREAMS, (mNextStreamID - 1) / 2); + Telemetry::Accumulate(Telemetry::SPDY_REQUEST_PER_CONN, (mNextStreamID - 1) / 2); Telemetry::Accumulate(Telemetry::SPDY_SERVER_INITIATED_STREAMS, mServerPushedResources); } @@ -1805,6 +1805,12 @@ SpdySession::RequestHead() return NULL; } +PRUint32 +SpdySession::Http1xTransactionCount() +{ + return 0; +} + //----------------------------------------------------------------------------- // Pass through methods of nsAHttpConnection //----------------------------------------------------------------------------- diff --git a/netwerk/protocol/http/nsAHttpTransaction.h b/netwerk/protocol/http/nsAHttpTransaction.h index cc9bcfc5f980..fa5f3ab5b156 100644 --- a/netwerk/protocol/http/nsAHttpTransaction.h +++ b/netwerk/protocol/http/nsAHttpTransaction.h @@ -96,6 +96,11 @@ public: // called to retrieve the request headers of the transaction virtual nsHttpRequestHead *RequestHead() = 0; + + // determine the number of real http/1.x transactions on this + // abstract object. Pipelines may have multiple, SPDY has 0, + // normal http transactions have 1. + virtual PRUint32 Http1xTransactionCount() = 0; }; #define NS_DECL_NSAHTTPTRANSACTION \ @@ -112,7 +117,8 @@ public: nsresult WriteSegments(nsAHttpSegmentWriter *, PRUint32, PRUint32 *); \ void Close(nsresult reason); \ void SetSSLConnectFailed(); \ - nsHttpRequestHead *RequestHead(); + nsHttpRequestHead *RequestHead(); \ + PRUint32 Http1xTransactionCount(); //----------------------------------------------------------------------------- // nsAHttpSegmentReader diff --git a/netwerk/protocol/http/nsHttpConnection.cpp b/netwerk/protocol/http/nsHttpConnection.cpp index 03e728afe9ef..d5e7aa1c5399 100644 --- a/netwerk/protocol/http/nsHttpConnection.cpp +++ b/netwerk/protocol/http/nsHttpConnection.cpp @@ -78,6 +78,7 @@ nsHttpConnection::nsHttpConnection() , mConsiderReusedAfterEpoch(0) , mCurrentBytesRead(0) , mMaxBytesRead(0) + , mTotalBytesRead(0) , mKeepAlive(true) // assume to keep-alive by default , mKeepAliveMask(true) , mSupportsPipelining(false) // assume low-grade server @@ -85,11 +86,13 @@ nsHttpConnection::nsHttpConnection() , mCompletedProxyConnect(false) , mLastTransactionExpectedNoContent(false) , mIdleMonitoring(false) + , mHttp1xTransactionCount(0) , mNPNComplete(false) , mSetupNPNCalled(false) , mUsingSpdy(false) , mPriority(nsISupportsPriority::PRIORITY_NORMAL) , mReportedSpdy(false) + , mEverUsedSpdy(false) { LOG(("Creating nsHttpConnection @%x\n", this)); @@ -111,6 +114,24 @@ nsHttpConnection::~nsHttpConnection() // release our reference to the handler nsHttpHandler *handler = gHttpHandler; NS_RELEASE(handler); + + if (!mEverUsedSpdy) { + LOG(("nsHttpConnection %p performed %d HTTP/1.x transactions\n", + this, mHttp1xTransactionCount)); + mozilla::Telemetry::Accumulate( + mozilla::Telemetry::HTTP_REQUEST_PER_CONN, mHttp1xTransactionCount); + } + + if (mTotalBytesRead) { + PRUint32 totalKBRead = static_cast(mTotalBytesRead >> 10); + LOG(("nsHttpConnection %p read %dkb on connection spdy=%d\n", + this, totalKBRead, mEverUsedSpdy)); + mozilla::Telemetry::Accumulate( + mEverUsedSpdy ? + mozilla::Telemetry::SPDY_KBREAD_PER_CONN : + mozilla::Telemetry::HTTP_KBREAD_PER_CONN, + totalKBRead); + } } nsresult @@ -197,8 +218,8 @@ nsHttpConnection::EnsureNPNComplete() this, negotiatedNPN.get())); if (negotiatedNPN.Equals(NS_LITERAL_CSTRING("spdy/2"))) { - mUsingSpdy = true; + mEverUsedSpdy = true; mIsReused = true; /* all spdy streams are reused */ // Wrap the old http transaction into the new spdy session @@ -851,10 +872,13 @@ nsHttpConnection::CloseTransaction(nsAHttpTransaction *trans, nsresult reason) if (mUsingSpdy) { DontReuse(); + // if !mSpdySession then mUsingSpdy must be false for canreuse() mUsingSpdy = false; mSpdySession = nsnull; } + mHttp1xTransactionCount += mTransaction->Http1xTransactionCount(); + mTransaction->Close(reason); mTransaction = nsnull; @@ -1056,6 +1080,7 @@ nsHttpConnection::OnSocketReadable() } else { mCurrentBytesRead += n; + mTotalBytesRead += n; if (NS_FAILED(mSocketInCondition)) { // continue waiting for the socket if necessary... if (mSocketInCondition == NS_BASE_STREAM_WOULD_BLOCK) diff --git a/netwerk/protocol/http/nsHttpConnection.h b/netwerk/protocol/http/nsHttpConnection.h index e9ed2d8c43f8..a16de8c34f9b 100644 --- a/netwerk/protocol/http/nsHttpConnection.h +++ b/netwerk/protocol/http/nsHttpConnection.h @@ -210,6 +210,7 @@ private: PRIntervalTime mConsiderReusedAfterEpoch; PRInt64 mCurrentBytesRead; // data read per activation PRInt64 mMaxBytesRead; // max read in 1 activation + PRInt64 mTotalBytesRead; // total data read nsRefPtr mInputOverflow; @@ -221,6 +222,10 @@ private: bool mLastTransactionExpectedNoContent; bool mIdleMonitoring; + // The number of <= HTTP/1.1 transactions performed on this connection. This + // excludes spdy transactions. + PRUint32 mHttp1xTransactionCount; + // SPDY related bool mNPNComplete; bool mSetupNPNCalled; @@ -228,6 +233,9 @@ private: nsRefPtr mSpdySession; PRInt32 mPriority; bool mReportedSpdy; + + // mUsingSpdy is cleared when mSpdySession is freed, this is permanent + bool mEverUsedSpdy; }; #endif // nsHttpConnection_h__ diff --git a/netwerk/protocol/http/nsHttpConnectionMgr.cpp b/netwerk/protocol/http/nsHttpConnectionMgr.cpp index 8c7703af0102..17d897f8175b 100644 --- a/netwerk/protocol/http/nsHttpConnectionMgr.cpp +++ b/netwerk/protocol/http/nsHttpConnectionMgr.cpp @@ -50,6 +50,7 @@ #include "nsISSLSocketControl.h" #include "prnetdb.h" +#include "mozilla/Telemetry.h" using namespace mozilla; @@ -660,6 +661,8 @@ nsHttpConnectionMgr::GetSpdyPreferred(nsConnectionEntry *aOriginalEntry) "Host %s cannot be confirmed to be joined " "with %s connections", preferred->mConnInfo->Host(), aOriginalEntry->mConnInfo->Host())); + mozilla::Telemetry::Accumulate(mozilla::Telemetry::SPDY_NPN_JOIN, + false); return nsnull; } @@ -667,6 +670,7 @@ nsHttpConnectionMgr::GetSpdyPreferred(nsConnectionEntry *aOriginalEntry) LOG(("nsHttpConnectionMgr::GetSpdyPreferredConnection " "Host %s has cert valid for %s connections", preferred->mConnInfo->Host(), aOriginalEntry->mConnInfo->Host())); + mozilla::Telemetry::Accumulate(mozilla::Telemetry::SPDY_NPN_JOIN, true); return preferred; } diff --git a/netwerk/protocol/http/nsHttpPipeline.cpp b/netwerk/protocol/http/nsHttpPipeline.cpp index 8a7333381249..b78b88091237 100644 --- a/netwerk/protocol/http/nsHttpPipeline.cpp +++ b/netwerk/protocol/http/nsHttpPipeline.cpp @@ -101,6 +101,7 @@ nsHttpPipeline::nsHttpPipeline() , mPushBackBuf(nsnull) , mPushBackLen(0) , mPushBackMax(0) + , mHttp1xTransactionCount(0) , mReceivingFromProgress(0) , mSendingToProgress(0) , mSuppressSendEvents(true) @@ -355,6 +356,12 @@ nsHttpPipeline::RequestHead() return nsnull; } +PRUint32 +nsHttpPipeline::Http1xTransactionCount() +{ + return mHttp1xTransactionCount; +} + //----------------------------------------------------------------------------- // nsHttpPipeline::nsAHttpConnection //----------------------------------------------------------------------------- @@ -614,6 +621,7 @@ nsHttpPipeline::WriteSegments(nsAHttpSegmentWriter *writer, NS_RELEASE(trans); mResponseQ.RemoveElementAt(0); mResponseIsPartial = false; + ++mHttp1xTransactionCount; // ask the connection manager to add additional transactions // to our pipeline. diff --git a/netwerk/protocol/http/nsHttpPipeline.h b/netwerk/protocol/http/nsHttpPipeline.h index c78a72589d84..ca45fc30f2d0 100644 --- a/netwerk/protocol/http/nsHttpPipeline.h +++ b/netwerk/protocol/http/nsHttpPipeline.h @@ -112,6 +112,9 @@ private: PRUint32 mPushBackLen; PRUint32 mPushBackMax; + // The number of transactions completed on this pipeline. + PRUint32 mHttp1xTransactionCount; + // For support of OnTransportStatus() PRUint64 mReceivingFromProgress; PRUint64 mSendingToProgress; diff --git a/netwerk/protocol/http/nsHttpTransaction.cpp b/netwerk/protocol/http/nsHttpTransaction.cpp index 8895e80e8257..bb149d7bfa83 100644 --- a/netwerk/protocol/http/nsHttpTransaction.cpp +++ b/netwerk/protocol/http/nsHttpTransaction.cpp @@ -336,6 +336,12 @@ nsHttpTransaction::RequestHead() return mRequestHead; } +PRUint32 +nsHttpTransaction::Http1xTransactionCount() +{ + return 1; +} + //---------------------------------------------------------------------------- // nsHttpTransaction::nsAHttpTransaction //---------------------------------------------------------------------------- diff --git a/toolkit/components/telemetry/TelemetryHistograms.h b/toolkit/components/telemetry/TelemetryHistograms.h index 1ad2c243754a..c63e42f3cf1a 100644 --- a/toolkit/components/telemetry/TelemetryHistograms.h +++ b/toolkit/components/telemetry/TelemetryHistograms.h @@ -141,6 +141,8 @@ HISTOGRAM(HTTP_SUBITEM_OPEN_LATENCY_TIME, 1, 30000, 50, EXPONENTIAL, "HTTP subit HISTOGRAM(HTTP_SUBITEM_FIRST_BYTE_LATENCY_TIME, 1, 30000, 50, EXPONENTIAL, "HTTP subitem: Page start -> first byte received for subitem reply (ms)") HISTOGRAM(HTTP_REQUEST_PER_PAGE, 1, 1000, 50, EXPONENTIAL, "HTTP: Requests per page (count)") HISTOGRAM(HTTP_REQUEST_PER_PAGE_FROM_CACHE, 1, 101, 102, LINEAR, "HTTP: Requests serviced from cache (%)") +HISTOGRAM(HTTP_REQUEST_PER_CONN, 1, 1000, 50, EXPONENTIAL, "HTTP: requests per connection") +HISTOGRAM(HTTP_KBREAD_PER_CONN, 1, 3000, 50, EXPONENTIAL, "HTTP: KB read per connection") #define _HTTP_HIST(name, label) \ HISTOGRAM(name, 1, 30000, 50, EXPONENTIAL, "HTTP " label) \ @@ -163,7 +165,7 @@ HTTP_HISTOGRAMS(PAGE, "page: ") HTTP_HISTOGRAMS(SUB, "subitem: ") HISTOGRAM(SPDY_PARALLEL_STREAMS, 1, 1000, 50, EXPONENTIAL, "SPDY: Streams concurrent active per connection") -HISTOGRAM(SPDY_TOTAL_STREAMS, 1, 100000, 50, EXPONENTIAL, "SPDY: Streams created per connection") +HISTOGRAM(SPDY_REQUEST_PER_CONN, 1, 1000, 50, EXPONENTIAL, "SPDY: Streams created per connection") HISTOGRAM(SPDY_SERVER_INITIATED_STREAMS, 1, 100000, 250, EXPONENTIAL, "SPDY: Streams recevied per connection") HISTOGRAM(SPDY_CHUNK_RECVD, 1, 1000, 100, EXPONENTIAL, "SPDY: Recvd Chunk Size (rounded to KB)") HISTOGRAM(SPDY_SYN_SIZE, 20, 20000, 50, EXPONENTIAL, "SPDY: SYN Frame Header Size") @@ -171,6 +173,8 @@ HISTOGRAM(SPDY_SYN_RATIO, 1, 99, 20, LINEAR, "SPDY: SYN Frame Header Ratio (low HISTOGRAM(SPDY_SYN_REPLY_SIZE, 16, 20000, 50, EXPONENTIAL, "SPDY: SYN Reply Header Size") HISTOGRAM(SPDY_SYN_REPLY_RATIO, 1, 99, 20, LINEAR, "SPDY: SYN Reply Header Ratio (lower better)") HISTOGRAM(SPDY_NPN_CONNECT, 0, 1, 2, BOOLEAN, "SPDY: NPN Negotiated") +HISTOGRAM(SPDY_NPN_JOIN, 0, 1, 2, BOOLEAN, "SPDY: Coalesce Succeeded") +HISTOGRAM(SPDY_KBREAD_PER_CONN, 1, 3000, 50, EXPONENTIAL, "SPDY: KB read per connection") HISTOGRAM(SPDY_SETTINGS_UL_BW, 1, 10000, 100, EXPONENTIAL, "SPDY: Settings Upload Bandwidth") HISTOGRAM(SPDY_SETTINGS_DL_BW, 1, 10000, 100, EXPONENTIAL, "SPDY: Settings Download Bandwidth")