mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-23 04:41:11 +00:00
Bug 1915183 - Collect telemetry for usage of storage.sync r=rpl
Differential Revision: https://phabricator.services.mozilla.com/D222442
This commit is contained in:
parent
3ae4f3573a
commit
b1146d27a1
@ -82,6 +82,7 @@ export class ExtensionStorageSync {
|
||||
// migration failure, it will become false. In practice, this will only ever
|
||||
// happen on the first operation.
|
||||
this.migrationOk = true;
|
||||
this.backend = "rust";
|
||||
}
|
||||
|
||||
// The main entry-point to our bridge. It performs some important roles:
|
||||
|
@ -735,6 +735,7 @@ export class ExtensionStorageSyncKinto {
|
||||
this._fxaService = fxaService;
|
||||
this.cryptoCollection = new CryptoCollection(fxaService);
|
||||
this.listeners = new WeakMap();
|
||||
this.backend = "kinto";
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -366,6 +366,37 @@ extensions.data:
|
||||
type: string
|
||||
expires: 140
|
||||
|
||||
sync_usage_quotas:
|
||||
type: event
|
||||
description: |
|
||||
These events record the basic stat about usage, and are collected the
|
||||
first time an extension uses the sync storage API during a session.
|
||||
bugs:
|
||||
- https://bugzilla.mozilla.org/1915183
|
||||
data_reviews:
|
||||
- https://phabricator.services.mozilla.com/D222442
|
||||
data_sensitivity:
|
||||
- technical
|
||||
notification_emails:
|
||||
- addons-dev-internal@mozilla.com
|
||||
extra_keys:
|
||||
addon_id:
|
||||
description: Id of the addon.
|
||||
type: string
|
||||
total_size_bytes:
|
||||
description: Size of the sync data.
|
||||
type: quantity
|
||||
items_count:
|
||||
description: Number of items in sync storage.
|
||||
type: quantity
|
||||
items_over_quota:
|
||||
description: Count of items larger than QUOTA_BYTES_PER_ITEM.
|
||||
type: quantity
|
||||
backend:
|
||||
description: Backend engine used, currently either "kinto" or "rust"
|
||||
type: string
|
||||
expires: 140
|
||||
|
||||
extensions.counters:
|
||||
|
||||
browser_action_preload_result:
|
||||
|
@ -30,6 +30,13 @@ ChromeUtils.defineLazyGetter(this, "extensionStorageSync", () => {
|
||||
return extensionStorageSync;
|
||||
});
|
||||
|
||||
XPCOMUtils.defineLazyPreferenceGetter(
|
||||
this,
|
||||
"prefStorageSyncEnabled",
|
||||
"webextensions.storage.sync.enabled",
|
||||
true
|
||||
);
|
||||
|
||||
const enforceNoTemporaryAddon = extensionId => {
|
||||
const EXCEPTION_MESSAGE =
|
||||
"The storage API will not work with a temporary addon ID. " +
|
||||
@ -40,6 +47,35 @@ const enforceNoTemporaryAddon = extensionId => {
|
||||
}
|
||||
};
|
||||
|
||||
// Set of extensions that already recorded the sync quota event.
|
||||
const syncQuotasRecorded = new WeakSet();
|
||||
const QUOTA_BYTES_PER_ITEM = 8_192;
|
||||
|
||||
async function recordSyncQuotaTelemetry(extension, context) {
|
||||
if (syncQuotasRecorded.has(extension) || !prefStorageSyncEnabled) {
|
||||
return;
|
||||
}
|
||||
syncQuotasRecorded.add(extension);
|
||||
let items = await extensionStorageSync.get(extension, null, context);
|
||||
let items_over_quota = 0;
|
||||
let total_size_bytes = 0;
|
||||
let entries = Object.entries(items);
|
||||
for (let [key, value] of entries) {
|
||||
let bytes = JSON.stringify(value).length;
|
||||
total_size_bytes += key.length + bytes;
|
||||
if (bytes > QUOTA_BYTES_PER_ITEM) {
|
||||
items_over_quota++;
|
||||
}
|
||||
}
|
||||
Glean.extensionsData.syncUsageQuotas.record({
|
||||
addon_id: extension.id,
|
||||
total_size_bytes,
|
||||
items_count: entries.length,
|
||||
items_over_quota,
|
||||
backend: extensionStorageSync.backend,
|
||||
});
|
||||
}
|
||||
|
||||
// WeakMap[extension -> Promise<SerializableMap?>]
|
||||
const managedStorage = new WeakMap();
|
||||
|
||||
@ -324,22 +360,27 @@ this.storage = class extends ExtensionAPIPersistent {
|
||||
sync: {
|
||||
get(spec) {
|
||||
enforceNoTemporaryAddon(extension.id);
|
||||
recordSyncQuotaTelemetry(extension, context);
|
||||
return extensionStorageSync.get(extension, spec, context);
|
||||
},
|
||||
set(items) {
|
||||
enforceNoTemporaryAddon(extension.id);
|
||||
recordSyncQuotaTelemetry(extension, context);
|
||||
return extensionStorageSync.set(extension, items, context);
|
||||
},
|
||||
remove(keys) {
|
||||
enforceNoTemporaryAddon(extension.id);
|
||||
recordSyncQuotaTelemetry(extension, context);
|
||||
return extensionStorageSync.remove(extension, keys, context);
|
||||
},
|
||||
clear() {
|
||||
enforceNoTemporaryAddon(extension.id);
|
||||
recordSyncQuotaTelemetry(extension, context);
|
||||
return extensionStorageSync.clear(extension, context);
|
||||
},
|
||||
getBytesInUse(keys) {
|
||||
enforceNoTemporaryAddon(extension.id);
|
||||
recordSyncQuotaTelemetry(extension, context);
|
||||
return extensionStorageSync.getBytesInUse(extension, keys, context);
|
||||
},
|
||||
onChanged: new EventManager({
|
||||
|
@ -1398,3 +1398,58 @@ async function test_storage_change_event_page(areaName) {
|
||||
|
||||
return runWithPrefs([["extensions.eventPages.enabled", true]], testFn);
|
||||
}
|
||||
|
||||
async function test_storage_sync_telemetry_quota(backend, enforced = false) {
|
||||
Services.fog.testResetFOG();
|
||||
let id = "my-extension-id@23";
|
||||
|
||||
// Repeat twice to get the glean events "before" and "after".
|
||||
for (let i = 0; i < 2; i++) {
|
||||
let ext = ExtensionTestUtils.loadExtension({
|
||||
manifest: {
|
||||
browser_specific_settings: { gecko: { id: id } },
|
||||
permissions: ["storage"],
|
||||
},
|
||||
background() {
|
||||
browser.test.onMessage.addListener(async enforced => {
|
||||
await browser.storage.sync.set({
|
||||
a: "1",
|
||||
b: "x".repeat(enforced ? 1_000 : 10_000),
|
||||
});
|
||||
browser.test.notifyPass("done");
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
await ext.startup();
|
||||
ext.sendMessage(enforced);
|
||||
await ext.awaitFinish("done");
|
||||
await ext.unload();
|
||||
}
|
||||
|
||||
let events = Glean.extensionsData.syncUsageQuotas.testGetValue();
|
||||
events = events.filter(e => e.extra?.addon_id === id);
|
||||
|
||||
Assert.deepEqual(
|
||||
events[0].extra,
|
||||
{
|
||||
addon_id: id,
|
||||
total_size_bytes: 0,
|
||||
items_count: 0,
|
||||
items_over_quota: 0,
|
||||
backend: backend,
|
||||
},
|
||||
"Expected event values before setting sync storage"
|
||||
);
|
||||
Assert.deepEqual(
|
||||
events[1].extra,
|
||||
{
|
||||
addon_id: id,
|
||||
total_size_bytes: enforced ? 1_007 : 10_007,
|
||||
items_count: 2,
|
||||
items_over_quota: enforced ? 0 : 1,
|
||||
backend: backend,
|
||||
},
|
||||
"Expected event values after setting sync storage"
|
||||
);
|
||||
}
|
||||
|
@ -8,6 +8,11 @@ AddonTestUtils.init(this);
|
||||
|
||||
add_task(async function setup() {
|
||||
await ExtensionTestUtils.startAddonManager();
|
||||
|
||||
// FOG needs a profile directory to put its data in.
|
||||
do_get_profile();
|
||||
// FOG needs to be initialized in order for data to flow.
|
||||
Services.fog.initializeFOG();
|
||||
});
|
||||
|
||||
add_task(test_config_flag_needed);
|
||||
@ -33,3 +38,9 @@ add_task(function test_storage_onChanged_event_page() {
|
||||
test_storage_change_event_page("sync")
|
||||
);
|
||||
});
|
||||
|
||||
add_task(async function test_storage_sync_telemetry() {
|
||||
return runWithPrefs([[STORAGE_SYNC_PREF, true]], () =>
|
||||
test_storage_sync_telemetry_quota("rust", true)
|
||||
);
|
||||
});
|
||||
|
@ -664,6 +664,11 @@ function uuid() {
|
||||
|
||||
add_task(async function test_setup() {
|
||||
await promiseStartupManager();
|
||||
|
||||
// FOG needs a profile directory to put its data in.
|
||||
do_get_profile();
|
||||
// FOG needs to be initialized in order for data to flow.
|
||||
Services.fog.initializeFOG();
|
||||
});
|
||||
|
||||
add_task(async function test_single_initialization() {
|
||||
@ -2307,3 +2312,9 @@ add_task(function test_storage_onChanged_event_page() {
|
||||
test_storage_change_event_page("sync")
|
||||
);
|
||||
});
|
||||
|
||||
add_task(async function test_storage_sync_telemetry() {
|
||||
return runWithPrefs([[STORAGE_SYNC_PREF, true]], () =>
|
||||
test_storage_sync_telemetry_quota("kinto", false)
|
||||
);
|
||||
});
|
||||
|
Loading…
Reference in New Issue
Block a user