ConnectionDiagnostics.cpp (9249B)
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 2 /* vim: set sw=2 ts=8 et tw=80 : */ 3 /* This Source Code Form is subject to the terms of the Mozilla Public 4 * License, v. 2.0. If a copy of the MPL was not distributed with this 5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 6 7 // HttpLog.h should generally be included first 8 #include "HttpLog.h" 9 10 #include "nsHttpConnectionMgr.h" 11 #include "nsHttpConnection.h" 12 #include "HttpConnectionUDP.h" 13 #include "Http2Session.h" 14 #include "nsHttpHandler.h" 15 #include "nsIConsoleService.h" 16 #include "nsHttpRequestHead.h" 17 #include "nsServiceManagerUtils.h" 18 #include "nsSocketTransportService2.h" 19 20 #include "mozilla/IntegerPrintfMacros.h" 21 #include "mozilla/StaticPrefs_network.h" 22 23 namespace mozilla { 24 namespace net { 25 26 void nsHttpConnectionMgr::PrintDiagnostics() { 27 nsresult rv = 28 PostEvent(&nsHttpConnectionMgr::OnMsgPrintDiagnostics, 0, nullptr); 29 if (NS_FAILED(rv)) { 30 LOG( 31 ("nsHttpConnectionMgr::PrintDiagnostics\n" 32 " failed to post OnMsgPrintDiagnostics event")); 33 } 34 } 35 36 void nsHttpConnectionMgr::OnMsgPrintDiagnostics(int32_t, ARefBase*) { 37 MOZ_ASSERT(OnSocketThread(), "not on socket thread"); 38 39 nsCOMPtr<nsIConsoleService> consoleService = 40 do_GetService(NS_CONSOLESERVICE_CONTRACTID); 41 if (!consoleService) return; 42 43 mLogData.AppendPrintf("HTTP Connection Diagnostics\n---------------------\n"); 44 mLogData.AppendPrintf("IsSpdyEnabled() = %d\n", 45 StaticPrefs::network_http_http2_enabled()); 46 mLogData.AppendPrintf("MaxSocketCount() = %d\n", 47 gHttpHandler->MaxSocketCount()); 48 mLogData.AppendPrintf("mNumActiveConns = %d\n", mNumActiveConns); 49 mLogData.AppendPrintf("mNumIdleConns = %d\n", mNumIdleConns); 50 51 for (const RefPtr<ConnectionEntry>& ent : mCT.Values()) { 52 mLogData.AppendPrintf( 53 " AtActiveConnectionLimit = %d\n", 54 AtActiveConnectionLimit(ent, NS_HTTP_ALLOW_KEEPALIVE)); 55 56 ent->PrintDiagnostics(mLogData, MaxPersistConnections(ent)); 57 } 58 59 consoleService->LogStringMessage(NS_ConvertUTF8toUTF16(mLogData).Data()); 60 mLogData.Truncate(); 61 } 62 63 void ConnectionEntry::PrintDiagnostics(nsCString& log, 64 uint32_t aMaxPersistConns) { 65 log.AppendPrintf(" ent host = %s hashkey = %s\n", mConnInfo->Origin(), 66 mConnInfo->HashKey().get()); 67 68 log.AppendPrintf(" RestrictConnections = %d\n", RestrictConnections()); 69 log.AppendPrintf(" Pending Q Length = %zu\n", PendingQueueLength()); 70 log.AppendPrintf(" Active Conns Length = %zu\n", mActiveConns.Length()); 71 log.AppendPrintf(" Idle Conns Length = %zu\n", mIdleConns.Length()); 72 log.AppendPrintf(" DnsAndSock Length = %zu\n", 73 mDnsAndConnectSockets.Length()); 74 log.AppendPrintf(" Coalescing Keys Length = %zu\n", 75 mCoalescingKeys.Length()); 76 log.AppendPrintf(" Spdy using = %d\n", mUsingSpdy); 77 78 uint32_t i; 79 for (i = 0; i < mActiveConns.Length(); ++i) { 80 log.AppendPrintf(" :: Active Connection #%u\n", i); 81 mActiveConns[i]->PrintDiagnostics(log); 82 } 83 for (i = 0; i < mIdleConns.Length(); ++i) { 84 log.AppendPrintf(" :: Idle Connection #%u\n", i); 85 mIdleConns[i]->PrintDiagnostics(log); 86 } 87 for (i = 0; i < mDnsAndConnectSockets.Length(); ++i) { 88 log.AppendPrintf(" :: Half Open #%u\n", i); 89 mDnsAndConnectSockets[i]->PrintDiagnostics(log); 90 } 91 92 mPendingQ.PrintDiagnostics(log); 93 94 for (i = 0; i < mCoalescingKeys.Length(); ++i) { 95 log.AppendPrintf(" :: Coalescing Key #%u %s\n", i, 96 mCoalescingKeys[i].get()); 97 } 98 } 99 100 void PendingTransactionQueue::PrintDiagnostics(nsCString& log) { 101 uint32_t i = 0; 102 for (const auto& entry : mPendingTransactionTable) { 103 log.AppendPrintf(" :: Pending Transactions with Window ID = %" PRIu64 104 "\n", 105 entry.GetKey()); 106 for (uint32_t j = 0; j < entry.GetData()->Length(); ++j) { 107 log.AppendPrintf(" ::: Pending Transaction #%u\n", i); 108 entry.GetData()->ElementAt(j)->PrintDiagnostics(log); 109 ++i; 110 } 111 } 112 } 113 114 void DnsAndConnectSocket::PrintDiagnostics(nsCString& log) { 115 log.AppendPrintf(" has connected = %d, isSpeculative = %d\n", 116 HasConnected(), IsSpeculative()); 117 118 TimeStamp now = TimeStamp::Now(); 119 120 if (mPrimaryTransport.mSynStarted.IsNull()) { 121 log.AppendPrintf(" primary not started\n"); 122 } else { 123 log.AppendPrintf(" primary started %.2fms ago\n", 124 (now - mPrimaryTransport.mSynStarted).ToMilliseconds()); 125 } 126 127 if (mBackupTransport.mSynStarted.IsNull()) { 128 log.AppendPrintf(" backup not started\n"); 129 } else { 130 log.AppendPrintf(" backup started %.2f ago\n", 131 (now - mBackupTransport.mSynStarted).ToMilliseconds()); 132 } 133 134 log.AppendPrintf(" primary transport %d, backup transport %d\n", 135 !!mPrimaryTransport.mSocketTransport, 136 !!mBackupTransport.mSocketTransport); 137 } 138 139 void nsHttpConnection::PrintDiagnostics(nsCString& log) { 140 log.AppendPrintf(" CanDirectlyActivate = %d\n", CanDirectlyActivate()); 141 142 log.AppendPrintf(" npncomplete = %d setupSSLCalled = %d\n", 143 mTlsHandshaker->NPNComplete(), 144 mTlsHandshaker->SetupSSLCalled()); 145 146 log.AppendPrintf(" spdyVersion = %d reportedSpdy = %d everspdy = %d\n", 147 static_cast<int32_t>(mUsingSpdyVersion), mReportedSpdy, 148 mEverUsedSpdy); 149 150 log.AppendPrintf(" iskeepalive = %d dontReuse = %d isReused = %d\n", 151 IsKeepAlive(), mDontReuse, mIsReused); 152 153 log.AppendPrintf(" mTransaction = %d mSpdySession = %d\n", !!mTransaction, 154 !!mSpdySession); 155 156 PRIntervalTime now = PR_IntervalNow(); 157 log.AppendPrintf(" time since last read = %ums\n", 158 PR_IntervalToMilliseconds(now - mLastReadTime)); 159 160 log.AppendPrintf(" max-read/read/written %" PRId64 "/%" PRId64 "/%" PRId64 161 "\n", 162 mMaxBytesRead, mTotalBytesRead, mTotalBytesWritten); 163 164 log.AppendPrintf(" rtt = %ums\n", PR_IntervalToMilliseconds(mRtt)); 165 166 log.AppendPrintf(" idlemonitoring = %d transactionCount=%d\n", 167 mIdleMonitoring, mHttp1xTransactionCount); 168 169 if (mSpdySession) mSpdySession->PrintDiagnostics(log); 170 } 171 172 void HttpConnectionUDP::PrintDiagnostics(nsCString& log) { 173 log.AppendPrintf(" CanDirectlyActivate = %d\n", CanDirectlyActivate()); 174 175 log.AppendPrintf(" dontReuse = %d isReused = %d\n", mDontReuse, mIsReused); 176 177 log.AppendPrintf(" read/written %" PRId64 "/%" PRId64 "\n", 178 mHttp3Session ? mHttp3Session->BytesRead() : 0, 179 mHttp3Session ? mHttp3Session->GetBytesWritten() : 0); 180 181 log.AppendPrintf(" rtt = %ums\n", PR_IntervalToMilliseconds(mRtt)); 182 } 183 184 void Http2Session::PrintDiagnostics(nsCString& log) { 185 log.AppendPrintf(" ::: HTTP2\n"); 186 log.AppendPrintf( 187 " shouldgoaway = %d mClosed = %d CanReuse = %d nextID=0x%X\n", 188 mShouldGoAway, mClosed, CanReuse(), mNextStreamID); 189 190 log.AppendPrintf(" concurrent = %d maxconcurrent = %d\n", mConcurrent, 191 mMaxConcurrent); 192 193 log.AppendPrintf(" roomformorestreams = %d roomformoreconcurrent = %d\n", 194 RoomForMoreStreams(), RoomForMoreConcurrent()); 195 196 log.AppendPrintf(" transactionHashCount = %d streamIDHashCount = %d\n", 197 mStreamTransactionHash.Count(), mStreamIDHash.Count()); 198 199 PRIntervalTime now = PR_IntervalNow(); 200 log.AppendPrintf(" Ping Threshold = %ums\n", 201 PR_IntervalToMilliseconds(mPingThreshold)); 202 log.AppendPrintf(" Ping Timeout = %ums\n", 203 PR_IntervalToMilliseconds(gHttpHandler->SpdyPingTimeout())); 204 log.AppendPrintf(" Idle for Any Activity (ping) = %ums\n", 205 PR_IntervalToMilliseconds(now - mLastReadEpoch)); 206 log.AppendPrintf(" Idle for Data Activity = %ums\n", 207 PR_IntervalToMilliseconds(now - mLastDataReadEpoch)); 208 if (mPingSentEpoch) { 209 log.AppendPrintf(" Ping Outstanding (ping) = %ums, expired = %d\n", 210 PR_IntervalToMilliseconds(now - mPingSentEpoch), 211 now - mPingSentEpoch >= gHttpHandler->SpdyPingTimeout()); 212 } else { 213 log.AppendPrintf(" No Ping Outstanding\n"); 214 } 215 } 216 217 void nsHttpTransaction::PrintDiagnostics(nsCString& log) { 218 if (!mRequestHead) return; 219 220 nsAutoCString requestURI; 221 mRequestHead->RequestURI(requestURI); 222 log.AppendPrintf(" :::: uri = %s\n", requestURI.get()); 223 log.AppendPrintf(" caps = 0x%x\n", static_cast<uint32_t>(mCaps)); 224 log.AppendPrintf(" priority = %d\n", mPriority); 225 log.AppendPrintf(" restart count = %u\n", mRestartCount); 226 } 227 228 void PendingTransactionInfo::PrintDiagnostics(nsCString& log) { 229 log.AppendPrintf(" ::: Pending transaction\n"); 230 mTransaction->PrintDiagnostics(log); 231 RefPtr<DnsAndConnectSocket> dnsAndSock = do_QueryReferent(mDnsAndSock); 232 log.AppendPrintf(" Waiting for half open sock: %p or connection: %p\n", 233 dnsAndSock.get(), mActiveConn.get()); 234 } 235 236 } // namespace net 237 } // namespace mozilla