Bug 1489252 - Part 2: Add a telemetry probe for measuring the rate at which popular analytics providers get blocked by fastblock for top-level documents; r=baku,mayhemer,chutten data-r=liuche

Differential Revision: https://phabricator.services.mozilla.com/D5296
This commit is contained in:
Ehsan Akhgari 2018-09-07 14:43:11 -04:00
Родитель 2012a895a1
Коммит d3787265b1
12 изменённых файлов: 189 добавлений и 20 удалений

Просмотреть файл

@ -1673,6 +1673,20 @@ nsDocument::~nsDocument()
ScalarAdd(Telemetry::ScalarID::MEDIA_PAGE_HAD_PLAY_REVOKED_COUNT, 1);
}
}
// Report the fastblock telemetry probes when the document is dying if
// fastblock is enabled and we're not a private document. We always report
// the all probe, and for the rest, report each category's probe depending
// on whether the respective bit has been set in our enum set.
if (StaticPrefs::browser_contentblocking_enabled() &&
StaticPrefs::browser_fastblock_enabled() &&
!nsContentUtils::IsInPrivateBrowsing(this)) {
for (auto label : mTrackerBlockedReasons) {
AccumulateCategorical(label);
}
// Always accumulate the "all" probe since we will use it as a baseline counter.
AccumulateCategorical(Telemetry::LABELS_DOCUMENT_ANALYTICS_TRACKER_FASTBLOCKED::all);
}
}
ReportUseCounters();

Просмотреть файл

