/* -*- 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