Bug 1357682 - Part 2, add telemetry for HTTPChannelChild OMT success/fail rate and reason. r=mcmanus data-r=bsmedberg
In order to identify how HTTP OMT is used in user environment, I add a telemetry HTTP_CHILD_OMT_STATS
to record the success and fail reason for each HttpChannelChild.
- "success": OMT request is accepted and the target thread is not main thread.
- "successMainThread": OMT request is accepted but the target thread is still main thread.
- "failListener": OMT request is rejected by the direct listener of this channel.
- "failListenerChain": OMT request is rejected by one of the listener in the listener chain.
- "notRequested": HTTP OMT is not requested by the channel owner.
MozReview-Commit-ID: 1Gif1oteOOh
--- a/netwerk/protocol/http/HttpChannelChild.cpp
+++ b/netwerk/protocol/http/HttpChannelChild.cpp
@@ -20,16 +20,17 @@
#include "mozilla/net/NeckoChild.h"
#include "mozilla/net/HttpChannelChild.h"
#include "AltDataOutputStreamChild.h"
#include "HttpBackgroundChannelChild.h"
#include "nsCOMPtr.h"
#include "nsISupportsPrimitives.h"
#include "nsChannelClassifier.h"
+#include "nsContentPolicyUtils.h"
#include "nsGlobalWindow.h"
#include "nsStringStream.h"
#include "nsHttpChannel.h"
#include "nsHttpHandler.h"
#include "nsNetUtil.h"
#include "nsSerializationHelper.h"
#include "mozilla/Attributes.h"
#include "mozilla/dom/Performance.h"
@@ -1100,16 +1101,39 @@ HttpChannelChild::DoPreOnStopRequest(nsr
{
LOG(("HttpChannelChild::DoPreOnStopRequest [this=%p status=%" PRIx32 "]\n",
this, static_cast<uint32_t>(aStatus)));
mIsPending = false;
if (!mCanceled && NS_SUCCEEDED(mStatus)) {
mStatus = aStatus;
}
+
+ CollectOMTTelemetry();
+}
+
+void
+HttpChannelChild::CollectOMTTelemetry()
+{
+ MOZ_ASSERT(NS_IsMainThread());
+
+ // Only collect telemetry for HTTP channel that is loaded successfully and
+ // completely.
+ if (mCanceled || NS_FAILED(mStatus)) {
+ return;
+ }
+
+ // Use content policy type to accumulate data by usage.
+ nsContentPolicyType type = mLoadInfo ?
+ mLoadInfo->InternalContentPolicyType() :
+ nsIContentPolicy::TYPE_OTHER;
+
+ nsAutoCString key(NS_CP_ContentTypeName(type));
+
+ Telemetry::AccumulateCategoricalKeyed(key, mOMTResult);
}
void
HttpChannelChild::DoOnStopRequest(nsIRequest* aRequest, nsresult aChannelStatus, nsISupports* aContext)
{
LOG(("HttpChannelChild::DoOnStopRequest [this=%p]\n", this));
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(!mIsPending);
@@ -3256,39 +3280,44 @@ HttpChannelChild::RetargetDeliveryTo(nsI
MOZ_ASSERT(NS_IsMainThread(), "Should be called on main thread only");
MOZ_ASSERT(!mODATarget);
MOZ_ASSERT(aNewTarget);
NS_ENSURE_ARG(aNewTarget);
if (aNewTarget->IsOnCurrentThread()) {
NS_WARNING("Retargeting delivery to same thread");
+ mOMTResult = LABELS_HTTP_CHILD_OMT_STATS::successMainThread;
return NS_OK;
}
// Ensure that |mListener| and any subsequent listeners can be retargeted
// to another thread.
nsresult rv = NS_OK;
nsCOMPtr<nsIThreadRetargetableStreamListener> retargetableListener =
do_QueryInterface(mListener, &rv);
if (!retargetableListener || NS_FAILED(rv)) {
NS_WARNING("Listener is not retargetable");
+ mOMTResult = LABELS_HTTP_CHILD_OMT_STATS::failListener;
return NS_ERROR_NO_INTERFACE;
}
rv = retargetableListener->CheckListenerChain();
if (NS_FAILED(rv)) {
NS_WARNING("Subsequent listeners are not retargetable");
+ mOMTResult = LABELS_HTTP_CHILD_OMT_STATS::failListenerChain;
return rv;
}
{
MutexAutoLock lock(mEventTargetMutex);
mODATarget = aNewTarget;
}
+
+ mOMTResult = LABELS_HTTP_CHILD_OMT_STATS::success;
return NS_OK;
}
void
HttpChannelChild::ResetInterception()
{
NS_ENSURE_TRUE_VOID(gNeckoChild != nullptr);
--- a/netwerk/protocol/http/HttpChannelChild.h
+++ b/netwerk/protocol/http/HttpChannelChild.h
@@ -4,16 +4,17 @@
/* 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/. */
#ifndef mozilla_net_HttpChannelChild_h
#define mozilla_net_HttpChannelChild_h
#include "mozilla/Mutex.h"
+#include "mozilla/Telemetry.h"
#include "mozilla/UniquePtr.h"
#include "mozilla/net/HttpBaseChannel.h"
#include "mozilla/net/NeckoTargetHolder.h"
#include "mozilla/net/PHttpChannelChild.h"
#include "mozilla/net/ChannelEventQueue.h"
#include "nsIStreamListener.h"
#include "nsILoadGroup.h"
@@ -29,16 +30,18 @@
#include "nsIAsyncVerifyRedirectCallback.h"
#include "nsIAssociatedContentSecurity.h"
#include "nsIChildChannel.h"
#include "nsIHttpChannelChild.h"
#include "nsIDivertableChannel.h"
#include "nsIThreadRetargetableRequest.h"
#include "mozilla/net/DNS.h"
+using mozilla::Telemetry::LABELS_HTTP_CHILD_OMT_STATS;
+
class nsIEventTarget;
class nsInputStreamPump;
namespace mozilla {
namespace net {
class HttpBackgroundChannelChild;
class InterceptedChannelContent;
@@ -414,16 +417,23 @@ private:
// Perform a redirection without communicating with the parent process at all.
void BeginNonIPCRedirect(nsIURI* responseURI,
const nsHttpResponseHead* responseHead);
// Override the default security info pointer during a non-IPC redirection.
void OverrideSecurityInfoForNonIPCRedirect(nsISupports* securityInfo);
+ // Collect telemetry for the successful rate of OMT.
+ void CollectOMTTelemetry();
+
+ // The result of RetargetDeliveryTo for this channel.
+ // |notRequested| represents OMT is not requested by the channel owner.
+ LABELS_HTTP_CHILD_OMT_STATS mOMTResult = LABELS_HTTP_CHILD_OMT_STATS::notRequested;
+
friend class AssociateApplicationCacheEvent;
friend class StartRequestEvent;
friend class StopRequestEvent;
friend class TransportAndDataEvent;
friend class MaybeDivertOnDataHttpEvent;
friend class MaybeDivertOnStopHttpEvent;
friend class ProgressEvent;
friend class StatusEvent;
--- a/toolkit/components/telemetry/Histograms.json
+++ b/toolkit/components/telemetry/Histograms.json
@@ -2477,16 +2477,26 @@
"alert_emails": ["rbarnes@mozilla.com"],
"bug_numbers": [1266571],
"expires_in_version": "52",
"kind": "enumerated",
"n_values": 8,
"releaseChannelCollection": "opt-out",
"description": "Recorded once for each HTTP 401 response. The value records the type of authentication and the TLS-enabled status. (0=basic/clear, 1=basic/tls, 2=digest/clear, 3=digest/tls, 4=ntlm/clear, 5=ntlm/tls, 6=negotiate/clear, 7=negotiate/tls)"
},
+ "HTTP_CHILD_OMT_STATS": {
+ "record_in_processes": ["content"],
+ "alert_emails": ["necko@mozilla.com"],
+ "bug_numbers": [1357682],
+ "expires_in_version": "61",
+ "kind": "categorical",
+ "keyed": true,
+ "description": "Stats about success rate of HTTP OMT request in content process, keyed by content policy.",
+ "labels": ["success", "successMainThread", "failListener", "failListenerChain", "notRequested"]
+ },
"TCP_FAST_OPEN": {
"record_in_processes": ["main", "content"],
"expires_in_version": "61",
"kind": "enumerated",
"n_values": 8,
"description": "When a http connection is closed, track whether or not TCP Fast Open was used: 0=TFO_NOT_TRIED, 1=TFO_TRIED_NEGOTIATING, 2=TFO_DATA_SENT, 3=TFO_FAILED.",
"alert_emails": ["necko@mozilla.com"],
"bug_numbers": [1352271]