Bug 1341128 - high level HTTP Channel Success Telemetry r=dragana r=bsmedberg
authorPatrick McManus <mcmanus@ducksong.com>
Mon, 20 Feb 2017 17:15:36 -0500
changeset 373423 8128e71288af4e1455db51ff32962b4bff73edba
parent 373422 ec3487e17b2f04d247601d1019c219c762c1318f
child 373424 361f2f36838371c5c4e1d68571e0c69a77cc75b4
push id10863
push userjlorenzo@mozilla.com
push dateMon, 06 Mar 2017 23:02:23 +0000
treeherdermozilla-aurora@0931190cd725 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersdragana, bsmedberg
bugs1341128
milestone54.0a1
Bug 1341128 - high level HTTP Channel Success Telemetry r=dragana r=bsmedberg
netwerk/protocol/http/nsHttpChannel.cpp
netwerk/protocol/http/nsHttpChannel.h
netwerk/protocol/http/nsHttpTransaction.h
toolkit/components/telemetry/Histograms.json
--- a/netwerk/protocol/http/nsHttpChannel.cpp
+++ b/netwerk/protocol/http/nsHttpChannel.cpp
@@ -278,16 +278,17 @@ nsHttpChannel::nsHttpChannel()
     , mCacheEntriesToWaitFor(0)
     , mHasQueryString(0)
     , mConcurrentCacheAccess(0)
     , mIsPartialRequest(0)
     , mHasAutoRedirectVetoNotifier(0)
     , mPinCacheContent(0)
     , mIsCorsPreflightDone(0)
     , mStronglyFramed(false)
