diff -r 000000000000 -r 6474c204b198 netwerk/protocol/http/ConnectionDiagnostics.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/netwerk/protocol/http/ConnectionDiagnostics.cpp Wed Dec 31 06:09:35 2014 +0100 @@ -0,0 +1,290 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set sw=2 ts=8 et tw=80 : */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +// HttpLog.h should generally be included first +#include "HttpLog.h" + +#include "nsHttpConnectionMgr.h" +#include "nsHttpConnection.h" +#include "SpdySession3.h" +#include "SpdySession31.h" +#include "Http2Session.h" +#include "nsHttpHandler.h" +#include "nsIConsoleService.h" +#include "nsHttpRequestHead.h" + +extern PRThread *gSocketThread; + +namespace mozilla { +namespace net { + +void +nsHttpConnectionMgr::PrintDiagnostics() +{ + PostEvent(&nsHttpConnectionMgr::OnMsgPrintDiagnostics, 0, nullptr); +} + +void +nsHttpConnectionMgr::OnMsgPrintDiagnostics(int32_t, void *) +{ + MOZ_ASSERT(PR_GetCurrentThread() == gSocketThread); + + nsCOMPtr consoleService = + do_GetService(NS_CONSOLESERVICE_CONTRACTID); + if (!consoleService) + return; + + mLogData.AppendPrintf("HTTP Connection Diagnostics\n---------------------\n"); + mLogData.AppendPrintf("IsSpdyEnabled() = %d\n", gHttpHandler->IsSpdyEnabled()); + mLogData.AppendPrintf("MaxSocketCount() = %d\n", gHttpHandler->MaxSocketCount()); + mLogData.AppendPrintf("mNumActiveConns = %d\n", mNumActiveConns); + mLogData.AppendPrintf("mNumIdleConns = %d\n", mNumIdleConns); + + mCT.Enumerate(PrintDiagnosticsCB, this); + + consoleService->LogStringMessage(NS_ConvertUTF8toUTF16(mLogData).Data()); + mLogData.Truncate(); +} + +PLDHashOperator +nsHttpConnectionMgr::PrintDiagnosticsCB(const nsACString &key, + nsAutoPtr &ent, + void *closure) +{ + nsHttpConnectionMgr *self = static_cast(closure); + uint32_t i; + + self->mLogData.AppendPrintf(" ent host = %s hashkey = %s\n", + ent->mConnInfo->Host(), ent->mConnInfo->HashKey().get()); + self->mLogData.AppendPrintf(" AtActiveConnectionLimit = %d\n", + self->AtActiveConnectionLimit(ent, NS_HTTP_ALLOW_KEEPALIVE)); + self->mLogData.AppendPrintf(" RestrictConnections = %d\n", + self->RestrictConnections(ent)); + self->mLogData.AppendPrintf(" Pending Q Length = %u\n", + ent->mPendingQ.Length()); + self->mLogData.AppendPrintf(" Active Conns Length = %u\n", + ent->mActiveConns.Length()); + self->mLogData.AppendPrintf(" Idle Conns Length = %u\n", + ent->mIdleConns.Length()); + self->mLogData.AppendPrintf(" Half Opens Length = %u\n", + ent->mHalfOpens.Length()); + self->mLogData.AppendPrintf(" Coalescing Key = %s\n", + ent->mCoalescingKey.get()); + self->mLogData.AppendPrintf(" Spdy using = %d, tested = %d, preferred = %d\n", + ent->mUsingSpdy, ent->mTestedSpdy, ent->mSpdyPreferred); + self->mLogData.AppendPrintf(" pipelinestate = %d penalty = %d\n", + ent->mPipelineState, ent->mPipeliningPenalty); + for (i = 0; i < nsAHttpTransaction::CLASS_MAX; ++i) { + self->mLogData.AppendPrintf(" pipeline per class penalty 0x%x %d\n", + i, ent->mPipeliningClassPenalty[i]); + } + for (i = 0; i < ent->mActiveConns.Length(); ++i) { + self->mLogData.AppendPrintf(" :: Active Connection #%u\n", i); + ent->mActiveConns[i]->PrintDiagnostics(self->mLogData); + } + for (i = 0; i < ent->mIdleConns.Length(); ++i) { + self->mLogData.AppendPrintf(" :: Idle Connection #%u\n", i); + ent->mIdleConns[i]->PrintDiagnostics(self->mLogData); + } + for (i = 0; i < ent->mHalfOpens.Length(); ++i) { + self->mLogData.AppendPrintf(" :: Half Open #%u\n", i); + ent->mHalfOpens[i]->PrintDiagnostics(self->mLogData); + } + for (i = 0; i < ent->mPendingQ.Length(); ++i) { + self->mLogData.AppendPrintf(" :: Pending Transaction #%u\n", i); + ent->mPendingQ[i]->PrintDiagnostics(self->mLogData); + } + + return PL_DHASH_NEXT; +} + +void +nsHttpConnectionMgr::nsHalfOpenSocket::PrintDiagnostics(nsCString &log) +{ + log.AppendPrintf(" has connected = %d, isSpeculative = %d\n", + HasConnected(), IsSpeculative()); + + TimeStamp now = TimeStamp::Now(); + + if (mPrimarySynStarted.IsNull()) + log.AppendPrintf(" primary not started\n"); + else + log.AppendPrintf(" primary started %.2fms ago\n", + (now - mPrimarySynStarted).ToMilliseconds()); + + if (mBackupSynStarted.IsNull()) + log.AppendPrintf(" backup not started\n"); + else + log.AppendPrintf(" backup started %.2f ago\n", + (now - mBackupSynStarted).ToMilliseconds()); + + log.AppendPrintf(" primary transport %d, backup transport %d\n", + !!mSocketTransport.get(), !!mBackupTransport.get()); +} + +void +nsHttpConnection::PrintDiagnostics(nsCString &log) +{ + log.AppendPrintf(" CanDirectlyActivate = %d\n", CanDirectlyActivate()); + + log.AppendPrintf(" npncomplete = %d setupSSLCalled = %d\n", + mNPNComplete, mSetupSSLCalled); + + log.AppendPrintf(" spdyVersion = %d reportedSpdy = %d everspdy = %d\n", + mUsingSpdyVersion, mReportedSpdy, mEverUsedSpdy); + + log.AppendPrintf(" iskeepalive = %d dontReuse = %d isReused = %d\n", + IsKeepAlive(), mDontReuse, mIsReused); + + log.AppendPrintf(" mTransaction = %d mSpdySession = %d\n", + !!mTransaction.get(), !!mSpdySession.get()); + + PRIntervalTime now = PR_IntervalNow(); + log.AppendPrintf(" time since last read = %ums\n", + PR_IntervalToMilliseconds(now - mLastReadTime)); + + log.AppendPrintf(" max-read/read/written %lld/%lld/%lld\n", + mMaxBytesRead, mTotalBytesRead, mTotalBytesWritten); + + log.AppendPrintf(" rtt = %ums\n", PR_IntervalToMilliseconds(mRtt)); + + log.AppendPrintf(" idlemonitoring = %d transactionCount=%d\n", + mIdleMonitoring, mHttp1xTransactionCount); + + log.AppendPrintf(" supports pipeline = %d classification = 0x%x\n", + mSupportsPipelining, mClassification); + + if (mSpdySession) + mSpdySession->PrintDiagnostics(log); +} + + +void +SpdySession3::PrintDiagnostics(nsCString &log) +{ + log.AppendPrintf(" ::: SPDY VERSION 3\n"); + log.AppendPrintf(" shouldgoaway = %d mClosed = %d CanReuse = %d nextID=0x%X\n", + mShouldGoAway, mClosed, CanReuse(), mNextStreamID); + + log.AppendPrintf(" concurrent = %d maxconcurrent = %d\n", + mConcurrent, mMaxConcurrent); + + log.AppendPrintf(" roomformorestreams = %d roomformoreconcurrent = %d\n", + RoomForMoreStreams(), RoomForMoreConcurrent()); + + log.AppendPrintf(" transactionHashCount = %d streamIDHashCount = %d\n", + mStreamTransactionHash.Count(), + mStreamIDHash.Count()); + + log.AppendPrintf(" Queued Stream Size = %d\n", mQueuedStreams.GetSize()); + + PRIntervalTime now = PR_IntervalNow(); + log.AppendPrintf(" Ping Threshold = %ums next ping id = 0x%X\n", + PR_IntervalToMilliseconds(mPingThreshold), + mNextPingID); + log.AppendPrintf(" Ping Timeout = %ums\n", + PR_IntervalToMilliseconds(gHttpHandler->SpdyPingTimeout())); + log.AppendPrintf(" Idle for Any Activity (ping) = %ums\n", + PR_IntervalToMilliseconds(now - mLastReadEpoch)); + log.AppendPrintf(" Idle for Data Activity = %ums\n", + PR_IntervalToMilliseconds(now - mLastDataReadEpoch)); + if (mPingSentEpoch) + log.AppendPrintf(" Ping Outstanding (ping) = %ums, expired = %d\n", + PR_IntervalToMilliseconds(now - mPingSentEpoch), + now - mPingSentEpoch >= gHttpHandler->SpdyPingTimeout()); + else + log.AppendPrintf(" No Ping Outstanding\n"); +} + +void +SpdySession31::PrintDiagnostics(nsCString &log) +{ + log.AppendPrintf(" ::: SPDY VERSION 3.1\n"); + log.AppendPrintf(" shouldgoaway = %d mClosed = %d CanReuse = %d nextID=0x%X\n", + mShouldGoAway, mClosed, CanReuse(), mNextStreamID); + + log.AppendPrintf(" concurrent = %d maxconcurrent = %d\n", + mConcurrent, mMaxConcurrent); + + log.AppendPrintf(" roomformorestreams = %d roomformoreconcurrent = %d\n", + RoomForMoreStreams(), RoomForMoreConcurrent()); + + log.AppendPrintf(" transactionHashCount = %d streamIDHashCount = %d\n", + mStreamTransactionHash.Count(), + mStreamIDHash.Count()); + + log.AppendPrintf(" Queued Stream Size = %d\n", mQueuedStreams.GetSize()); + + PRIntervalTime now = PR_IntervalNow(); + log.AppendPrintf(" Ping Threshold = %ums next ping id = 0x%X\n", + PR_IntervalToMilliseconds(mPingThreshold), + mNextPingID); + log.AppendPrintf(" Ping Timeout = %ums\n", + PR_IntervalToMilliseconds(gHttpHandler->SpdyPingTimeout())); + log.AppendPrintf(" Idle for Any Activity (ping) = %ums\n", + PR_IntervalToMilliseconds(now - mLastReadEpoch)); + log.AppendPrintf(" Idle for Data Activity = %ums\n", + PR_IntervalToMilliseconds(now - mLastDataReadEpoch)); + if (mPingSentEpoch) + log.AppendPrintf(" Ping Outstanding (ping) = %ums, expired = %d\n", + PR_IntervalToMilliseconds(now - mPingSentEpoch), + now - mPingSentEpoch >= gHttpHandler->SpdyPingTimeout()); + else + log.AppendPrintf(" No Ping Outstanding\n"); +} + +void +Http2Session::PrintDiagnostics(nsCString &log) +{ + log.AppendPrintf(" ::: HTTP2\n"); + log.AppendPrintf(" shouldgoaway = %d mClosed = %d CanReuse = %d nextID=0x%X\n", + mShouldGoAway, mClosed, CanReuse(), mNextStreamID); + + log.AppendPrintf(" concurrent = %d maxconcurrent = %d\n", + mConcurrent, mMaxConcurrent); + + log.AppendPrintf(" roomformorestreams = %d roomformoreconcurrent = %d\n", + RoomForMoreStreams(), RoomForMoreConcurrent()); + + log.AppendPrintf(" transactionHashCount = %d streamIDHashCount = %d\n", + mStreamTransactionHash.Count(), + mStreamIDHash.Count()); + + log.AppendPrintf(" Queued Stream Size = %d\n", mQueuedStreams.GetSize()); + + PRIntervalTime now = PR_IntervalNow(); + log.AppendPrintf(" Ping Threshold = %ums\n", + PR_IntervalToMilliseconds(mPingThreshold)); + log.AppendPrintf(" Ping Timeout = %ums\n", + PR_IntervalToMilliseconds(gHttpHandler->SpdyPingTimeout())); + log.AppendPrintf(" Idle for Any Activity (ping) = %ums\n", + PR_IntervalToMilliseconds(now - mLastReadEpoch)); + log.AppendPrintf(" Idle for Data Activity = %ums\n", + PR_IntervalToMilliseconds(now - mLastDataReadEpoch)); + if (mPingSentEpoch) + log.AppendPrintf(" Ping Outstanding (ping) = %ums, expired = %d\n", + PR_IntervalToMilliseconds(now - mPingSentEpoch), + now - mPingSentEpoch >= gHttpHandler->SpdyPingTimeout()); + else + log.AppendPrintf(" No Ping Outstanding\n"); +} + +void +nsHttpTransaction::PrintDiagnostics(nsCString &log) +{ + if (!mRequestHead) + return; + + log.AppendPrintf(" ::: uri = %s\n", + nsAutoCString(mRequestHead->RequestURI()).get()); + log.AppendPrintf(" caps = 0x%x\n", mCaps); + log.AppendPrintf(" priority = %d\n", mPriority); + log.AppendPrintf(" restart count = %u\n", mRestartCount); + log.AppendPrintf(" classification = 0x%x\n", mClassification); +} + +} // namespace mozilla::net +} // namespace mozilla