feat(ads-client): add telemetry support
Telemetry Architecture
Core Telemetry Trait
A generic Telemetry<A> trait at the core/std layer:
- Simple: single
record(&self, event: &A)method - Generic: works with any event type
- Dependency-free: modules depend only on the trait, not implementations
- Minimal coupling: each module records only what it needs
Super Traits for Complex Components
Higher-level traits compose multiple telemetry types:
MARSTelemetry: RequiresTelemetry<CacheOutcome>+Telemetry<serde_json::Error>AdsTelemetry: ComposesMARSTelemetry+ specific error types (RequestAdsError,RecordClickError, etc.) +ClientOperationEvent
This provides granular control without coupling modules to specific implementations.
FFI Layer: Platform-Specific Implementations
The MozAdsTelemetry trait is exposed via UniFFI for iOS/Android:
- Platform-specific: devices implement it with their own Glean code
- Glean-ready: methods map directly to Glean metrics (labels/values)
- Passed at construction: injected via
MozAdsClientConfig - Wrapped:
MozAdsTelemetryWrapperbridges FFI trait to core telemetry traits
Benefits
- Clean separation: Core logic is independent of FFI/platform concerns
- Granular control: Each module records only relevant events
- Trait composition: Super traits express requirements without implementation details
- Platform flexibility: Each platform implements telemetry with its own Glean integration
- No dependency bloat: Core modules don't depend on FFI or platform-specific code
This keeps the core clean and flexible while enabling platform-specific telemetry integration.
Pull Request checklist
- Breaking changes: This PR follows our breaking change policy
- [ ] This PR follows the breaking change policy:
- This PR has no breaking API changes, or
- There are corresponding PRs for our consumer applications that resolve the breaking changes and have been approved
- [ ] This PR follows the breaking change policy:
- [ ] Quality: This PR builds and tests run cleanly
- Note:
- For changes that need extra cross-platform testing, consider adding
[ci full]to the PR title. - If this pull request includes a breaking change, consider cutting a new release after merging.
- For changes that need extra cross-platform testing, consider adding
- Note:
- [ ] Tests: This PR includes thorough tests or an explanation of why it does not
- [ ] Changelog: This PR includes a changelog entry in CHANGELOG.md or an explanation of why it does not need one
- Any breaking changes to Swift or Kotlin binding APIs are noted explicitly
- [ ] Dependencies: This PR follows our dependency management guidelines
- Any new dependencies are accompanied by a summary of the due diligence applied in selecting them.
Data review:
Request for data collection review form
All questions are mandatory. You must receive review from a data steward peer on your responses to these questions before shipping new data collection.
1) What questions will you answer with this data?
Is the ads-client component (to be shipped on FF iOS and Android) working reliably in the wild?
Specifically:
- What is the error rate of different sub-systems within the component?
- Do the clicks/impression interactions registered in the client generally match up with the click/impression counts we see in our backend servers.
2) Why does Mozilla need to answer these questions? Are there benefits for users? Do we need this information to address product or business requirements?
They will establish baseline quality and performance measures for the new ads-client component.
Short-term, Mozilla needs to understand if this component is working as intended as we roll it out on FF mobile.
3) What alternative methods did you consider to answer these questions? Why were they not sufficient?
Local testing is about all we have currently. This however does not give us a good view on how it is performing "out in the wild."
We could use indirect metrics from our backend server, such as ad requests counts, click counts, or request counts to indirectly infer whether the ads-client is working correctly on the client. However it would not help us identify where failure points were if we suspected crashes were occurring.
4) Can current instrumentation answer these questions?
No. At best FF iOS or Android could build some instrumentation themselves to determine if the ads-client failed, but it would not have insight into anything past the UniFFI boundary making it considerably less useful for quality monitoring.
5) List all proposed measurements and indicate the category of data collection for each measurement, using the Firefox data collection categories on the Mozilla wiki.
| Measurement Description | Data Collection Category | Tracking Bug # |
| A count of errors encountered when building the HTTP cache, labeled by error type. The string value contains the error message or error type. | Category 1 | https://github.com/mozilla/application-services/pull/7111 |
| A count of errors encountered when using the ads client, labeled by operation type. The string value contains the error message or error type. Errors are recorded even if they are propagated to the consumer. | Category 1 | https://github.com/mozilla/application-services/pull/7111 |
| The total number of operations attempted by the ads client, labeled by operation type. Used as the denominator for client_operation_success_rate. | Category 2 | https://github.com/mozilla/application-services/pull/7111 |
| A count of deserialization errors encountered when parsing AdResponse data, labeled by error type. The string value contains the error message or details. Invalid ad items are skipped but these errors are tracked for monitoring data quality issues. | Category 1 | https://github.com/mozilla/application-services/pull/7111 |
| A count of the total number of outcomes encountered during read operations on the http cache, labeled by type. | Category 1 | https://github.com/mozilla/application-services/pull/7111 |
6) How long will this data be collected? Choose one of the following:
- Ideally this data could be collected permanently for active monitoring by engineers. However, at least 6 months would be great as we launch with it potentially being renewable.
7) What populations will you measure?
- Which release channels?
All.
- Which countries?
All.
- Which locales?
All.
This component will ship with Firefox iOS and Android.
8) If this data collection is default on, what is the opt-out mechanism for users?
This is by default on. Disabling all reporting via datareporting.healthreport.uploadEnabled should be the opt-out mechanism.
9) Please provide a general description of how you will analyze this data.
We'll make a "ads-client quality metrics" dashboard to monitor the datapoints described above. This will only be for engineers on the ads-client team to validate the component is working correctly, and establish baselines for what we consider healthy "normal operation metrics."
10) Where do you intend to share the results of your analysis?
The results will be shared internally within the ads-engineering team responsible for the ads-client. We do not plan to distribute or share analyses to anyone else.
11) Is there a third-party tool (i.e. not Telemetry) that you are proposing to use for this data collection?
Nope!
data-review+
- Is there or will there be documentation that describes the schema for the ultimate data set in a public, complete, and accurate way? Click the documentation link provided in Q6 and ensure it is publicly accessible and does or will contain documentation for the data collection.
Yes, the usual Glean data dictionary for iOS and android, https://dictionary.telemetry.mozilla.org.
- Is there a control mechanism that allows the user to turn the data collection on and off? (Note, for data collection not needed for security purposes, Mozilla provides such a control mechanism) Provide details as to the control mechanism available.
Yes, the existing datareporting.healthreport.uploadEnabled setting allows users to opt out.
- If the request is for permanent data collection, is there someone who will monitor the data over time?
Yes, the team will monitor (emails currently being revised in metrics.yaml).
- Using the category system of data types on the Mozilla wiki, what collection type of data do the requested measurements fall under?
Category 2, interaction data.
- Is the data collection request for default-on or default-off?
Default-on.
- Does the instrumentation include the addition of any new identifiers (whether anonymous or otherwise; e.g., username, random IDs, etc. See the appendix for more details)?
No.
- Is the data collection covered by the existing Firefox privacy notice?
Yes.
- Does the data collection use a third-party collection tool?
No.