mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-23 12:51:06 +00:00
Backed out 7 changesets (bug 1852098) for causing build bustages in UseCounterMetrics.cpp. CLOSED TREE
Backed out changeset 2caabd4bfe86 (bug 1852098) Backed out changeset 5c174b0ee1ab (bug 1852098) Backed out changeset 05ba23510b93 (bug 1852098) Backed out changeset 256984effaa2 (bug 1852098) Backed out changeset 8bed08cf2a68 (bug 1852098) Backed out changeset 16b0698a239d (bug 1852098) Backed out changeset 6e8d54a51fb7 (bug 1852098)
This commit is contained in:
parent
3dc8d2660f
commit
1a7724cfd6
@ -232,7 +232,6 @@
|
||||
#include "mozilla/dom/TreeOrderedArrayInlines.h"
|
||||
#include "mozilla/dom/TreeWalker.h"
|
||||
#include "mozilla/dom/URL.h"
|
||||
#include "mozilla/dom/UseCounterMetrics.h"
|
||||
#include "mozilla/dom/UserActivation.h"
|
||||
#include "mozilla/dom/WindowBinding.h"
|
||||
#include "mozilla/dom/WindowContext.h"
|
||||
@ -16152,7 +16151,6 @@ void Document::ReportDocumentUseCounters() {
|
||||
// TOP_LEVEL_CONTENT_DOCUMENTS_DESTROYED is recorded in
|
||||
// WindowGlobalParent::FinishAccumulatingPageUseCounters.
|
||||
Telemetry::Accumulate(Telemetry::CONTENT_DOCUMENTS_DESTROYED, 1);
|
||||
glean::use_counter::content_documents_destroyed.Add();
|
||||
|
||||
// Ask all of our resource documents to report their own document use
|
||||
// counters.
|
||||
@ -16185,7 +16183,6 @@ void Document::ReportDocumentUseCounters() {
|
||||
Telemetry::GetHistogramName(id), urlForLogging->get());
|
||||
}
|
||||
Telemetry::Accumulate(id, 1);
|
||||
IncrementUseCounter(uc, /* aIsPage = */ false);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,31 +0,0 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=8 sts=2 et sw=2 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/. */
|
||||
#ifndef UseCounterMetrics_h_
|
||||
#define UseCounterMetrics_h_
|
||||
|
||||
namespace mozilla::dom {
|
||||
|
||||
enum WorkerKind : uint8_t;
|
||||
|
||||
/**
|
||||
* Increments the metric associated with the specific use counter.
|
||||
*
|
||||
* @param aUseCounter - The use counter for the feature that was used.
|
||||
* @param aIsPage - Whether we should record to the page or document metric.
|
||||
*/
|
||||
void IncrementUseCounter(UseCounter aUseCounter, bool aIsPage);
|
||||
|
||||
/**
|
||||
* Increments the metric associated with the specific worker use counter.
|
||||
*
|
||||
* @param aUseCounter - The use counter for the feature that was used.
|
||||
* @param aKind - The kind of worker that triggered the use counter.
|
||||
*/
|
||||
void IncrementWorkerUseCounter(UseCounterWorker aUseCounter, WorkerKind aKind);
|
||||
|
||||
} // namespace mozilla::dom
|
||||
|
||||
#endif // UseCounterMetrics_h_
|
@ -1,21 +0,0 @@
|
||||
# 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/.
|
||||
|
||||
from mach.decorators import Command
|
||||
|
||||
|
||||
@Command(
|
||||
"gen-use-counter-metrics",
|
||||
category="misc",
|
||||
description="Generate a Glean use_counter_metrics.yaml file, creating metrics definitions for every use counter.",
|
||||
)
|
||||
def gen_use_counter_metrics(command_context):
|
||||
# Dispatch to usecounters.py
|
||||
import sys
|
||||
from os import path
|
||||
|
||||
sys.path.append(path.dirname(__file__))
|
||||
from usecounters import gen_use_counter_metrics
|
||||
|
||||
return gen_use_counter_metrics()
|
@ -283,7 +283,6 @@ EXPORTS.mozilla.dom += [
|
||||
"TreeOrderedArrayInlines.h",
|
||||
"TreeWalker.h",
|
||||
"UIDirectionManager.h",
|
||||
"UseCounterMetrics.h",
|
||||
"UserActivation.h",
|
||||
"ViewportMetaData.h",
|
||||
"VisualViewport.h",
|
||||
@ -308,7 +307,6 @@ if CONFIG["COMPILE_ENVIRONMENT"]:
|
||||
)
|
||||
|
||||
UNIFIED_SOURCES += [
|
||||
"!UseCounterMetrics.cpp",
|
||||
"AbstractRange.cpp",
|
||||
"AnchorAreaFormRelValues.cpp",
|
||||
"AnimationFrameProvider.cpp",
|
||||
@ -619,16 +617,3 @@ GeneratedFile(
|
||||
entry_point="use_counter_list",
|
||||
inputs=["UseCountersWorker.conf"],
|
||||
)
|
||||
|
||||
GeneratedFile(
|
||||
"UseCounterMetrics.cpp",
|
||||
script="usecounters.py",
|
||||
entry_point="metric_map",
|
||||
inputs=[
|
||||
"UseCounters.conf",
|
||||
"UseCountersWorker.conf",
|
||||
"nsDeprecatedOperationList.h",
|
||||
"!/layout/style/ServoCSSPropList.py",
|
||||
"/servo/components/style/properties/counted_unknown_properties.py",
|
||||
],
|
||||
)
|
||||
|
@ -72,7 +72,6 @@
|
||||
#include "mozilla/CORSMode.h"
|
||||
#include "mozilla/CallState.h"
|
||||
#include "mozilla/CheckedInt.h"
|
||||
#include "mozilla/ClearOnShutdown.h"
|
||||
#include "mozilla/Components.h"
|
||||
#include "mozilla/ContentBlockingAllowList.h"
|
||||
#include "mozilla/CycleCollectedJSContext.h"
|
||||
@ -110,7 +109,6 @@
|
||||
#include "mozilla/Result.h"
|
||||
#include "mozilla/ResultExtensions.h"
|
||||
#include "mozilla/ScrollbarPreferences.h"
|
||||
#include "mozilla/ShutdownPhase.h"
|
||||
#include "mozilla/Span.h"
|
||||
#include "mozilla/StaticAnalysisFunctions.h"
|
||||
#include "mozilla/StaticPrefs_browser.h"
|
||||
@ -201,7 +199,6 @@
|
||||
#include "mozilla/dom/WorkerPrivate.h"
|
||||
#include "mozilla/dom/WorkerRunnable.h"
|
||||
#include "mozilla/dom/XULCommandEvent.h"
|
||||
#include "mozilla/glean/GleanPings.h"
|
||||
#include "mozilla/fallible.h"
|
||||
#include "mozilla/gfx/2D.h"
|
||||
#include "mozilla/gfx/BaseMargin.h"
|
||||
@ -831,10 +828,6 @@ nsresult nsContentUtils::Init() {
|
||||
|
||||
if (XRE_IsParentProcess()) {
|
||||
AsyncPrecreateStringBundles();
|
||||
|
||||
RunOnShutdown(
|
||||
[&] { glean_pings::UseCounters.Submit("app_shutdown_confirmed"_ns); },
|
||||
ShutdownPhase::AppShutdownConfirmed);
|
||||
}
|
||||
|
||||
RefPtr<UserInteractionObserver> uio = new UserInteractionObserver();
|
||||
|
@ -4,13 +4,42 @@ requestLongerTimeout(2);
|
||||
|
||||
const gHttpTestRoot = "https://example.com/browser/dom/base/test/";
|
||||
|
||||
/**
|
||||
* Enable local telemetry recording for the duration of the tests.
|
||||
*/
|
||||
var gOldContentCanRecord = false;
|
||||
var gOldParentCanRecord = false;
|
||||
add_task(async function test_initialize() {
|
||||
let Telemetry = Cc["@mozilla.org/base/telemetry;1"].getService(
|
||||
Ci.nsITelemetry
|
||||
);
|
||||
gOldParentCanRecord = Telemetry.canRecordExtended;
|
||||
Telemetry.canRecordExtended = true;
|
||||
|
||||
await SpecialPowers.pushPrefEnv({
|
||||
set: [
|
||||
// Because canRecordExtended is a per-process variable, we need to make sure
|
||||
// that all of the pages load in the same content process. Limit the number
|
||||
// of content processes to at most 1 (or 0 if e10s is off entirely).
|
||||
["dom.ipc.processCount", 1],
|
||||
["layout.css.use-counters.enabled", true],
|
||||
["layout.css.use-counters-unimplemented.enabled", true],
|
||||
],
|
||||
});
|
||||
|
||||
gOldContentCanRecord = await SpecialPowers.spawn(
|
||||
gBrowser.selectedBrowser,
|
||||
[],
|
||||
function () {
|
||||
let telemetry = Cc["@mozilla.org/base/telemetry;1"].getService(
|
||||
Ci.nsITelemetry
|
||||
);
|
||||
let old = telemetry.canRecordExtended;
|
||||
telemetry.canRecordExtended = true;
|
||||
return old;
|
||||
}
|
||||
);
|
||||
info("canRecord for content: " + gOldContentCanRecord);
|
||||
});
|
||||
|
||||
add_task(async function () {
|
||||
@ -19,25 +48,14 @@ add_task(async function () {
|
||||
{
|
||||
type: "iframe",
|
||||
filename: "file_use_counter_svg_getElementById.svg",
|
||||
counters: [
|
||||
{
|
||||
name: "SVGSVGELEMENT_GETELEMENTBYID",
|
||||
glean: ["", "svgsvgelementGetelementbyid"],
|
||||
},
|
||||
],
|
||||
counters: [{ name: "SVGSVGELEMENT_GETELEMENTBYID" }],
|
||||
},
|
||||
{
|
||||
type: "iframe",
|
||||
filename: "file_use_counter_svg_currentScale.svg",
|
||||
counters: [
|
||||
{
|
||||
name: "SVGSVGELEMENT_CURRENTSCALE_getter",
|
||||
glean: ["", "svgsvgelementCurrentscaleGetter"],
|
||||
},
|
||||
{
|
||||
name: "SVGSVGELEMENT_CURRENTSCALE_setter",
|
||||
glean: ["", "svgsvgelementCurrentscaleSetter"],
|
||||
},
|
||||
{ name: "SVGSVGELEMENT_CURRENTSCALE_getter" },
|
||||
{ name: "SVGSVGELEMENT_CURRENTSCALE_setter" },
|
||||
],
|
||||
},
|
||||
|
||||
@ -46,22 +64,13 @@ add_task(async function () {
|
||||
filename: "file_use_counter_style.html",
|
||||
counters: [
|
||||
// Check for longhands.
|
||||
{
|
||||
name: "CSS_PROPERTY_BackgroundImage",
|
||||
glean: ["Css", "cssBackgroundImage"],
|
||||
},
|
||||
{ name: "CSS_PROPERTY_BackgroundImage" },
|
||||
// Check for shorthands.
|
||||
{ name: "CSS_PROPERTY_Padding", glean: ["Css", "cssPadding"] },
|
||||
{ name: "CSS_PROPERTY_Padding" },
|
||||
// Check for aliases.
|
||||
{
|
||||
name: "CSS_PROPERTY_MozAppearance",
|
||||
glean: ["Css", "cssMozAppearance"],
|
||||
},
|
||||
{ name: "CSS_PROPERTY_MozAppearance" },
|
||||
// Check for counted unknown properties.
|
||||
{
|
||||
name: "CSS_PROPERTY_WebkitPaddingStart",
|
||||
glean: ["Css", "webkitPaddingStart"],
|
||||
},
|
||||
{ name: "CSS_PROPERTY_WebkitPaddingStart" },
|
||||
],
|
||||
},
|
||||
|
||||
@ -72,25 +81,14 @@ add_task(async function () {
|
||||
{
|
||||
type: "iframe",
|
||||
filename: "file_use_counter_svg_getElementById.svg",
|
||||
counters: [
|
||||
{
|
||||
name: "SVGSVGELEMENT_GETELEMENTBYID",
|
||||
glean: ["", "svgsvgelementGetelementbyid"],
|
||||
},
|
||||
],
|
||||
counters: [{ name: "SVGSVGELEMENT_GETELEMENTBYID" }],
|
||||
},
|
||||
{
|
||||
type: "iframe",
|
||||
filename: "file_use_counter_svg_currentScale.svg",
|
||||
counters: [
|
||||
{
|
||||
name: "SVGSVGELEMENT_CURRENTSCALE_getter",
|
||||
glean: ["", "svgsvgelementCurrentscaleGetter"],
|
||||
},
|
||||
{
|
||||
name: "SVGSVGELEMENT_CURRENTSCALE_setter",
|
||||
glean: ["", "svgsvgelementCurrentscaleSetter"],
|
||||
},
|
||||
{ name: "SVGSVGELEMENT_CURRENTSCALE_getter" },
|
||||
{ name: "SVGSVGELEMENT_CURRENTSCALE_setter" },
|
||||
],
|
||||
},
|
||||
|
||||
@ -100,12 +98,12 @@ add_task(async function () {
|
||||
{
|
||||
type: "img",
|
||||
filename: "file_use_counter_svg_getElementById.svg",
|
||||
counters: [{ name: "CSS_PROPERTY_Fill", glean: ["Css", "cssFill"] }],
|
||||
counters: [{ name: "CSS_PROPERTY_Fill" }],
|
||||
},
|
||||
{
|
||||
type: "img",
|
||||
filename: "file_use_counter_svg_currentScale.svg",
|
||||
counters: [{ name: "CSS_PROPERTY_Fill", glean: ["Css", "cssFill"] }],
|
||||
counters: [{ name: "CSS_PROPERTY_Fill" }],
|
||||
},
|
||||
|
||||
// Check that use counters are incremented by directly loading SVGs
|
||||
@ -113,13 +111,7 @@ add_task(async function () {
|
||||
{
|
||||
type: "direct",
|
||||
filename: "file_use_counter_svg_fill_pattern.svg",
|
||||
counters: [
|
||||
{
|
||||
name: "CSS_PROPERTY_FillOpacity",
|
||||
glean: ["Css", "cssFillOpacity"],
|
||||
xfail: true,
|
||||
},
|
||||
],
|
||||
counters: [{ name: "CSS_PROPERTY_FillOpacity", xfail: true }],
|
||||
},
|
||||
|
||||
// Check that use counters are incremented by directly loading SVGs
|
||||
@ -127,21 +119,14 @@ add_task(async function () {
|
||||
{
|
||||
type: "direct",
|
||||
filename: "file_use_counter_svg_fill_pattern_internal.svg",
|
||||
counters: [
|
||||
{ name: "CSS_PROPERTY_FillOpacity", glean: ["Css", "cssFillOpacity"] },
|
||||
],
|
||||
counters: [{ name: "CSS_PROPERTY_FillOpacity" }],
|
||||
},
|
||||
|
||||
// Check that use counters are incremented in a display:none iframe.
|
||||
{
|
||||
type: "undisplayed-iframe",
|
||||
filename: "file_use_counter_svg_currentScale.svg",
|
||||
counters: [
|
||||
{
|
||||
name: "SVGSVGELEMENT_CURRENTSCALE_getter",
|
||||
glean: ["", "svgsvgelementCurrentscaleGetter"],
|
||||
},
|
||||
],
|
||||
counters: [{ name: "SVGSVGELEMENT_CURRENTSCALE_getter" }],
|
||||
},
|
||||
|
||||
// Check that a document that comes out of the bfcache reports any new use
|
||||
@ -150,12 +135,7 @@ add_task(async function () {
|
||||
type: "direct",
|
||||
filename: "file_use_counter_bfcache.html",
|
||||
waitForExplicitFinish: true,
|
||||
counters: [
|
||||
{
|
||||
name: "SVGSVGELEMENT_GETELEMENTBYID",
|
||||
glean: ["", "svgsvgelementGetelementbyid"],
|
||||
},
|
||||
],
|
||||
counters: [{ name: "SVGSVGELEMENT_GETELEMENTBYID" }],
|
||||
},
|
||||
|
||||
// // data: URLs don't correctly propagate to their referring document yet.
|
||||
@ -178,24 +158,6 @@ add_task(async function () {
|
||||
test.counters.map(c => c.name)
|
||||
);
|
||||
|
||||
await Services.fog.testFlushAllChildren();
|
||||
before.gleanPage = Object.fromEntries(
|
||||
test.counters.map(c => [
|
||||
c.name,
|
||||
Glean[`useCounter${c.glean[0]}Page`][c.glean[1]].testGetValue() ?? 0,
|
||||
])
|
||||
);
|
||||
before.gleanDoc = Object.fromEntries(
|
||||
test.counters.map(c => [
|
||||
c.name,
|
||||
Glean[`useCounter${c.glean[0]}Doc`][c.glean[1]].testGetValue() ?? 0,
|
||||
])
|
||||
);
|
||||
before.glean_docs_destroyed =
|
||||
Glean.useCounter.contentDocumentsDestroyed.testGetValue();
|
||||
before.glean_toplevel_destroyed =
|
||||
Glean.useCounter.topLevelContentDocumentsDestroyed.testGetValue();
|
||||
|
||||
// Load the test file in the new tab, either directly or via
|
||||
// file_use_counter_outer{,_display_none}.html, depending on the test type.
|
||||
let url, targetElement;
|
||||
@ -267,23 +229,6 @@ add_task(async function () {
|
||||
test.counters.map(c => c.name),
|
||||
before.sentinel
|
||||
);
|
||||
await Services.fog.testFlushAllChildren();
|
||||
after.gleanPage = Object.fromEntries(
|
||||
test.counters.map(c => [
|
||||
c.name,
|
||||
Glean[`useCounter${c.glean[0]}Page`][c.glean[1]].testGetValue() ?? 0,
|
||||
])
|
||||
);
|
||||
after.gleanDoc = Object.fromEntries(
|
||||
test.counters.map(c => [
|
||||
c.name,
|
||||
Glean[`useCounter${c.glean[0]}Doc`][c.glean[1]].testGetValue() ?? 0,
|
||||
])
|
||||
);
|
||||
after.glean_docs_destroyed =
|
||||
Glean.useCounter.contentDocumentsDestroyed.testGetValue();
|
||||
after.glean_toplevel_destroyed =
|
||||
Glean.useCounter.topLevelContentDocumentsDestroyed.testGetValue();
|
||||
|
||||
// Compare before and after.
|
||||
for (let counter of test.counters) {
|
||||
@ -300,16 +245,6 @@ add_task(async function () {
|
||||
before.document[name] + value,
|
||||
`document counts for ${name} after are correct`
|
||||
);
|
||||
is(
|
||||
after.gleanPage[name],
|
||||
before.gleanPage[name] + value,
|
||||
`Glean page counts for ${name} are correct`
|
||||
);
|
||||
is(
|
||||
after.gleanDoc[name],
|
||||
before.gleanDoc[name] + value,
|
||||
`Glean document counts for ${name} are correct`
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@ -323,22 +258,12 @@ add_task(async function () {
|
||||
after.toplevel_docs == before.toplevel_docs + 6,
|
||||
`top level destroyed document counts are correct: ${before.toplevel_docs} vs ${after.toplevel_docs}`
|
||||
);
|
||||
ok(
|
||||
after.glean_toplevel_destroyed == before.glean_toplevel_destroyed + 5 ||
|
||||
after.glean_toplevel_destroyed == before.glean_toplevel_destroyed + 6,
|
||||
`Glean top level destroyed docs counts are correct: ${before.glean_toplevel_destroyed} vs ${after.glean_toplevel_destroyed}`
|
||||
);
|
||||
} else {
|
||||
is(
|
||||
after.toplevel_docs,
|
||||
before.toplevel_docs + 1,
|
||||
"top level destroyed document counts are correct"
|
||||
);
|
||||
is(
|
||||
after.glean_toplevel_destroyed,
|
||||
before.glean_toplevel_destroyed + 1,
|
||||
"Glean top level destroyed document counts are correct"
|
||||
);
|
||||
}
|
||||
|
||||
// 2 documents for "img" tests: one for the outer html page containing the
|
||||
@ -348,14 +273,30 @@ add_task(async function () {
|
||||
after.docs >= before.docs + (test.type == "img" ? 2 : 1),
|
||||
"destroyed document counts are correct"
|
||||
);
|
||||
Assert.greaterOrEqual(
|
||||
after.glean_docs_destroyed,
|
||||
before.glean_docs_destroyed + (test.type == "img" ? 2 : 1),
|
||||
"Glean destroyed doc counts are correct"
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
add_task(async function () {
|
||||
let Telemetry = Cc["@mozilla.org/base/telemetry;1"].getService(
|
||||
Ci.nsITelemetry
|
||||
);
|
||||
Telemetry.canRecordExtended = gOldParentCanRecord;
|
||||
|
||||
await SpecialPowers.spawn(
|
||||
gBrowser.selectedBrowser,
|
||||
[{ oldCanRecord: gOldContentCanRecord }],
|
||||
async function (arg) {
|
||||
await new Promise(resolve => {
|
||||
let telemetry = Cc["@mozilla.org/base/telemetry;1"].getService(
|
||||
Ci.nsITelemetry
|
||||
);
|
||||
telemetry.canRecordExtended = arg.oldCanRecord;
|
||||
resolve();
|
||||
});
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
async function grabHistogramsFromContent(names, prev_sentinel = null) {
|
||||
// We don't have any way to get a notification when telemetry from the
|
||||
// document that was just closed has been reported. So instead, we
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -11,8 +11,8 @@ def read_conf(conf_filename):
|
||||
stream = open(conf_filename, "r")
|
||||
|
||||
def parse_counters(stream):
|
||||
for line_num, full_line in enumerate(stream):
|
||||
line = full_line.rstrip("\n")
|
||||
for line_num, line in enumerate(stream):
|
||||
line = line.rstrip("\n")
|
||||
if not line or line.startswith("//"):
|
||||
# empty line or comment
|
||||
continue
|
||||
@ -87,798 +87,3 @@ def generate_histograms(filename, is_for_worker=False):
|
||||
append_counters(counter["name"].upper(), counter["desc"])
|
||||
|
||||
return items
|
||||
|
||||
|
||||
YAML_HEADER = """\
|
||||
# This file is AUTOGENERATED by usecounters.py. DO NOT EDIT.
|
||||
# (instead, re-run ./mach gen-use-counter-metrics)
|
||||
|
||||
# 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/.
|
||||
|
||||
---
|
||||
$schema: moz://mozilla.org/schemas/glean/metrics/2-0-0
|
||||
$tags:
|
||||
- 'Core :: DOM: Core & HTML'
|
||||
|
||||
"""
|
||||
|
||||
BASE_METRICS = """\
|
||||
use.counter:
|
||||
content_documents_destroyed:
|
||||
type: counter
|
||||
description: >
|
||||
A count of how many content documents were destroyed.
|
||||
Used to turn document use counters' counts into rates.
|
||||
Excludes documents for which we do not count use counters
|
||||
(See `Document::ShouldIncludeInTelemetry`).
|
||||
bugs:
|
||||
- https://bugzilla.mozilla.org/show_bug.cgi?id=1204994
|
||||
- https://bugzilla.mozilla.org/show_bug.cgi?id=1569672
|
||||
- https://bugzilla.mozilla.org/show_bug.cgi?id=1845779
|
||||
- https://bugzilla.mozilla.org/show_bug.cgi?id=1852098
|
||||
data_reviews:
|
||||
- https://bugzilla.mozilla.org/show_bug.cgi?id=1569672
|
||||
notification_emails:
|
||||
- dom-core@mozilla.com
|
||||
- emilio@mozilla.com
|
||||
expires: never
|
||||
send_in_pings:
|
||||
- use-counters
|
||||
|
||||
top_level_content_documents_destroyed:
|
||||
type: counter
|
||||
description: >
|
||||
A count of how many "pages" were destroyed.
|
||||
Used to turn page use counters' counts into rates.
|
||||
Excludes pages that contain only documents for which we do not count use
|
||||
counters (See `Document::ShouldIncludeInTelemetry`).
|
||||
bugs:
|
||||
- https://bugzilla.mozilla.org/show_bug.cgi?id=1204994
|
||||
- https://bugzilla.mozilla.org/show_bug.cgi?id=1569672
|
||||
- https://bugzilla.mozilla.org/show_bug.cgi?id=1845779
|
||||
- https://bugzilla.mozilla.org/show_bug.cgi?id=1852098
|
||||
data_reviews:
|
||||
- https://bugzilla.mozilla.org/show_bug.cgi?id=1569672
|
||||
notification_emails:
|
||||
- dom-core@mozilla.com
|
||||
- emilio@mozilla.com
|
||||
expires: never
|
||||
send_in_pings:
|
||||
- use-counters
|
||||
|
||||
dedicated_workers_destroyed:
|
||||
type: counter
|
||||
description: >
|
||||
A count of how many `Dedicated`-kind workers were destroyed.
|
||||
Used to turn dedicated worker use counters' counts into rates.
|
||||
Excludes chrome workers.
|
||||
bugs:
|
||||
- https://bugzilla.mozilla.org/show_bug.cgi?id=1202706
|
||||
- https://bugzilla.mozilla.org/show_bug.cgi?id=1852098
|
||||
data_reviews:
|
||||
- https://bugzilla.mozilla.org/show_bug.cgi?id=1202706
|
||||
notification_emails:
|
||||
- dom-core@mozilla.com
|
||||
- emilio@mozilla.com
|
||||
expires: never
|
||||
send_in_pings:
|
||||
- use-counters
|
||||
|
||||
shared_workers_destroyed:
|
||||
type: counter
|
||||
description: >
|
||||
A count of how many `Shared`-kind workers were destroyed.
|
||||
Used to turn shared worker use counters' counts into rates.
|
||||
Excludes chrome workers.
|
||||
bugs:
|
||||
- https://bugzilla.mozilla.org/show_bug.cgi?id=1202706
|
||||
- https://bugzilla.mozilla.org/show_bug.cgi?id=1852098
|
||||
data_reviews:
|
||||
- https://bugzilla.mozilla.org/show_bug.cgi?id=1202706
|
||||
notification_emails:
|
||||
- dom-core@mozilla.com
|
||||
- emilio@mozilla.com
|
||||
expires: never
|
||||
send_in_pings:
|
||||
- use-counters
|
||||
|
||||
service_workers_destroyed:
|
||||
type: counter
|
||||
description: >
|
||||
A count of how many `Service`-kind workers were destroyed.
|
||||
Used to turn service worker use counters' counts into rates.
|
||||
Excludes chrome workers.
|
||||
bugs:
|
||||
- https://bugzilla.mozilla.org/show_bug.cgi?id=1202706
|
||||
- https://bugzilla.mozilla.org/show_bug.cgi?id=1852098
|
||||
data_reviews:
|
||||
- https://bugzilla.mozilla.org/show_bug.cgi?id=1202706
|
||||
notification_emails:
|
||||
- dom-core@mozilla.com
|
||||
- emilio@mozilla.com
|
||||
expires: never
|
||||
send_in_pings:
|
||||
- use-counters
|
||||
|
||||
use.counter.error:
|
||||
unknown_counter:
|
||||
type: labeled_counter
|
||||
description: >
|
||||
How many times did we try to increment a use counter we couldn't find?
|
||||
Labeled by what kind of use counter it is.
|
||||
labels:
|
||||
- page
|
||||
- doc
|
||||
- dedicated
|
||||
- shared
|
||||
- service
|
||||
bugs:
|
||||
- https://bugzilla.mozilla.org/show_bug.cgi?id=1852098
|
||||
data_reviews:
|
||||
- https://bugzilla.mozilla.org/show_bug.cgi?id=1852098
|
||||
notification_emails:
|
||||
- dom-core@mozilla.com
|
||||
- chutten@mozilla.com
|
||||
- emilio@mozilla.com
|
||||
expires: never
|
||||
send_in_pings:
|
||||
- use-counters
|
||||
|
||||
"""
|
||||
|
||||
USE_COUNTER_TEMPLATE = """\
|
||||
{name}:
|
||||
type: counter
|
||||
description: >
|
||||
{desc}
|
||||
Compare against `{denominator}`
|
||||
to calculate the rate.
|
||||
bugs:
|
||||
- https://bugzilla.mozilla.org/show_bug.cgi?id=1852098
|
||||
data_reviews:
|
||||
- https://bugzilla.mozilla.org/show_bug.cgi?id=1852098
|
||||
notification_emails:
|
||||
- dom-core@mozilla.com
|
||||
- emilio@mozilla.com
|
||||
expires: never
|
||||
send_in_pings:
|
||||
- use-counters
|
||||
|
||||
"""
|
||||
|
||||
|
||||
def gen_use_counter_metrics():
|
||||
"""
|
||||
Finds use counters in:
|
||||
* dom/base/UseCounters.conf
|
||||
* dom/base/UseCountersWorker.conf
|
||||
* dom/base/nsDeprecatedOperationsList.h
|
||||
* !/layout/style/ServoCSSPropList.py
|
||||
* servo/components/style/properties/counted_unknown_properties.py
|
||||
and overwrites the Glean metrics definition file
|
||||
`dom/base/use_counter_metrics.yaml` with definitions for each use counter found.
|
||||
|
||||
IF YOU CHANGE THIS FUNCTION:
|
||||
* You should probably add your bug's number to USE_COUNTER_TEMPLATE, above.
|
||||
|
||||
Returns 0 on success.
|
||||
"""
|
||||
(
|
||||
page,
|
||||
doc,
|
||||
dedicated,
|
||||
shared,
|
||||
service,
|
||||
ops_page,
|
||||
ops_doc,
|
||||
css_page,
|
||||
css_doc,
|
||||
) = parse_use_counters()
|
||||
import os
|
||||
|
||||
import buildconfig
|
||||
from mozbuild.util import FileAvoidWrite
|
||||
|
||||
yaml_path = os.path.join(
|
||||
buildconfig.topsrcdir, "dom", "base", "use_counter_metrics.yaml"
|
||||
)
|
||||
with FileAvoidWrite(yaml_path) as f:
|
||||
f.write(YAML_HEADER)
|
||||
f.write(BASE_METRICS)
|
||||
|
||||
total = (
|
||||
len(page)
|
||||
+ len(doc)
|
||||
+ len(dedicated)
|
||||
+ len(shared)
|
||||
+ len(service)
|
||||
+ len(ops_page)
|
||||
+ len(ops_doc)
|
||||
+ len(css_page)
|
||||
+ len(css_doc)
|
||||
)
|
||||
f.write(f"# Total of {total} use counter metrics (excludes denominators).\n")
|
||||
f.write(f"# Total of {len(page)} 'page' use counters.\n")
|
||||
f.write("use.counter.page:\n")
|
||||
for [_, name, desc] in page:
|
||||
f.write(
|
||||
USE_COUNTER_TEMPLATE.format(
|
||||
name=name,
|
||||
desc=desc,
|
||||
denominator="use.counter.top_level_content_documents_destroyed",
|
||||
)
|
||||
)
|
||||
|
||||
f.write(f"# Total of {len(doc)} 'document' use counters.\n")
|
||||
f.write("use.counter.doc:\n")
|
||||
for [_, name, desc] in doc:
|
||||
f.write(
|
||||
USE_COUNTER_TEMPLATE.format(
|
||||
name=name,
|
||||
desc=desc,
|
||||
denominator="use.counter.content_documents_destroyed",
|
||||
)
|
||||
)
|
||||
|
||||
f.write(f"# Total of {len(dedicated)} 'dedicated worker' use counters.\n")
|
||||
f.write("use.counter.worker.dedicated:\n")
|
||||
for [_, name, desc] in dedicated:
|
||||
f.write(
|
||||
USE_COUNTER_TEMPLATE.format(
|
||||
name=name,
|
||||
desc=desc,
|
||||
denominator="use.counter.dedicated_workers_destroyed",
|
||||
)
|
||||
)
|
||||
|
||||
f.write(f"# Total of {len(shared)} 'shared worker' use counters.\n")
|
||||
f.write("use.counter.worker.shared:\n")
|
||||
for [_, name, desc] in shared:
|
||||
f.write(
|
||||
USE_COUNTER_TEMPLATE.format(
|
||||
name=name,
|
||||
desc=desc,
|
||||
denominator="use.counter.shared_workers_destroyed",
|
||||
)
|
||||
)
|
||||
|
||||
f.write(f"# Total of {len(service)} 'service worker' use counters.\n")
|
||||
f.write("use.counter.worker.service:\n")
|
||||
for [_, name, desc] in service:
|
||||
f.write(
|
||||
USE_COUNTER_TEMPLATE.format(
|
||||
name=name,
|
||||
desc=desc,
|
||||
denominator="use.counter.service_workers_destroyed",
|
||||
)
|
||||
)
|
||||
|
||||
f.write(
|
||||
f"# Total of {len(ops_page)} 'deprecated operations (page)' use counters.\n"
|
||||
)
|
||||
f.write("use.counter.deprecated_ops.page:\n")
|
||||
for [_, name, desc] in ops_page:
|
||||
f.write(
|
||||
USE_COUNTER_TEMPLATE.format(
|
||||
name=name,
|
||||
desc=desc,
|
||||
denominator="use.counter.top_level_content_documents_destroyed",
|
||||
)
|
||||
)
|
||||
|
||||
f.write(
|
||||
f"# Total of {len(ops_doc)} 'deprecated operations (document)' use counters.\n"
|
||||
)
|
||||
f.write("use.counter.deprecated_ops.doc:\n")
|
||||
for [_, name, desc] in ops_doc:
|
||||
f.write(
|
||||
USE_COUNTER_TEMPLATE.format(
|
||||
name=name,
|
||||
desc=desc,
|
||||
denominator="use.counter.content_documents_destroyed",
|
||||
)
|
||||
)
|
||||
|
||||
f.write(f"# Total of {len(css_page)} 'CSS (page)' use counters.\n")
|
||||
f.write("use.counter.css.page:\n")
|
||||
for [_, name, desc] in css_page:
|
||||
f.write(
|
||||
USE_COUNTER_TEMPLATE.format(
|
||||
name=name,
|
||||
desc=desc,
|
||||
denominator="use.counter.top_level_content_documents_destroyed",
|
||||
)
|
||||
)
|
||||
|
||||
f.write(f"# Total of {len(css_doc)} 'CSS (document)' use counters.\n")
|
||||
f.write("use.counter.css.doc:\n")
|
||||
for [_, name, desc] in css_doc:
|
||||
f.write(
|
||||
USE_COUNTER_TEMPLATE.format(
|
||||
name=name,
|
||||
desc=desc,
|
||||
denominator="use.counter.content_documents_destroyed",
|
||||
)
|
||||
)
|
||||
|
||||
return 0
|
||||
|
||||
|
||||
def parse_use_counters():
|
||||
"""
|
||||
Finds use counters in:
|
||||
* dom/base/UseCounters.conf
|
||||
* dom/base/UseCountersWorker.conf
|
||||
* dom/base/nsDeprecatedOperationsList.h
|
||||
* !/layout/style/ServoCSSPropList.py
|
||||
* servo/components/style/properties/counted_unknown_properties.py
|
||||
and returns them as a tuple of lists of tuples of the form:
|
||||
(page, doc, dedicated, shared, service, ops_page, ops_doc, css_page, css_doc)
|
||||
where each of the items is a List<Tuple<enum_name, glean_name, description>>
|
||||
where `enum_name` is the name of the enum variant from UseCounter.h
|
||||
(like `eUseCounter_custom_CustomizedBuiltin`), and
|
||||
where `glean_name` is the name conjugated to Glean metric name safety.
|
||||
"""
|
||||
|
||||
# Note, this function contains a duplication of enum naming logic from UseCounter.h.
|
||||
# If you change the enum name format, you'll need to do it twice.
|
||||
|
||||
# There are 3 kinds of Use Counters in conf files: method, attribute, custom.
|
||||
# `method` and `attribute` are presumed label-safe and are taken as-is.
|
||||
# `custom` can be any case, so are coerced to snake_case.
|
||||
import os
|
||||
|
||||
import buildconfig
|
||||
|
||||
uc_path = os.path.join(buildconfig.topsrcdir, "dom", "base", "UseCounters.conf")
|
||||
page = []
|
||||
doc = []
|
||||
for counter in read_conf(uc_path):
|
||||
if counter["type"] == "method":
|
||||
enum_name = (
|
||||
f"eUseCounter_{counter['interface_name']}_{counter['method_name']}"
|
||||
)
|
||||
glean_name = f"{counter['interface_name']}_{counter['method_name']}".lower()
|
||||
method = f"called {counter['interface_name']}.{counter['method_name']}"
|
||||
page.append((enum_name, glean_name, f"Whether a page called {method}."))
|
||||
doc.append((enum_name, glean_name, f"Whether a document called {method}."))
|
||||
elif counter["type"] == "attribute":
|
||||
enum_root = (
|
||||
f"eUseCounter_{counter['interface_name']}_{counter['attribute_name']}"
|
||||
)
|
||||
name = f"{counter['interface_name']}_{counter['attribute_name']}".lower()
|
||||
attr = f"{counter['interface_name']}.{counter['attribute_name']}"
|
||||
page.append(
|
||||
(f"{enum_root}_getter", f"{name}_getter", f"Whether a page got {attr}.")
|
||||
)
|
||||
page.append(
|
||||
(f"{enum_root}_setter", f"{name}_setter", f"Whether a page set {attr}.")
|
||||
)
|
||||
doc.append(
|
||||
(
|
||||
f"{enum_root}_getter",
|
||||
f"{name}_getter",
|
||||
f"Whether a document got {attr}.",
|
||||
)
|
||||
)
|
||||
doc.append(
|
||||
(
|
||||
f"{enum_root}_setter",
|
||||
f"{name}_setter",
|
||||
f"Whether a document set {attr}.",
|
||||
)
|
||||
)
|
||||
elif counter["type"] == "custom":
|
||||
enum_name = f"eUseCounter_custom_{counter['name']}"
|
||||
page.append(
|
||||
(
|
||||
enum_name,
|
||||
to_snake_case(counter["name"]),
|
||||
f"Whether a page {counter['desc']}.",
|
||||
)
|
||||
)
|
||||
doc.append(
|
||||
(
|
||||
enum_name,
|
||||
to_snake_case(counter["name"]),
|
||||
f"Whether a document {counter['desc']}.",
|
||||
)
|
||||
)
|
||||
else:
|
||||
print(f"Found unexpected use counter type {counter['type']}. Returning 1.")
|
||||
return 1
|
||||
|
||||
worker_uc_path = os.path.join(
|
||||
buildconfig.topsrcdir, "dom", "base", "UseCountersWorker.conf"
|
||||
)
|
||||
dedicated = []
|
||||
shared = []
|
||||
service = []
|
||||
for counter in read_conf(worker_uc_path):
|
||||
if counter["type"] == "method":
|
||||
enum_name = f"{counter['interface_name']}_{counter['method_name']}"
|
||||
name = f"{counter['interface_name']}_{counter['method_name']}".lower()
|
||||
method = f"called {counter['interface_name']}.{counter['method_name']}"
|
||||
dedicated.append(
|
||||
(enum_name, name, f"Whether a dedicated worker called {method}.")
|
||||
)
|
||||
shared.append(
|
||||
(enum_name, name, f"Whether a shared worker called {method}.")
|
||||
)
|
||||
service.append(
|
||||
(enum_name, name, f"Whether a service worker called {method}.")
|
||||
)
|
||||
elif counter["type"] == "attribute":
|
||||
enum_root = f"{counter['interface_name']}_{counter['attribute_name']}"
|
||||
name = f"{counter['interface_name']}_{counter['attribute_name']}".lower()
|
||||
attr = f"{counter['interface_name']}.{counter['attribute_name']}"
|
||||
dedicated.append(
|
||||
(
|
||||
f"{enum_root}_getter",
|
||||
f"{name}_getter",
|
||||
f"Whether a dedicated worker got {attr}.",
|
||||
)
|
||||
)
|
||||
dedicated.append(
|
||||
(
|
||||
f"{enum_root}_setter",
|
||||
f"{name}_setter",
|
||||
f"Whether a dedicated worker set {attr}.",
|
||||
)
|
||||
)
|
||||
shared.append(
|
||||
(
|
||||
f"{enum_root}_getter",
|
||||
f"{name}_getter",
|
||||
f"Whether a shared worker got {attr}.",
|
||||
)
|
||||
)
|
||||
shared.append(
|
||||
(
|
||||
f"{enum_root}_setter",
|
||||
f"{name}_setter",
|
||||
f"Whether a shared worker set {attr}.",
|
||||
)
|
||||
)
|
||||
service.append(
|
||||
(
|
||||
f"{enum_root}_getter",
|
||||
f"{name}_getter",
|
||||
f"Whether a service worker got {attr}.",
|
||||
)
|
||||
)
|
||||
service.append(
|
||||
(
|
||||
f"{enum_root}_setter",
|
||||
f"{name}_setter",
|
||||
f"Whether a service worker set {attr}.",
|
||||
)
|
||||
)
|
||||
elif counter["type"] == "custom":
|
||||
enum_name = f"Custom_{counter['name']}"
|
||||
dedicated.append(
|
||||
(
|
||||
enum_name,
|
||||
to_snake_case(counter["name"]),
|
||||
f"Whether a dedicated worker {counter['desc']}.",
|
||||
)
|
||||
)
|
||||
shared.append(
|
||||
(
|
||||
enum_name,
|
||||
to_snake_case(counter["name"]),
|
||||
f"Whether a shared worker {counter['desc']}.",
|
||||
)
|
||||
)
|
||||
service.append(
|
||||
(
|
||||
enum_name,
|
||||
to_snake_case(counter["name"]),
|
||||
f"Whether a service worker {counter['desc']}.",
|
||||
)
|
||||
)
|
||||
else:
|
||||
print(
|
||||
f"Found unexpected worker use counter type {counter['type']}. Returning 1."
|
||||
)
|
||||
return 1
|
||||
|
||||
# nsDeprecatedOperationsList.h parsing is adapted from parse_histograms.py.
|
||||
operation_list_path = os.path.join(
|
||||
buildconfig.topsrcdir, "dom", "base", "nsDeprecatedOperationList.h"
|
||||
)
|
||||
operation_regex = re.compile("^DEPRECATED_OPERATION\\(([^)]+)\\)")
|
||||
ops_page = []
|
||||
ops_doc = []
|
||||
with open(operation_list_path) as f:
|
||||
for line in f:
|
||||
match = operation_regex.search(line)
|
||||
if not match:
|
||||
# No macro, probably whitespace or comment.
|
||||
continue
|
||||
|
||||
op = match.group(1)
|
||||
op_name = to_snake_case(op)
|
||||
enum_name = f"eUseCounter_{op}"
|
||||
ops_page.append((enum_name, op_name, f"Whether a page used {op}."))
|
||||
ops_doc.append((enum_name, op_name, f"Whether a document used {op}."))
|
||||
|
||||
# Theoretically, we could do this without a completed build
|
||||
# (ie, without the generated ServoCSSPropList.py) by sourcing direct from
|
||||
# servo/components/style/properties/data.py:PropertiesData(engine=gecko).
|
||||
#
|
||||
# ...but parse_histograms.py doesn't do this the hard way. Should we?
|
||||
|
||||
import runpy
|
||||
|
||||
proplist_path = os.path.join(
|
||||
buildconfig.topobjdir, "layout", "style", "ServoCSSPropList.py"
|
||||
)
|
||||
css_properties = runpy.run_path(proplist_path)["data"]
|
||||
css_page = []
|
||||
css_doc = []
|
||||
for prop in css_properties.values():
|
||||
# We prefix `prop_name` with `css_` to avoid colliding with C++ keywords
|
||||
# like `float`.
|
||||
prop_name = "css_" + to_snake_case(prop.name)
|
||||
|
||||
# Dependency keywords: CSS_PROP_PUBLIC_OR_PRIVATE, GenerateServoCSSPropList.py.
|
||||
method = "Float" if prop.method == "CssFloat" else prop.method
|
||||
# Dependency keywords: CSS_PROP_DOMPROP_PREFIXED, GenerateServoCSSPropList.py.
|
||||
if method.startswith("Moz") and prop.type() != "alias":
|
||||
method = method[3:] # remove the moz prefix
|
||||
|
||||
enum_name = f"eUseCounter_property_{method}"
|
||||
css_page.append(
|
||||
(enum_name, prop_name, f"Whether a page used the CSS property {prop.name}.")
|
||||
)
|
||||
css_doc.append(
|
||||
(
|
||||
enum_name,
|
||||
prop_name,
|
||||
f"Whether a document used the CSS property {prop.name}.",
|
||||
)
|
||||
)
|
||||
|
||||
# Counted unknown properties: AKA - stuff that doesn't exist, but we want
|
||||
# to count uses of anyway.
|
||||
# We _might_ decide to implement these in the future, though, so we just add
|
||||
# them to the css_page, css_doc lists directly for continuity.
|
||||
# (We do give them a different description, though)
|
||||
|
||||
import sys
|
||||
|
||||
sys.path.append(os.path.join(buildconfig.topsrcdir, "layout", "style"))
|
||||
from GenerateCountedUnknownProperties import to_camel_case
|
||||
|
||||
unknown_proplist_path = os.path.join(
|
||||
buildconfig.topsrcdir,
|
||||
"servo",
|
||||
"components",
|
||||
"style",
|
||||
"properties",
|
||||
"counted_unknown_properties.py",
|
||||
)
|
||||
unknown_properties = runpy.run_path(unknown_proplist_path)[
|
||||
"COUNTED_UNKNOWN_PROPERTIES"
|
||||
]
|
||||
for prop in unknown_properties:
|
||||
enum_name = f"eUseCounter_unknown_property_{to_camel_case(prop)}"
|
||||
prop_name = to_snake_case(prop)
|
||||
css_page.append(
|
||||
(
|
||||
enum_name,
|
||||
prop_name,
|
||||
f"Whether a page used the (unknown, counted) CSS property {prop}.",
|
||||
)
|
||||
)
|
||||
css_doc.append(
|
||||
(
|
||||
enum_name,
|
||||
prop_name,
|
||||
f"Whether a document used the (unknown, counted) CSS property {prop}.",
|
||||
)
|
||||
)
|
||||
|
||||
return (page, doc, dedicated, shared, service, ops_page, ops_doc, css_page, css_doc)
|
||||
|
||||
|
||||
def to_snake_case(kebab_or_pascal):
|
||||
"""
|
||||
Takes `kebab_or_pascal` which is in PascalCase or kebab-case
|
||||
and conjugates it to "snake_case" (all lowercase, "_"-delimited).
|
||||
"""
|
||||
return (
|
||||
re.sub("([A-Z]+)", r"_\1", kebab_or_pascal).replace("-", "_").lower().strip("_")
|
||||
)
|
||||
|
||||
|
||||
def metric_map(f, *inputs):
|
||||
"""
|
||||
Parses all use counters and outputs UseCounter.cpp which contains implementations
|
||||
for two functions defined in UseCounter.h:
|
||||
* void IncrementUseCounter(UseCounter aUseCounter, bool aIsPage)
|
||||
* void IncrementWorkerUseCounter(UseCounterWorker aUseCounter, dom::WorkerKind aKind)
|
||||
|
||||
(Basically big switch statements mapping from enums to glean metrics, calling Add())
|
||||
"""
|
||||
|
||||
(
|
||||
page,
|
||||
doc,
|
||||
dedicated,
|
||||
shared,
|
||||
service,
|
||||
ops_page,
|
||||
ops_doc,
|
||||
css_page,
|
||||
css_doc,
|
||||
) = parse_use_counters()
|
||||
|
||||
f.write(
|
||||
"""\
|
||||
/* AUTOGENERATED by usecounters.py. DO NOT EDIT */
|
||||
/* 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/. */
|
||||
|
||||
#include "mozilla/dom/UseCounterMetrics.h"
|
||||
|
||||
#include "mozilla/dom/WorkerPrivate.h"
|
||||
#include "mozilla/glean/GleanMetrics.h"
|
||||
|
||||
namespace mozilla::dom {
|
||||
|
||||
void IncrementUseCounter(UseCounter aUseCounter, bool aIsPage) {
|
||||
if (aIsPage) {
|
||||
switch (aUseCounter) {
|
||||
"""
|
||||
)
|
||||
for uc in page:
|
||||
f.write(
|
||||
f"""\
|
||||
case UseCounter::{uc[0]}:
|
||||
glean::use_counter_page::{uc[1]}.Add();
|
||||
break;
|
||||
"""
|
||||
)
|
||||
|
||||
for uc in ops_page:
|
||||
f.write(
|
||||
f"""\
|
||||
case UseCounter::{uc[0]}:
|
||||
glean::use_counter_deprecated_ops_page::{uc[1]}.Add();
|
||||
break;
|
||||
"""
|
||||
)
|
||||
|
||||
for uc in css_page:
|
||||
f.write(
|
||||
f"""\
|
||||
case UseCounter::{uc[0]}:
|
||||
glean::use_counter_css_page::{uc[1]}.Add();
|
||||
break;
|
||||
"""
|
||||
)
|
||||
|
||||
f.write(
|
||||
"""\
|
||||
default:
|
||||
MOZ_ASSERT_UNREACHABLE("Unknown page usecounter.");
|
||||
glean::use_counter_error::unknown_counter.Get("page"_ns).Add();
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
switch (aUseCounter) {
|
||||
"""
|
||||
)
|
||||
for uc in doc:
|
||||
f.write(
|
||||
f"""\
|
||||
case UseCounter::{uc[0]}:
|
||||
glean::use_counter_doc::{uc[1]}.Add();
|
||||
break;
|
||||
"""
|
||||
)
|
||||
|
||||
for uc in ops_doc:
|
||||
f.write(
|
||||
f"""\
|
||||
case UseCounter::{uc[0]}:
|
||||
glean::use_counter_deprecated_ops_doc::{uc[1]}.Add();
|
||||
break;
|
||||
"""
|
||||
)
|
||||
|
||||
for uc in css_doc:
|
||||
f.write(
|
||||
f"""\
|
||||
case UseCounter::{uc[0]}:
|
||||
glean::use_counter_css_doc::{uc[1]}.Add();
|
||||
break;
|
||||
"""
|
||||
)
|
||||
|
||||
f.write(
|
||||
"""\
|
||||
default:
|
||||
MOZ_ASSERT_UNREACHABLE("Unknown document usecounter.");
|
||||
glean::use_counter_error::unknown_counter.Get("doc"_ns).Add();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void IncrementWorkerUseCounter(UseCounterWorker aUseCounter, WorkerKind aKind) {
|
||||
switch(aKind) {
|
||||
case WorkerKind::WorkerKindDedicated:
|
||||
switch (aUseCounter) {
|
||||
"""
|
||||
)
|
||||
for uc in dedicated:
|
||||
f.write(
|
||||
f"""\
|
||||
case UseCounterWorker::{uc[0]}:
|
||||
glean::use_counter_worker_dedicated::{uc[1]}.Add();
|
||||
break;
|
||||
"""
|
||||
)
|
||||
|
||||
f.write(
|
||||
"""\
|
||||
default:
|
||||
MOZ_ASSERT_UNREACHABLE("Unknown dedicated worker usecounter.");
|
||||
glean::use_counter_error::unknown_counter.Get("dedicated"_ns).Add();
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case WorkerKind::WorkerKindShared:
|
||||
switch (aUseCounter) {
|
||||
"""
|
||||
)
|
||||
for uc in shared:
|
||||
f.write(
|
||||
f"""\
|
||||
case UseCounterWorker::{uc[0]}:
|
||||
glean::use_counter_worker_shared::{uc[1]}.Add();
|
||||
break;
|
||||
"""
|
||||
)
|
||||
|
||||
f.write(
|
||||
"""\
|
||||
default:
|
||||
MOZ_ASSERT_UNREACHABLE("Unknown shared worker usecounter.");
|
||||
glean::use_counter_error::unknown_counter.Get("shared"_ns).Add();
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case WorkerKind::WorkerKindService:
|
||||
switch (aUseCounter) {
|
||||
"""
|
||||
)
|
||||
for uc in service:
|
||||
f.write(
|
||||
f"""\
|
||||
case UseCounterWorker::{uc[0]}:
|
||||
glean::use_counter_worker_service::{uc[1]}.Add();
|
||||
break;
|
||||
"""
|
||||
)
|
||||
|
||||
f.write(
|
||||
"""\
|
||||
default:
|
||||
MOZ_ASSERT_UNREACHABLE("Unknown service worker usecounter.");
|
||||
glean::use_counter_error::unknown_counter.Get("service"_ns).Add();
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace mozilla
|
||||
"""
|
||||
)
|
||||
|
@ -16,4 +16,3 @@ These linked pages contain design documents for the DOM implementation in Gecko.
|
||||
ioutils_migration
|
||||
fedcm
|
||||
streams
|
||||
use-counters
|
||||
|
@ -1,165 +0,0 @@
|
||||
============
|
||||
Use Counters
|
||||
============
|
||||
|
||||
Use counters are used to report statistics on how much a given web platform feature is used across the Web.
|
||||
Supported features include:
|
||||
|
||||
* WebIDL methods and attributes (getters and setters are reported separately) for pages, documents, and workers,
|
||||
* CSS properties (including properties that aren't in the web platform, but we're interested in),
|
||||
* Deprecated DOM operations,
|
||||
* Other things like SVG filters and APIs specifically unsupported in Private Browsing Mode,
|
||||
via custom use counters.
|
||||
|
||||
Adding a new Use Counter
|
||||
========================
|
||||
How you add a new use counter is different depending on what kind of web platform feature you're instrumenting.
|
||||
The one constant is that you must run ``./mach gen-use-counter-metrics``
|
||||
after adding or removing a use counter.
|
||||
|
||||
(Why this is a manual step and not part of the build is explained in
|
||||
`the implementation bug 1852098 <https://bugzilla.mozilla.org/show_bug.cgi?id=1852098#c11>`_.)
|
||||
|
||||
WebIDL Methods and Attributes
|
||||
-----------------------------
|
||||
Use counters for WebIDL Methods and Attributes are added manually by editing
|
||||
:searchfox:`UseCounters.conf <dom/base/UseCounters.conf>` or, for workers,
|
||||
:searchfox:`UseCountersWorker.conf <dom/base/UseCountersWorker.conf>`, and
|
||||
by annotating the WebIDL Method or Attribute with the ``[UseCounter]``
|
||||
extended attribute.
|
||||
|
||||
(Why you must write this in two places is because generating things from
|
||||
bindings codegen and ensuring all the dependencies were correct proved to be
|
||||
rather difficult)
|
||||
|
||||
Then run ``./mach gen-use-counter-metrics`` and build as normal.
|
||||
|
||||
CSS Properties
|
||||
--------------
|
||||
Use counters for CSS properties are automatically generated for every property Gecko supports.
|
||||
|
||||
To add a use counter for a CSS property that isn't supported by Gecko,
|
||||
add it to :searchfox:`counted_unknown_properties.py <servo/components/style/properties/counted_unknown_properties.py>`.
|
||||
|
||||
Then run ``./mach gen-use-counter-metrics`` and build as normal.
|
||||
|
||||
Deprecated DOM operations
|
||||
-------------------------
|
||||
Use counters for deprecated DOM operations are declared in
|
||||
:searchfox:`nsDeprecatedOperationList.h <dom/base/nsDeprecatedOperationList.h>`.
|
||||
To add a use counter for a deprecated DOM operation, you'll add an invocation of the
|
||||
``DEPRECATED_OPERATION(DeprecationReference)`` macro.
|
||||
The provided parameter must have the same value of the deprecation note added to the *IDL* file.
|
||||
|
||||
See `bug 1860635 <https://bugzilla.mozilla.org/show_bug.cgi?id=1860635>`_ for a sample
|
||||
deprecated operation.
|
||||
|
||||
Then run ``./mach gen-use-counter-metrics`` and build as normal.
|
||||
|
||||
Custom use counters
|
||||
-------------------
|
||||
Custom use counters are for counting per-page, per-document, or per-worker
|
||||
uses of web platform features that can't be handled directly through WebIDL annotation.
|
||||
|
||||
For example, the use of specific SVG filters isn't a WebIDL method or attribute,
|
||||
but was still an aspect of the web platform of interest.
|
||||
|
||||
To add a custom use counter, define it in
|
||||
:searchfox:`UseCounters.conf <dom/base/UseCounters.conf>` or, for workers,
|
||||
:searchfox:`UseCountersWorker.conf <dom/base/UseCountersWorker.conf>`
|
||||
by following the instructions in the file.
|
||||
Broadly, you'll be writing a line like ``custom feBlend uses the feBlend SVG filter``.
|
||||
|
||||
Then, by running the build as normal, an enum in ``enum class UseCounter``
|
||||
will be generated for your use counter, which you should pass to
|
||||
``Document::SetUseCounter()`` when it's used.
|
||||
``Document::SetUseCounter()`` is very cheap,
|
||||
so do not be afraid to call it every time the feature is used.
|
||||
|
||||
Take care to craft the description appropriately.
|
||||
It will be appended to "Whether a document " or "Whether a shared worker ",
|
||||
so write only the ending.
|
||||
|
||||
|
||||
The processor scripts
|
||||
=====================
|
||||
The definition files are processed during the build to generate C++ headers
|
||||
included by web platform components (e.g. DOM) that own the features to be tracked.
|
||||
|
||||
The definition files are also processed during ``./mach gen-use-counter-metrics``
|
||||
to generate :searchfox:`use_counter_metrics.yaml <dom/base/use_counter_metrics.yaml>`
|
||||
which generates the necessary Glean metrics for recording and reporting use counter data.
|
||||
|
||||
gen-usecounters.py
|
||||
------------------
|
||||
This script is called by the build system to generate:
|
||||
|
||||
- the ``UseCounterList.h`` header for the WebIDL, out of the definition files.
|
||||
- the ``UseCounterWorkerList.h`` header for the WebIDL, out of the definition files.
|
||||
|
||||
usecounters.py
|
||||
--------------
|
||||
Contains methods for parsing and transforming use counter definition files,
|
||||
as well as the mechanism that outputs the Glean use counter metrics definitions.
|
||||
|
||||
Data Review
|
||||
===========
|
||||
The concept of a Use Counter data collection
|
||||
(being a web platform feature which has the number of pages, documents, workers
|
||||
(of various types), or other broad category of web platform API surfaces that
|
||||
*use* it recorded and reported by a data collection mechanism (like Glean))
|
||||
was approved for opt-out collection in all products using Gecko and Glean in
|
||||
`bug 1852098 <https://bugzilla.mozilla.org/show_bug.cgi?id=1852098>`_.
|
||||
|
||||
As a result,
|
||||
if you are adding new use counter data collections for WebIDL methods or attributes,
|
||||
deprecated operations, or CSS properties:
|
||||
you almost certainly don't need a data collection review.
|
||||
|
||||
If you are adding a custom use counter, you might need a data collection review.
|
||||
The criteria for whether you do or not is whether the custom use counter you're adding
|
||||
can fall under
|
||||
`the over-arching data collection review request <https://bugzilla.mozilla.org/show_bug.cgi?id=1852098>`_.
|
||||
For example: a custom use counter for an SVG filter? Clearly a web platform feature being counted.
|
||||
A custom use counter that solely increments when you visit a social media website?
|
||||
Doesn't seem like it'd be covered, no.
|
||||
|
||||
If unsure, please ask on
|
||||
`the #data-stewards channel on Matrix <https://chat.mozilla.org/#/room/#data-stewards:mozilla.org>`_.
|
||||
|
||||
The Data
|
||||
========
|
||||
Use Counters are, as of Firefox 121, collected using Glean as
|
||||
``counter`` metrics on the "use-counters" ping.
|
||||
They are in a variety of metrics categories of ``use.counter.X``
|
||||
which you can browse on
|
||||
`the Glean Dictionary <https://dictionary.telemetry.mozilla.org/apps/firefox_desktop?page=1&search=use.counter>`_.
|
||||
The dictionary also contains information about how to view the data.
|
||||
|
||||
Interpreting the data
|
||||
---------------------
|
||||
A use counter on its own is minimally useful, as it is solely a count of how many
|
||||
(pages, documents, workers of a specific type, other web platform API surfaces)
|
||||
a given part of the web platform was used on.
|
||||
|
||||
Knowing a feature was encountered ``0`` times across all of Firefox would be useful to know.
|
||||
(If you wanted to remove something).
|
||||
Knowing a feature was encountered *more than* ``0`` times would be useful.
|
||||
(If you wanted to argue against removing something).
|
||||
|
||||
But any other number of, say, pages using a web platform feature is only useful
|
||||
in context with how many total pages were viewed.
|
||||
|
||||
Thus, each use counter has in its description a name of another counter
|
||||
-- a denominator -- to convert the use counter into a usage rate.
|
||||
|
||||
Using pages as an example, knowing the CSS property ``overflow``
|
||||
is used on ``1504`` pages is... nice. I guess.
|
||||
But if you sum up ``use.counters.top_level_content_documents_destroyed``
|
||||
to find that there were only ``1506`` pages loaded?
|
||||
That's a figure we can do something with.
|
||||
We can order MDN search results by popularity.
|
||||
We can prioritize performance efforts in Gecko to focus on the most-encountered features.
|
||||
We can view the popularity over time and see when we expect we'll be able to deprecate and remove the feature.
|
||||
|
||||
This is why you'll more likely encounter use counter data expressed as usage rates.
|
@ -26,10 +26,8 @@
|
||||
#include "mozilla/dom/MediaController.h"
|
||||
#include "mozilla/dom/WindowGlobalChild.h"
|
||||
#include "mozilla/dom/ChromeUtils.h"
|
||||
#include "mozilla/dom/UseCounterMetrics.h"
|
||||
#include "mozilla/dom/ipc/IdType.h"
|
||||
#include "mozilla/dom/ipc/StructuredCloneData.h"
|
||||
#include "mozilla/glean/GleanMetrics.h"
|
||||
#include "mozilla/Components.h"
|
||||
#include "mozilla/ScopeExit.h"
|
||||
#include "mozilla/ServoCSSParser.h"
|
||||
@ -1119,7 +1117,6 @@ void WindowGlobalParent::FinishAccumulatingPageUseCounters() {
|
||||
}
|
||||
|
||||
Telemetry::Accumulate(Telemetry::TOP_LEVEL_CONTENT_DOCUMENTS_DESTROYED, 1);
|
||||
glean::use_counter::top_level_content_documents_destroyed.Add();
|
||||
|
||||
bool any = false;
|
||||
for (int32_t c = 0; c < eUseCounter_Count; ++c) {
|
||||
@ -1135,7 +1132,6 @@ void WindowGlobalParent::FinishAccumulatingPageUseCounters() {
|
||||
Telemetry::GetHistogramName(id), urlForLogging->get());
|
||||
}
|
||||
Telemetry::Accumulate(id, 1);
|
||||
IncrementUseCounter(uc, /* aIsPage = */ true);
|
||||
}
|
||||
|
||||
if (!any) {
|
||||
|
@ -23,23 +23,3 @@ pageload:
|
||||
notification_emails:
|
||||
- perf-telemetry-alerts@mozilla.com
|
||||
- dpalmeiro@mozilla.com
|
||||
|
||||
use-counters:
|
||||
description: |
|
||||
Collects counts of uses of web platform features.
|
||||
See [Use Counters Documentation](https://firefox-source-docs.mozilla.org/dom/use-counters.html)
|
||||
for more information.
|
||||
reasons:
|
||||
app_shutdown_confirmed: |
|
||||
Submitted when we reach `ShutdownPhase::AppShutdownConfirmed`.
|
||||
(Any later and the network might have been torn down.)
|
||||
include_client_id: true
|
||||
send_if_empty: false
|
||||
bugs:
|
||||
- https://bugzilla.mozilla.org/show_bug.cgi?id=1852098
|
||||
data_reviews:
|
||||
- https://bugzilla.mozilla.org/show_bug.cgi?id=1852098
|
||||
notification_emails:
|
||||
- dom-core@mozilla.com
|
||||
- chutten@mozilla.com
|
||||
- emilio@mozilla.com
|
||||
|
@ -53,7 +53,6 @@
|
||||
#include "mozilla/dom/RemoteWorkerService.h"
|
||||
#include "mozilla/dom/RootedDictionary.h"
|
||||
#include "mozilla/dom/TimeoutHandler.h"
|
||||
#include "mozilla/dom/UseCounterMetrics.h"
|
||||
#include "mozilla/dom/WorkerBinding.h"
|
||||
#include "mozilla/dom/WorkerScope.h"
|
||||
#include "mozilla/dom/WorkerStatus.h"
|
||||
@ -62,7 +61,6 @@
|
||||
#include "mozilla/dom/WindowContext.h"
|
||||
#include "mozilla/extensions/ExtensionBrowser.h" // extensions::Create{AndDispatchInitWorkerContext,WorkerLoaded,WorkerDestroyed}Runnable
|
||||
#include "mozilla/extensions/WebExtensionPolicy.h"
|
||||
#include "mozilla/glean/GleanMetrics.h"
|
||||
#include "mozilla/ipc/BackgroundChild.h"
|
||||
#include "mozilla/ipc/PBackgroundChild.h"
|
||||
#include "mozilla/StorageAccess.h"
|
||||
@ -4629,15 +4627,12 @@ void WorkerPrivate::ReportUseCounters() {
|
||||
switch (kind) {
|
||||
case WorkerKindDedicated:
|
||||
Telemetry::Accumulate(Telemetry::DEDICATED_WORKER_DESTROYED, 1);
|
||||
glean::use_counter::dedicated_workers_destroyed.Add();
|
||||
break;
|
||||
case WorkerKindShared:
|
||||
Telemetry::Accumulate(Telemetry::SHARED_WORKER_DESTROYED, 1);
|
||||
glean::use_counter::shared_workers_destroyed.Add();
|
||||
break;
|
||||
case WorkerKindService:
|
||||
Telemetry::Accumulate(Telemetry::SERVICE_WORKER_DESTROYED, 1);
|
||||
glean::use_counter::service_workers_destroyed.Add();
|
||||
break;
|
||||
default:
|
||||
MOZ_ASSERT(false, "Unknown worker kind");
|
||||
@ -4665,7 +4660,6 @@ void WorkerPrivate::ReportUseCounters() {
|
||||
static_cast<size_t>(Telemetry::HistogramUseCounterWorkerCount) / count;
|
||||
MOZ_ASSERT(factor > kind);
|
||||
|
||||
const auto workerKind = Kind();
|
||||
for (size_t c = 0; c < count; ++c) {
|
||||
// Histograms for worker use counters use the same order as the worker kinds
|
||||
// , so we can use the worker kind to index to corresponding histogram.
|
||||
@ -4682,7 +4676,6 @@ void WorkerPrivate::ReportUseCounters() {
|
||||
workerPathForLogging->get());
|
||||
}
|
||||
Telemetry::Accumulate(id, 1);
|
||||
IncrementWorkerUseCounter(static_cast<UseCounterWorker>(c), workerKind);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -63,11 +63,7 @@ class RemoteWorkerChild;
|
||||
// If you change this, the corresponding list in nsIWorkerDebugger.idl needs
|
||||
// to be updated too. And histograms enum for worker use counters uses the same
|
||||
// order of worker kind. Please also update dom/base/usecounters.py.
|
||||
enum WorkerKind : uint8_t {
|
||||
WorkerKindDedicated,
|
||||
WorkerKindShared,
|
||||
WorkerKindService
|
||||
};
|
||||
enum WorkerKind { WorkerKindDedicated, WorkerKindShared, WorkerKindService };
|
||||
|
||||
class ClientInfo;
|
||||
class ClientSource;
|
||||
|
@ -33,17 +33,6 @@ function grabHistogramsFromContent(
|
||||
}).then(gather, gather);
|
||||
}
|
||||
|
||||
function unscream(s) {
|
||||
// Takes SCREAMINGCASE `s` and returns "Screamingcase".
|
||||
return s.charAt(0) + s.slice(1).toLowerCase();
|
||||
}
|
||||
|
||||
function screamToCamel(s) {
|
||||
// Takes SCREAMING_CASE `s` and returns "screamingCase".
|
||||
const pascal = s.split("_").map(unscream).join("");
|
||||
return pascal.charAt(0).toLowerCase() + pascal.slice(1);
|
||||
}
|
||||
|
||||
var check_use_counter_worker = async function (
|
||||
use_counter_name,
|
||||
worker_type,
|
||||
@ -61,15 +50,6 @@ var check_use_counter_worker = async function (
|
||||
use_counter_name,
|
||||
worker_type
|
||||
);
|
||||
await Services.fog.testFlushAllChildren();
|
||||
let glean_before =
|
||||
Glean[`useCounterWorker${unscream(worker_type)}`][
|
||||
screamToCamel(use_counter_name)
|
||||
].testGetValue();
|
||||
let glean_destructions_before =
|
||||
Glean.useCounter[
|
||||
`${worker_type.toLowerCase()}WorkersDestroyed`
|
||||
].testGetValue();
|
||||
|
||||
BrowserTestUtils.startLoadingURIString(
|
||||
gBrowser.selectedBrowser,
|
||||
@ -89,36 +69,18 @@ var check_use_counter_worker = async function (
|
||||
worker_type,
|
||||
histogram_before
|
||||
);
|
||||
await Services.fog.testFlushAllChildren();
|
||||
let glean_after =
|
||||
Glean[`useCounterWorker${unscream(worker_type)}`][
|
||||
screamToCamel(use_counter_name)
|
||||
].testGetValue();
|
||||
let glean_destructions_after =
|
||||
Glean.useCounter[
|
||||
`${worker_type.toLowerCase()}WorkersDestroyed`
|
||||
].testGetValue();
|
||||
|
||||
is(
|
||||
histogram_after,
|
||||
histogram_before + 1,
|
||||
`histogram ${use_counter_name} counts for ${worker_type} worker are correct`
|
||||
);
|
||||
is(
|
||||
glean_after,
|
||||
glean_before + 1,
|
||||
`Glean counter ${use_counter_name} for ${worker_type} worker is correct.`
|
||||
);
|
||||
// There might be other workers created by prior tests get destroyed during
|
||||
// this tests.
|
||||
ok(
|
||||
destructions_after > destructions_before,
|
||||
`${worker_type} worker counts are correct`
|
||||
);
|
||||
ok(
|
||||
glean_destructions_after > glean_destructions_before,
|
||||
`Glean ${worker_type} worker counts are correct`
|
||||
);
|
||||
};
|
||||
|
||||
add_task(async function test_dedicated_worker() {
|
||||
|
@ -103,7 +103,6 @@ MACH_COMMANDS = {
|
||||
"geckoview-junit": MachCommandReference(
|
||||
"testing/mochitest/mach_commands.py", ["test"]
|
||||
),
|
||||
"gen-use-counter-metrics": MachCommandReference("dom/base/mach_commands.py"),
|
||||
"generate-test-certs": MachCommandReference(
|
||||
"security/manager/tools/mach_commands.py"
|
||||
),
|
||||
|
@ -56,8 +56,8 @@ PING_INDEX_BITS = 16
|
||||
# This ensures the algorithm finds empty slots in the buckets
|
||||
# with the number of metrics we now have in-tree.
|
||||
# toolkit/components/telemetry uses 1024, some others 512.
|
||||
# See https://bugzilla.mozilla.org/show_bug.cgi?id=1822477
|
||||
PHF_SIZE = 1024
|
||||
# 512 seems to cover us just fine and future-proofs this for a while.
|
||||
PHF_SIZE = 512
|
||||
|
||||
|
||||
def ping_entry(ping_id, ping_string_index):
|
||||
|
@ -16,7 +16,6 @@
|
||||
# Order is lexicographical, enforced by t/c/glean/tests/pytest/test_yaml_indices.py
|
||||
gecko_metrics = [
|
||||
"browser/base/content/metrics.yaml",
|
||||
"dom/base/use_counter_metrics.yaml",
|
||||
"dom/media/metrics.yaml",
|
||||
"dom/media/webrtc/metrics.yaml",
|
||||
"dom/metrics.yaml",
|
||||
|
@ -194,38 +194,6 @@ Maybe<uint32_t>
|
||||
CategoryByNameLookup(const nsACString& aKey)
|
||||
{
|
||||
static const uint8_t BASES[] = {
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
@ -256,7 +224,7 @@ CategoryByNameLookup(const nsACString& aKey)
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
};
|
||||
|
||||
@ -303,28 +271,28 @@ constexpr char gMetricStringTable[] = {
|
||||
static_assert(sizeof(gMetricStringTable) < 4294967296, "Metric string table is too large.");
|
||||
|
||||
const metric_entry_t sMetricByNameLookupEntries[] = {
|
||||
6341068335467200838ull,
|
||||
5764607578868810038ull,
|
||||
9799832879352513026ull,
|
||||
1729382269795172390ull,
|
||||
2305843026393563204ull,
|
||||
5188146822270419236ull,
|
||||
10952754392549294655ull,
|
||||
9223372122754122216ull,
|
||||
4035225309073637616ull,
|
||||
576460756598390784ull,
|
||||
3458764548180279480ull,
|
||||
8646911366155731401ull,
|
||||
9799832879352513026ull,
|
||||
6341068335467200838ull,
|
||||
2305843026393563204ull,
|
||||
4035225309073637616ull,
|
||||
2305843030688530526ull,
|
||||
3458764552475246801ull,
|
||||
1152921513196781587ull,
|
||||
10376293635950903832ull,
|
||||
4611686065672028430ull,
|
||||
576460756598390784ull,
|
||||
7493989848663982456ull,
|
||||
8070450605262373266ull,
|
||||
8646911366155731401ull,
|
||||
3458764552475246801ull,
|
||||
5188146822270419236ull,
|
||||
1152921513196781587ull,
|
||||
10952754392549294655ull,
|
||||
1729382269795172390ull,
|
||||
2882303787286921342ull,
|
||||
10376293635950903832ull,
|
||||
2882303791581888664ull,
|
||||
6917529092065591642ull,
|
||||
4611686065672028430ull,
|
||||
5764607578868810038ull,
|
||||
8070450609557340585ull
|
||||
};
|
||||
|
||||
@ -336,66 +304,34 @@ MetricByNameLookup(const nsACString& aKey)
|
||||
static const uint8_t BASES[] = {
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0,
|
||||
1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0,
|
||||
0, 0, 0, 1, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 4, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 1, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 1, 0, 3, 0, 0, 0, 0, 0, 0, 0,
|
||||
21, 0, 0, 0, 39, 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0,
|
||||
0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 3, 0, 3, 0, 0, 0, 0, 0, 0, 0,
|
||||
2, 0, 0, 0, 2, 0, 0, 21, 0, 0, 0, 0, 34, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
};
|
||||
|
@ -38,10 +38,10 @@ constexpr char gPingStringTable[] = {
|
||||
|
||||
|
||||
const ping_entry_t sPingByNameLookupEntries[] = {
|
||||
65536,
|
||||
262185,
|
||||
131084,
|
||||
196639,
|
||||
262185
|
||||
65536,
|
||||
196639
|
||||
};
|
||||
|
||||
|
||||
@ -50,48 +50,16 @@ Maybe<uint32_t>
|
||||
PingByNameLookup(const nsACString& aKey)
|
||||
{
|
||||
static const uint8_t BASES[] = {
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
|
@ -18,6 +18,7 @@ The current data collection possibilities include:
|
||||
* :doc:`events` can record richer data on individual occurrences of specific actions
|
||||
* :doc:`Measuring elapsed time <measuring-time>`
|
||||
* :doc:`Custom pings <custom-pings>`
|
||||
* :doc:`Use counters <use-counters>` measure the usage of web platform features
|
||||
* :doc:`Experiment annotations <experiments>`
|
||||
* :doc:`Remote content uptake <uptake>`
|
||||
* :doc:`WebExtension API <webextension-api>` can be used in privileged webextensions
|
||||
|
105
toolkit/components/telemetry/docs/collection/use-counters.rst
Normal file
105
toolkit/components/telemetry/docs/collection/use-counters.rst
Normal file
@ -0,0 +1,105 @@
|
||||
============
|
||||
Use Counters
|
||||
============
|
||||
|
||||
Use counters are used to report Telemetry statistics on whether individual documents
|
||||
use a given WebIDL method or attribute (getters and setters are reported separately), CSS
|
||||
property, or deprecated DOM operation. Custom use counters can also be
|
||||
defined to test frequency of things that don't fall into one of those
|
||||
categories.
|
||||
|
||||
As of Firefox 65 the collection of Use Counters is enabled on all channels.
|
||||
|
||||
The API
|
||||
=======
|
||||
The process to add a new use counter is different depending on the type feature that needs
|
||||
to be measured. In general, for each defined use counter, two separate boolean histograms are generated:
|
||||
|
||||
- one describes the use of the tracked feature for individual documents and has the ``_DOCUMENT`` suffix;
|
||||
- the other describes the use of the same thing for top-level pages (basically what we think of as a *web page*) and has the ``_PAGE`` suffix.
|
||||
|
||||
Using two histograms is particularly suited to measure how many sites would be affected by
|
||||
removing the tracked feature.
|
||||
|
||||
Example scenarios:
|
||||
|
||||
- Site *X* triggers use counter *Y*. We report "used" (true) in both the ``_DOCUMENT`` and ``_PAGE`` histograms.
|
||||
- Site *X* does not trigger use counter *Y*. We report "unused" (false) in both the ``_DOCUMENT`` and ``_PAGE`` histograms.
|
||||
- Site *X* has an iframe for site *W*. Site *W* triggers use counter *Y*, but site *X* does not. We report one "used" and one "unused" in the individual ``_DOCUMENT`` histogram and one "used" in the top-level ``_PAGE`` histogram.
|
||||
|
||||
Deprecated DOM operations
|
||||
-------------------------
|
||||
Use counters for deprecated DOM operations are declared in the `nsDeprecatedOperationList.h <https://searchfox.org/mozilla-central/source/dom/base/nsDeprecatedOperationList.h>`_ file. The counters are
|
||||
registered through the ``DEPRECATED_OPERATION(DeprecationReference)`` macro. The provided
|
||||
parameter must have the same value of the deprecation note added to the *IDL* file.
|
||||
|
||||
See this `changeset <https://hg.mozilla.org/mozilla-central/rev/e30a357b25f1>`_ for a sample
|
||||
deprecated operation.
|
||||
|
||||
CSS Properties
|
||||
~~~~~~~~~~~~~~
|
||||
|
||||
Use counters for CSS properties are generated for every property Gecko supports automatically, and are counted via StyleUseCounters (`Rust code <https://searchfox.org/mozilla-central/rev/7ed8e2d3d1d7a1464ba42763a33fd2e60efcaedc/servo/components/style/use_counters/mod.rs>`_, `C++ code <https://searchfox.org/mozilla-central/rev/7ed8e2d3d1d7a1464ba42763a33fd2e60efcaedc/dom/base/Document.h#5077>`_).
|
||||
|
||||
The UseCounters registry
|
||||
------------------------
|
||||
Use counters for WebIDL methods/attributes are registered in the `UseCounters.conf <https://searchfox.org/mozilla-central/source/dom/base/UseCounters.conf>`_ file. The format of this file is very strict. Each line can be:
|
||||
|
||||
1. a blank line
|
||||
2. a comment, which is a line that begins with ``//``
|
||||
3. one of four possible use counter declarations:
|
||||
|
||||
* ``method <IDL interface name>.<IDL operation name>``
|
||||
* ``attribute <IDL interface name>.<IDL attribute name>``
|
||||
* ``custom <any valid identifier> <description>``
|
||||
|
||||
Custom use counters
|
||||
~~~~~~~~~~~~~~~~~~~
|
||||
The <description> for custom counters will be appended to "When a document " or "When a page ", so phrase it appropriately. For instance, "constructs a Foo object" or "calls Document.bar('some value')". It may contain any character (including whitespace). Custom counters are incremented when SetUseCounter(eUseCounter_custom_MyName) is called on a Document object.
|
||||
|
||||
WebIDL methods and attributes
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
Additionally to having a new entry added to the `UseCounters.conf <https://searchfox.org/mozilla-central/source/dom/base/UseCounters.conf>`_ file, WebIDL methods and attributes must have a ``[UseCounter]`` extended attribute in the Web IDL file in order for the counters to be incremented.
|
||||
|
||||
Both additions are required because generating things from bindings codegen and ensuring all the dependencies are correct would have been rather difficult.
|
||||
|
||||
The processor script
|
||||
====================
|
||||
The definition files are processed twice:
|
||||
|
||||
- once to generate two C++ headers files, included by the web platform components (e.g. DOM) that own the features to be tracked;
|
||||
- the other time by the Telemetry component, to generate the histogram definitions that make the collection system work.
|
||||
|
||||
.. note::
|
||||
|
||||
The histograms that are generated out of use counters are set to *never* expire and are collected from Firefox release. Note that before Firefox 65 they were only collected on pre-release.
|
||||
|
||||
gen-usecounters.py
|
||||
------------------
|
||||
This script is called by the build system to generate:
|
||||
|
||||
- the ``UseCounterList.h`` header for the WebIDL, out of the definition files.
|
||||
|
||||
Interpreting the data
|
||||
=====================
|
||||
The histogram as accumulated on the client only puts values into the 1 bucket, meaning that
|
||||
the use counter directly reports if a feature was used but it does not directly report if
|
||||
it isn't used.
|
||||
The values accumulated within a use counter should be considered proportional to
|
||||
``CONTENT_DOCUMENTS_DESTROYED`` and ``TOP_LEVEL_CONTENT_DOCUMENTS_DESTROYED`` (see
|
||||
`here <https://searchfox.org/mozilla-central/rev/1a973762afcbc5066f73f1508b0c846872fe3952/dom/base/Document.cpp#15059-15081>`__). The difference between the values of these two histograms
|
||||
and the related use counters below tell us how many pages did *not* use the feature in question.
|
||||
For instance, if we see that a given session has destroyed 30 content documents, but a
|
||||
particular use counter shows only a count of 5, we can infer that the use counter was *not*
|
||||
used in 25 of those 30 documents.
|
||||
|
||||
Things are done this way, rather than accumulating a boolean flag for each use counter,
|
||||
to avoid sending histograms for features that don't get widely used. Doing things in this
|
||||
fashion means smaller telemetry payloads and faster processing on the server side.
|
||||
|
||||
Version History
|
||||
---------------
|
||||
|
||||
- Firefox 65:
|
||||
|
||||
- Enable Use Counters on release channel (`bug 1477433 <https://bugzilla.mozilla.org/show_bug.cgi?id=1477433>`_)
|
@ -74,6 +74,8 @@ Most of our data collection happens through :doc:`scalars <../collection/scalars
|
||||
|
||||
Both scalars & histograms allow recording by keys. This allows for more flexible, two-level data collection.
|
||||
|
||||
Other collections can build on top of scalars & histograms. An example is :doc:`use counters <../collection/use-counters>`, which submit web feature usage through histograms.
|
||||
|
||||
We also collect :doc:`environment data <../data/environment>`. This consists of mostly scalar values that capture the “working environment” a Firefox session lives in, and includes e.g. data on hardware, OS, add-ons and some settings. Any data that is part of the "working environment", or needs to split :doc:`subsessions <../concepts/sessions>`, should go into it.
|
||||
|
||||
Rich data
|
||||
|
Loading…
Reference in New Issue
Block a user