+    , mUsedNetwork(0)
     , mPushedStream(nullptr)
     , mLocalBlocklist(false)
     , mWarningReporter(nullptr)
     , mIsReadingFromCache(false)
     , mOnCacheAvailableCalled(false)
     , mRacingNetAndCache(false)
     , mDidReval(false)
 {
@@ -819,16 +820,17 @@ nsresult
 nsHttpChannel::SetupTransaction()
 {
     LOG(("nsHttpChannel::SetupTransaction [this=%p]\n", this));
 
     NS_ENSURE_TRUE(!mTransaction, NS_ERROR_ALREADY_INITIALIZED);
 
     nsresult rv;
 
+    mUsedNetwork = 1;
     if (mCaps & NS_HTTP_ALLOW_PIPELINING) {
         //
         // disable pipelining if:
         //   (1) pipelining has been disabled by config
         //   (2) pipelining has been disabled by connection mgr info
         //   (3) request corresponds to a top-level document load (link click)
         //   (4) request method is non-idempotent
         //   (5) request is marked slow (e.g XHR)
@@ -6937,16 +6939,52 @@ nsHttpChannel::OnStopRequest(nsIRequest 
 
         if (mUpgradeProtocolCallback && stickyConn &&
             mResponseHead && mResponseHead->Status() == 101) {
             gHttpHandler->ConnMgr()->CompleteUpgrade(stickyConn,
                                                      mUpgradeProtocolCallback);
         }
     }
 
+    // HTTP_CHANNEL_DISPOSITION TELEMETRY
+    enum ChannelDisposition
+    {
+        kHttpCanceled = 0,
+        kHttpDisk = 1,
+        kHttpNetOK = 2,
+        kHttpNetEarlyFail = 3,
+        kHttpNetLateFail = 4,
+        kHttpsCanceled = 8,
+        kHttpsDisk = 9,
+        kHttpsNetOK = 10,
+        kHttpsNetEarlyFail = 11,
+        kHttpsNetLateFail = 12
+    } chanDisposition = kHttpCanceled;
+
+    // HTTP 0.9 is more likely to be an error than really 0.9, so count it that way
+    if (mCanceled) {
+        chanDisposition  = kHttpCanceled;
+    } else if (!mUsedNetwork) {
+        chanDisposition = kHttpDisk;
+    } else if (NS_SUCCEEDED(status) &&
+               mResponseHead &&
+               mResponseHead->Version() != NS_HTTP_VERSION_0_9) {
+        chanDisposition = kHttpNetOK;
+    } else if (!mTransferSize) {
+        chanDisposition = kHttpNetEarlyFail;
+    } else {
+        chanDisposition = kHttpNetLateFail;
+    }
+    if (IsHTTPS()) {
+        // shift http to https disposition enums
+        chanDisposition = static_cast<ChannelDisposition>(chanDisposition + kHttpsCanceled);
+    }
+    LOG(("  nsHttpChannel::OnStopRequest ChannelDisposition %d\n", chanDisposition));
+    Telemetry::Accumulate(Telemetry::HTTP_CHANNEL_DISPOSITION, chanDisposition);
+
     // if needed, check cache entry has all data we expect
     if (mCacheEntry && mCachePump &&
         mConcurrentCacheAccess && contentComplete) {
         int64_t size, contentLength;
         nsresult rv = CheckPartial(mCacheEntry, &size, &contentLength);
         if (NS_SUCCEEDED(rv)) {
             if (size == int64_t(-1)) {
                 // mayhemer TODO - we have to restart read from cache here at the size offset
--- a/netwerk/protocol/http/nsHttpChannel.h
+++ b/netwerk/protocol/http/nsHttpChannel.h
@@ -586,16 +586,19 @@ private:
     // True if CORS preflight has been performed
     uint32_t                          mIsCorsPreflightDone : 1;
 
     // if the http transaction was performed (i.e. not cached) and
     // the result in OnStopRequest was known to be correctly delimited
     // by chunking, content-length, or h2 end-stream framing
     uint32_t                          mStronglyFramed : 1;
 
+    // true if an HTTP transaction is created for the socket thread
+    uint32_t                          mUsedNetwork : 1;
+
     nsTArray<nsContinueRedirectionFunc> mRedirectFuncStack;
 
     // Needed for accurate DNS timing
     RefPtr<nsDNSPrefetch>           mDNSPrefetch;
 
     Http2PushedStream                 *mPushedStream;
     // True if the channel's principal was found on a phishing, malware, or
     // tracking (if tracking protection is enabled) blocklist
--- a/netwerk/protocol/http/nsHttpTransaction.h
+++ b/netwerk/protocol/http/nsHttpTransaction.h
@@ -252,17 +252,17 @@ private:
 
     nsAHttpSegmentReader           *mReader;
     nsAHttpSegmentWriter           *mWriter;
 
     nsCString                       mLineBuf;         // may contain a partial line
 
     int64_t                         mContentLength;   // equals -1 if unknown
     int64_t                         mContentRead;     // count of consumed content bytes
-    int64_t                         mTransferSize; // count of received bytes
+    Atomic<int64_t, ReleaseAcquire> mTransferSize; // count of received bytes
 
     // After a 304/204 or other "no-content" style response we will skip over
     // up to MAX_INVALID_RESPONSE_BODY_SZ bytes when looking for the next
     // response header to deal with servers that actually sent a response
     // body where they should not have. This member tracks how many bytes have
     // so far been skipped.
     uint32_t                        mInvalidResponseBytesRead;
 
--- a/toolkit/components/telemetry/Histograms.json
+++ b/toolkit/components/telemetry/Histograms.json
@@ -2347,16 +2347,25 @@
     "expires_in_version": "never",
     "kind": "exponential",
     "high": 16384,
     "n_buckets": 100,
     "description": "HPACK: peak size in bytes of the table",
     "alert_emails": ["necko@mozilla.com", "hurley@mozilla.com"],
     "bug_numbers": [1296280]
   },
+  "HTTP_CHANNEL_DISPOSITION" : {
+    "alert_emails": ["necko@mozilla.com"],
+    "bug_numbers": [1341128],
+    "expires_in_version": "60",
+    "kind": "enumerated",
+    "n_values": 16,
+    "releaseChannelCollection": "opt-out",
+    "description": "Channel Disposition: 0=Cancel, 1=Disk, 2=NetOK, 3=NetEarlyFail, 4=NetlateFail, +8 for HTTPS"
+  },
   "HTTP_CONNECTION_ENTRY_CACHE_HIT_1" : {
     "expires_in_version": "never",
     "kind": "boolean",
     "description": "Fraction of sockets that used a nsConnectionEntry with history - size 300."
   },
   "HTTP_CACHE_DISPOSITION_2": {
     "expires_in_version": "never",
     "kind": "enumerated",