Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,11 @@

[Full Changelog](In progress)

## ✨ What's New ✨

### Remote Settings
* Add uptake telemetry support ([#7288](https://github.com/mozilla/application-services/pull/7288))

# v150.0 (_2026-03-23_)

# General
Expand Down
38 changes: 38 additions & 0 deletions components/remote_settings/android/build.gradle
Original file line number Diff line number Diff line change
@@ -1,10 +1,48 @@
buildscript {
if (gradle.hasProperty("mozconfig")) {
repositories {
gradle.mozconfig.substs.GRADLE_MAVEN_REPOSITORIES.each { repository ->
maven {
url = repository
if (gradle.mozconfig.substs.ALLOW_INSECURE_GRADLE_REPOSITORIES) {
allowInsecureProtocol = true
}
}
}
}

dependencies {
classpath libs.mozilla.glean.gradle.plugin
}
}
}

plugins {
alias libs.plugins.python.envs.plugin
}

apply from: "$appServicesRootDir/build-scripts/component-common.gradle"
apply from: "$appServicesRootDir/publish.gradle"

ext {
gleanNamespace = "mozilla.telemetry.glean"
gleanYamlFiles = ["${project.projectDir}/../metrics.yaml"]
if (gradle.hasProperty("mozconfig")) {
gleanPythonEnvDir = gradle.mozconfig.substs.GRADLE_GLEAN_PARSER_VENV
}
}
apply plugin: "org.mozilla.telemetry.glean-gradle-plugin"

android {
namespace 'org.mozilla.appservices.remotesettings'
}

dependencies {
implementation libs.mozilla.glean

testImplementation libs.mozilla.glean.forUnitTests
}

ext.configureUniFFIBindgen("remote_settings")
ext.dependsOnTheMegazord()
ext.configurePublish()
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
/* 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/. */

package mozilla.appservices.remotesettings

import mozilla.appservices.remotesettings.RemoteSettingsTelemetry
import mozilla.appservices.remotesettings.UptakeEventExtras
import org.mozilla.appservices.remotesettings.GleanMetrics.RemoteSettings as RSMetrics

/**
* GleanTelemetry is a thin wrapper used to expose
* callbacks used to emit telemetry events to Glean.
*/
class GleanTelemetry : RemoteSettingsTelemetry {
override fun reportUptake(extras: UptakeEventExtras) {
RSMetrics.uptakeRemotesettings.record(
RSMetrics.UptakeRemotesettingsExtra(
value = extras.value,
source = extras.source,
age = extras.age,
trigger = extras.trigger,
timestamp = extras.timestamp,
duration = extras.duration,
errorname = extras.errorName,
),
)
}
}
61 changes: 61 additions & 0 deletions components/remote_settings/metrics.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
# 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/.

# This file defines the metrics that will be gathered for the Remote Settings
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this file even required?

Since technically the telemetry is done in consuming components (eg. kotlin)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's required if you want to check in the Kotlin code in app-services to implement the metrics (e.g. you could define a RemoteSettingsTelemetry implementation that firefox-android could use). Also you might want to use this PR for data review. If neither of those is true, then I don't think it's needed.

# component. Changes to these metrics require data review.
#
# We can't record metrics from Rust directly. To work around that we:
# - Define the metrics in application-services
# - Define API calls in application-services that return the metrics
# alongside the normal results.
# - Record the metrics with Glean in the consumer code

---
$schema: moz://mozilla.org/schemas/glean/metrics/2-0-0

remote_settings:
uptake_remotesettings:
type: event
disabled: true # To be controlled by server knobs due to expected high volume
description: >
Was the remote content successfully pulled? This uptake telemetry
allows to monitor the behaviour of our clients when it comes to
fetching data from remote servers.
See https://searchfox.org/firefox-main/rev/1427c8863/services/common/metrics.yaml
extra_keys:
value:
description: The synchronization status (success, up_to_date, sync_error, ...)
type: string
source:
description: >
A label to distinguish what is being pulled or updated in the component (eg. recipe id, settings collection name, ...).
type: string
duration:
description: The duration of the synchronization process in milliseconds.
type: string
errorName:
description: An optional string with the error name attribute in case of failure.
type: string
trigger:
description: >
A label to distinguish what triggered the polling/fetching of remote content (eg. "broadcast", "timer", "forced", "manual")
type: string
age:
description: >
The age of pulled data in seconds (ie. difference between publication time and fetch time).
type: string
timestamp:
description: >
The current timestamp, received during synchronization.
type: string
bugs: &uptake_remotecontent_result_uptake_bugs
- https://bugzil.la/1517469
- https://bugzil.la/1617133
data_reviews: *uptake_remotecontent_result_uptake_bugs
notification_emails: &uptake_remotecontent_result_uptake_emails
- mleplatre@mozilla.com
- acottner@mozilla.com
data_sensitivity:
- technical
expires: never
11 changes: 11 additions & 0 deletions components/remote_settings/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ pub mod service;
#[cfg(feature = "signatures")]
pub(crate) mod signatures;
pub mod storage;
pub mod telemetry;

pub(crate) mod jexl_filter;
mod macros;
Expand All @@ -24,10 +25,12 @@ pub use client::{Attachment, RemoteSettingsRecord, RemoteSettingsResponse, RsJso
pub use config::{BaseUrl, RemoteSettingsConfig, RemoteSettingsConfig2, RemoteSettingsServer};
pub use context::RemoteSettingsContext;
pub use error::{trace, ApiResult, RemoteSettingsError, Result};
pub use telemetry::{RemoteSettingsTelemetry, SyncStatus, UptakeEventExtras};

use client::Client;
use error::Error;
use storage::Storage;
use telemetry::RemoteSettingsTelemetryWrapper;

uniffi::setup_scaffolding!("remote_settings");

Expand Down Expand Up @@ -60,6 +63,14 @@ impl RemoteSettingsService {
}
}

/// Set the telemetry implementation used to record Glean metrics.
/// This should be set to a real implementation (eg. Kotlin, Swift).
/// If not set, all metric recording is a no-op.
pub fn set_telemetry(&self, telemetry: Arc<dyn RemoteSettingsTelemetry>) {
self.internal
.set_telemetry(RemoteSettingsTelemetryWrapper::new(telemetry));
}

/// Create a new Remote Settings client
///
/// This method performs no IO or network requests and is safe to run in a main thread that can't be blocked.
Expand Down
Loading