@ -45,6 +45,7 @@
#include "mozilla/CORSMode.h"
#include "mozilla/dom/DispatcherTrait.h"
#include "mozilla/dom/DocumentOrShadowRoot.h"
#include "mozilla/EnumSet.h"
#include "mozilla/LinkedList.h"
#include "mozilla/NotNull.h"
#include "mozilla/SegmentedVector.h"
@ -3696,6 +3697,13 @@ public:
++mNumTrackersBlocked;
}
void NoteTrackerBlockedReason(
mozilla::Telemetry::LABELS_DOCUMENT_ANALYTICS_TRACKER_FASTBLOCKED aLabel)
{
MOZ_ASSERT(!GetSameTypeParentDocument());
mTrackerBlockedReasons += aLabel;
}
uint32_t NumTrackersFound()
{
MOZ_ASSERT(!GetSameTypeParentDocument() || mNumTrackersFound == 0);
@ -4684,6 +4692,9 @@ protected:
uint32_t mNumTrackersFound;
uint32_t mNumTrackersBlocked;
mozilla::EnumSet<mozilla::Telemetry::LABELS_DOCUMENT_ANALYTICS_TRACKER_FASTBLOCKED>
mTrackerBlockedReasons;
// document lightweight theme for use with :-moz-lwtheme, :-moz-lwtheme-brighttext
// and :-moz-lwtheme-darktext
DocumentTheme mDocLWTheme;

Просмотреть файл

@ -635,6 +635,7 @@ LoadInfoToParentLoadInfoForwarder(nsILoadInfo* aLoadInfo,
false, // serviceWorkerTaintingSynthesized
false, // isTracker
false, // isTrackerBlocked
mozilla::Telemetry::LABELS_DOCUMENT_ANALYTICS_TRACKER_FASTBLOCKED::all, // trackerBlockedReason
false // documentHasUserInteracted
);
return;
@ -649,6 +650,10 @@ LoadInfoToParentLoadInfoForwarder(nsILoadInfo* aLoadInfo,
uint32_t tainting = nsILoadInfo::TAINTING_BASIC;
Unused << aLoadInfo->GetTainting(&tainting);
mozilla::Telemetry::LABELS_DOCUMENT_ANALYTICS_TRACKER_FASTBLOCKED label =
mozilla::Telemetry::LABELS_DOCUMENT_ANALYTICS_TRACKER_FASTBLOCKED::all;
Unused << aLoadInfo->GetTrackerBlockedReason(&label);
*aForwarderArgsOut = ParentLoadInfoForwarderArgs(
aLoadInfo->GetAllowInsecureRedirectToDataURI(),
ipcController,
@ -656,6 +661,7 @@ LoadInfoToParentLoadInfoForwarder(nsILoadInfo* aLoadInfo,
aLoadInfo->GetServiceWorkerTaintingSynthesized(),
aLoadInfo->GetIsTracker(),
aLoadInfo->GetIsTrackerBlocked(),
label,
aLoadInfo->GetDocumentHasUserInteracted()
);
}
@ -690,6 +696,7 @@ MergeParentLoadInfoForwarder(ParentLoadInfoForwarderArgs const& aForwarderArgs,
MOZ_ALWAYS_SUCCEEDS(aLoadInfo->SetIsTracker(aForwarderArgs.isTracker()));
MOZ_ALWAYS_SUCCEEDS(aLoadInfo->SetIsTrackerBlocked(aForwarderArgs.isTrackerBlocked()));
MOZ_ALWAYS_SUCCEEDS(aLoadInfo->SetTrackerBlockedReason(aForwarderArgs.trackerBlockedReason()));
MOZ_ALWAYS_SUCCEEDS(aLoadInfo->SetDocumentHasUserInteracted(aForwarderArgs.documentHasUserInteracted()));
return NS_OK;

Просмотреть файл

@ -84,6 +84,7 @@ LoadInfo::LoadInfo(nsIPrincipal* aLoadingPrincipal,
, mIsThirdPartyContext(false)
, mIsDocshellReload(false)
, mSendCSPViolationEvents(true)
, mTrackerBlockedReason(mozilla::Telemetry::LABELS_DOCUMENT_ANALYTICS_TRACKER_FASTBLOCKED::all)
, mForcePreflight(false)
, mIsPreflight(false)
, mLoadTriggeredFromExternal(false)
@ -323,6 +324,7 @@ LoadInfo::LoadInfo(nsPIDOMWindowOuter* aOuterWindow,
, mIsThirdPartyContext(false) // NB: TYPE_DOCUMENT implies not third-party.
, mIsDocshellReload(false)
, mSendCSPViolationEvents(true)
, mTrackerBlockedReason(mozilla::Telemetry::LABELS_DOCUMENT_ANALYTICS_TRACKER_FASTBLOCKED::all)
, mForcePreflight(false)
, mIsPreflight(false)
, mLoadTriggeredFromExternal(false)
@ -422,6 +424,7 @@ LoadInfo::LoadInfo(const LoadInfo& rhs)
, mAncestorPrincipals(rhs.mAncestorPrincipals)
, mAncestorOuterWindowIDs(rhs.mAncestorOuterWindowIDs)
, mCorsUnsafeHeaders(rhs.mCorsUnsafeHeaders)
, mTrackerBlockedReason(rhs.mTrackerBlockedReason)
, mForcePreflight(rhs.mForcePreflight)
, mIsPreflight(rhs.mIsPreflight)
, mLoadTriggeredFromExternal(rhs.mLoadTriggeredFromExternal)
@ -514,6 +517,7 @@ LoadInfo::LoadInfo(nsIPrincipal* aLoadingPrincipal,
, mAncestorPrincipals(std::move(aAncestorPrincipals))
, mAncestorOuterWindowIDs(aAncestorOuterWindowIDs)
, mCorsUnsafeHeaders(aCorsUnsafeHeaders)
, mTrackerBlockedReason(mozilla::Telemetry::LABELS_DOCUMENT_ANALYTICS_TRACKER_FASTBLOCKED::all)
, mForcePreflight(aForcePreflight)
, mIsPreflight(aIsPreflight)
, mLoadTriggeredFromExternal(aLoadTriggeredFromExternal)
@ -1373,6 +1377,21 @@ LoadInfo::SetIsTrackerBlocked(bool aIsTrackerBlocked)
return NS_OK;
}
NS_IMETHODIMP
LoadInfo::GetTrackerBlockedReason(mozilla::Telemetry::LABELS_DOCUMENT_ANALYTICS_TRACKER_FASTBLOCKED *aLabel)
{
MOZ_ASSERT(aLabel);
*aLabel = mTrackerBlockedReason;
return NS_OK;
}
NS_IMETHODIMP
LoadInfo::SetTrackerBlockedReason(mozilla::Telemetry::LABELS_DOCUMENT_ANALYTICS_TRACKER_FASTBLOCKED aLabel)
{
mTrackerBlockedReason = aLabel;
return NS_OK;
}
NS_IMETHODIMP
LoadInfo::GetDocumentHasUserInteracted(bool *aDocumentHasUserInteracted)
{

Просмотреть файл

@ -205,6 +205,9 @@ private:
nsTArray<nsCOMPtr<nsIPrincipal>> mAncestorPrincipals;
nsTArray<uint64_t> mAncestorOuterWindowIDs;
nsTArray<nsCString> mCorsUnsafeHeaders;
mozilla::Telemetry::LABELS_DOCUMENT_ANALYTICS_TRACKER_FASTBLOCKED mTrackerBlockedReason;
bool mForcePreflight;
bool mIsPreflight;
bool mLoadTriggeredFromExternal;

Просмотреть файл

@ -19,6 +19,7 @@ native LoadContextRef(already_AddRefed<nsISupports>);
#include "mozilla/BasePrincipal.h"
#include "mozilla/LoadTainting.h"
#include "mozilla/UniquePtr.h"
#include "mozilla/TelemetryHistogramEnums.h"
#include "nsStringFwd.h"
namespace mozilla {
@ -31,6 +32,7 @@ class ServiceWorkerDescriptor;
} // namespace mozilla
%}
native AnalyticsProvider(mozilla::Telemetry::LABELS_DOCUMENT_ANALYTICS_TRACKER_FASTBLOCKED);
[ref] native nsIRedirectHistoryEntryArray(const nsTArray<nsCOMPtr<nsIRedirectHistoryEntry>>);
native OriginAttributes(mozilla::OriginAttributes);
[ref] native const_OriginAttributesRef(const mozilla::OriginAttributes);
@ -1058,6 +1060,7 @@ interface nsILoadInfo : nsISupports
*/
[infallible] attribute boolean isTracker;
[infallible] attribute boolean isTrackerBlocked;
attribute AnalyticsProvider trackerBlockedReason;
/**
* The top-level document has been user-interacted.

Просмотреть файл

@ -21,6 +21,7 @@ using RequestHeaderTuples from "mozilla/net/PHttpChannelParams.h";
using struct nsHttpAtom from "nsHttp.h";
using class mozilla::net::nsHttpResponseHead from "nsHttpResponseHead.h";
using class mozilla::TimeStamp from "mozilla/TimeStamp.h";
using Telemetry::LABELS_DOCUMENT_ANALYTICS_TRACKER_FASTBLOCKED from "DocumentAnalyticsTrackerFastBlocked.h";
namespace mozilla {
namespace net {
@ -147,6 +148,7 @@ struct ParentLoadInfoForwarderArgs
// Tracker information, currently used by FastBlock
bool isTracker;
bool isTrackerBlocked;
LABELS_DOCUMENT_ANALYTICS_TRACKER_FASTBLOCKED trackerBlockedReason;
bool documentHasUserInteracted;
// IMPORTANT: when you add new properites here you must also update

Просмотреть файл

@ -0,0 +1,25 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/* vim:set ts=4 sw=4 sts=4 et cin: */
/* 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 DocumentAnalyticsTrackerFastBlocked_h__
#define DocumentAnalyticsTrackerFastBlocked_h__
#include "ipc/IPCMessageUtils.h"
#include "mozilla/TelemetryHistogramEnums.h"
namespace IPC {
template <>
struct ParamTraits<mozilla::Telemetry::LABELS_DOCUMENT_ANALYTICS_TRACKER_FASTBLOCKED> :
public ContiguousEnumSerializer<mozilla::Telemetry::LABELS_DOCUMENT_ANALYTICS_TRACKER_FASTBLOCKED,
mozilla::Telemetry::LABELS_DOCUMENT_ANALYTICS_TRACKER_FASTBLOCKED::other,
(mozilla::Telemetry::LABELS_DOCUMENT_ANALYTICS_TRACKER_FASTBLOCKED)
(uint32_t(mozilla::Telemetry::LABELS_DOCUMENT_ANALYTICS_TRACKER_FASTBLOCKED::all) + 1)>
{};
}
#endif

Просмотреть файл

@ -759,6 +759,11 @@ HttpChannelChild::DoOnStartRequest(nsIRequest* aRequest, nsISupports* aContext)
doc->IncrementTrackerCount();
if (isTrackerBlocked) {
doc->IncrementTrackerBlockedCount();
Telemetry::LABELS_DOCUMENT_ANALYTICS_TRACKER_FASTBLOCKED label =
Telemetry::LABELS_DOCUMENT_ANALYTICS_TRACKER_FASTBLOCKED::other;
MOZ_ALWAYS_SUCCEEDS(mLoadInfo->GetTrackerBlockedReason(&label));
doc->NoteTrackerBlockedReason(label);
}
}
}

Просмотреть файл

@ -27,6 +27,7 @@ XPIDL_SOURCES += [
XPIDL_MODULE = 'necko_http'
EXPORTS += [
'DocumentAnalyticsTrackerFastBlocked.h',
'nsCORSListenerProxy.h',
'nsHttp.h',
'nsHttpAtomList.h',

Просмотреть файл

@ -162,6 +162,24 @@ enum CacheDisposition {
kCacheMissed = 4
};
using mozilla::Telemetry::LABELS_DOCUMENT_ANALYTICS_TRACKER_FASTBLOCKED;
static const struct {
LABELS_DOCUMENT_ANALYTICS_TRACKER_FASTBLOCKED mTelemetryLabel;
const char* mHostName;
} gFastBlockAnalyticsProviders[] = {
{ LABELS_DOCUMENT_ANALYTICS_TRACKER_FASTBLOCKED::googleanalytics, "google-analytics.com" },
{ LABELS_DOCUMENT_ANALYTICS_TRACKER_FASTBLOCKED::scorecardresearch, "scorecardresearch.com" },
{ LABELS_DOCUMENT_ANALYTICS_TRACKER_FASTBLOCKED::hotjar, "hotjar.com" },
{ LABELS_DOCUMENT_ANALYTICS_TRACKER_FASTBLOCKED::newrelic, "newrelic.com" },
{ LABELS_DOCUMENT_ANALYTICS_TRACKER_FASTBLOCKED::nrdata, "nr-data.net" },
{ LABELS_DOCUMENT_ANALYTICS_TRACKER_FASTBLOCKED::crwdcntrl, "crwdcntrl.net" },
{ LABELS_DOCUMENT_ANALYTICS_TRACKER_FASTBLOCKED::eyeota, "eyeota.net" },
{ LABELS_DOCUMENT_ANALYTICS_TRACKER_FASTBLOCKED::yahooanalytics, "analytics.yahoo.com" },
{ LABELS_DOCUMENT_ANALYTICS_TRACKER_FASTBLOCKED::statcounter, "statcounter.com" },
{ LABELS_DOCUMENT_ANALYTICS_TRACKER_FASTBLOCKED::v12group, "v12group.com" }
};
void
AccumulateCacheHitTelemetry(CacheDisposition hitOrMiss)
{
@ -708,6 +726,13 @@ nsHttpChannel::CheckFastBlocked()
Preferences::AddUintVarCache(&sFastBlockLimit, "browser.fastblock.limit");
}
if (!StaticPrefs::browser_contentblocking_enabled() ||
!StaticPrefs::browser_fastblock_enabled()) {
LOG(("FastBlock disabled by pref [this=%p]\n", this));
return false;
}
TimeStamp timestamp;
if (NS_FAILED(GetNavigationStartTimeStamp(&timestamp)) || !timestamp) {
LOG(("FastBlock passed (no timestamp) [this=%p]\n", this));
@ -715,35 +740,80 @@ nsHttpChannel::CheckFastBlocked()
return false;
}
if (!StaticPrefs::browser_contentblocking_enabled() ||
!StaticPrefs::browser_fastblock_enabled() ||
IsContentPolicyTypeWhitelistedForFastBlock(mLoadInfo) ||
bool engageFastBlock = false;
if (IsContentPolicyTypeWhitelistedForFastBlock(mLoadInfo) ||
// If the user has interacted with the document, we disable fastblock.
(mLoadInfo && mLoadInfo->GetDocumentHasUserInteracted())) {
LOG(("FastBlock passed (invalid) [this=%p]\n", this));
return false;
} else {
TimeDuration duration = TimeStamp::NowLoRes() - timestamp;
bool hasFastBlockStarted = duration.ToMilliseconds() >= sFastBlockTimeout;
bool hasFastBlockStopped = false;
if ((sFastBlockLimit != 0) && (sFastBlockLimit > sFastBlockTimeout)) {
hasFastBlockStopped = duration.ToMilliseconds() > sFastBlockLimit;
}
LOG(("FastBlock started=%d stopped=%d (%lf) [this=%p]\n",
static_cast<int>(hasFastBlockStarted),
static_cast<int>(hasFastBlockStopped),
duration.ToMilliseconds(),
this));
engageFastBlock = hasFastBlockStarted && !hasFastBlockStopped;
}
TimeDuration duration = TimeStamp::NowLoRes() - timestamp;
bool hasFastBlockStarted = duration.ToMilliseconds() >= sFastBlockTimeout;
bool hasFastBlockStopped = false;
if ((sFastBlockLimit != 0) && (sFastBlockLimit > sFastBlockTimeout)) {
hasFastBlockStopped = duration.ToMilliseconds() > sFastBlockLimit;
}
const bool isFastBlocking = hasFastBlockStarted && !hasFastBlockStopped;
// Remember the data needed for fastblock telemetry in case fastblock is
// enabled, we have decided to block the channel, and the channel isn't
// marked as private.
if (engageFastBlock && !NS_UsePrivateBrowsing(this)) {
nsCOMPtr<nsIURI> uri;
nsresult rv = GetURI(getter_AddRefs(uri));
NS_ENSURE_SUCCESS(rv, false);
if (isFastBlocking && mLoadInfo) {
MOZ_ALWAYS_SUCCEEDS(mLoadInfo->SetIsTrackerBlocked(true));
nsAutoCString host;
rv = uri->GetHost(host);
NS_ENSURE_SUCCESS(rv, false);
nsCOMPtr<nsIEffectiveTLDService> tldService =
do_GetService(NS_EFFECTIVETLDSERVICE_CONTRACTID);
NS_ENSURE_TRUE(tldService, false);
LABELS_DOCUMENT_ANALYTICS_TRACKER_FASTBLOCKED label =
LABELS_DOCUMENT_ANALYTICS_TRACKER_FASTBLOCKED::other;
for (const auto& entry : gFastBlockAnalyticsProviders) {
// For each entry in the list of our analytics providers, use the
// effective TLD service to look up subdomains to make sure we find a
// potential match if one is available.
while (true) {
if (host == entry.mHostName) {
label = entry.mTelemetryLabel;
break;
}
nsAutoCString newHost;
rv = tldService->GetNextSubDomain(host, newHost);
if (rv == NS_ERROR_INSUFFICIENT_DOMAIN_LEVELS) {
// we're done searching this entry.
break;
}
NS_ENSURE_SUCCESS(rv, false);
host = newHost;
}
if (label != LABELS_DOCUMENT_ANALYTICS_TRACKER_FASTBLOCKED::other) {
// We have found a label in the previous loop, bail out now!
break;
}
}
if (mLoadInfo) {
MOZ_ALWAYS_SUCCEEDS(mLoadInfo->SetIsTrackerBlocked(true));
MOZ_ALWAYS_SUCCEEDS(mLoadInfo->SetTrackerBlockedReason(label));
}
}
LOG(("FastBlock started=%d stopped=%d (%lf) [this=%p]\n",
static_cast<int>(hasFastBlockStarted),
static_cast<int>(hasFastBlockStopped),
duration.ToMilliseconds(),
this));
return isFastBlocking;
return engageFastBlock;
}
nsresult

Просмотреть файл

@ -503,6 +503,15 @@
"bug_numbers": [1135408],
"description": "GPU Device Reset Reason (ok, hung, removed, reset, internal error, invalid call, out of memory)"
},
"DOCUMENT_ANALYTICS_TRACKER_FASTBLOCKED": {
"record_in_processes": ["content"],
"expires_in_version": "67",
"alert_emails": ["seceng-telemetry@mozilla.com", "fxprivacyandsecurity@mozilla.com"],
"kind": "categorical",
"labels": ["other", "googleanalytics", "scorecardresearch", "hotjar", "newrelic", "nrdata", "crwdcntrl", "eyeota", "yahooanalytics", "statcounter", "v12group", "all"],
"bug_numbers": [1489252],
"description": "Number of top-level documents which have resources blocked by fastblock, categorized by analytics provider."
},
"FETCH_IS_MAINTHREAD": {
"record_in_processes": ["main", "content"],
"expires_in_version": "50",