Glean Interface For Firefox Telemetry (GIFFT)¶
To make Migration from Firefox Telemetry to Glean easier, the C++ and JS Glean API can be configured (on a metric-by-metric basis) to mirror data collection to both the Glean metric and a Telemetry probe.
GIFFT should ideally be used only when the data you require for analysis still mostly lives in Telemetry, and should be removed promptly when no longer needed. Instrumentors are encouraged to have the Telemetry probe expire no later than Firefox 98 (scheduled for 2021-12-02).
Note: GIFFT only works for data provided via C++ or JS. Rust Glean metrics APIs will not mirror to Telemetry as Telemetry does not have a Rust API.
Note: Using the Glean API replaces the Telemetry API. Do not use any mix of the two APIs for the same probe.
How to Mirror a Glean Metric to a Firefox Telemetry Probe¶
For the mirror to work, you need three things:
A compatible Glean metric (defined in a
A compatible Telemetry probe (defined in
telemetry_mirrorproperty on the Glean metric definition identifying the Telemetry probe
This compatibility table explains which Telemetry probe types can be mirrors for which Glean metric types:
|Glean Metric Type||Telementry Probe Type|
|boolean||Scalar of kind: boolean|
|labeled_boolean||Keyed scalar of kind: boolean|
|counter||Scalar of kind: uint|
|labeled_counter||Keyed Scalar of kind: uint|
|string||Scalar of kind: string|
|labeled_string||No Supported Telemetry Type|
|string_list||Keyed Scalar of kind: boolean. The keys are the strings. The values are all
|timespan||Scalar of kind: uint. The value is in units of milliseconds.|
|timing_distribution||Histogram of kind "linear" or "exponential". Samples will be in units of milliseconts.|
|memory_distribution||Histogram of kind "linear" or "exponential". Samples will be in
|custom_distribution||Histogram of kind "linear" or "exponential". Samples will be used as is. Ensure the bucket count and range match.|
|uuid||Scalar of kind: string. Value will be in canonical 8-4-4-4-12 format. Value is not guaranteed to be valid, and invalid values may be present in the mirrored scalar which the uuid metric remains empty. Calling
|datetime||Scalar of kind: string. Value will be in ISO8601 format.|
|quantity||Scalar of kind: uint|
|rate||Keyed Scalar of kind: uint. The keys are "numerator" and "denominator". Does not work for
telemetry_mirror property in
You must use the C++ enum value of the Histogram, Scalar, or Event being mirrored to.
For example, for this Scalar of kind
category.name: probe_name: kind: boolean ...
You must provide the following
telemetry_mirror name for its source
boolean metric’s definition:
If you get this wrong it will manifest as a build error.
Artifact Build Support¶
Firefox Telemetry and the Glean SDK are very different. Though GIFFT bridges the differences as best it can, there are many things it cannot account for.
These are a few of the ways that differences between Firefox Telemetry and the Glean SDK might manifest as anomalies during analysis.
Processes, Products, and Channels¶
Like Firefox on Glean itself, GIFFT doesn’t know what process, product, or channel it is recording in. Telemetry does, and imposes restrictions on which probes can be recorded to and when.
Ensure that the following fields in any Telemetry mirror’s definition aren’t too restrictive for your use:
A mismatch won’t result in an error. If you, for example, record to a Glean metric in a release channel that the Telemetry mirror probe doesn’t permit, then the Glean metric will have a value and the Telemetry mirror probe won’t.
Also recall that Telemetry probes split their values across processes. Glean metrics do not. This may manifest as curious anomalies when comparing the Glean metric to its Telemetry mirror probe. Ensure your analyses are aggregating Telemetry values from all processes, or define and use process-specific Glean metrics and Telemetry mirror probes to keep things separate.
Glean and Telemetry both send their built-in pings on their own schedules. This means the values present in these pings may not agree since they reflect state at different time.
For example, if you are measuring “Number of Monitors” with a
sent by default in the Glean “metrics” ping mirrored to a
Scalar of kind: uint
sent by default in the Telemetry “main” ping,
then if the user plugs in a second monitor between midnight
(when Telemetry “main” pings with reason “daily” are sent) and 4AM
(when Glean “metrics” pings with reason “today” are sent),
the value in the
quantity will be
while the value in the Scalar of kind: uint will be
If the metric or mirrored probe are sent in Custom pings, the schedules could line up exactly or be entirely unrelated.
Labeled metrics supported by GIFFT
adhere to the Glean SDK’s
Keyed Scalars, on the other hand, do not have a concept of an “Invalid key”. Firefox Telemetry will accept just about any sequence of bytes as a key.
This means that a label deemed invalid by the Glean SDK may appear in the mirrored probe’s data.
For example, using
InvalidLabel as a label that doesn’t conform to the format
(it has upper-case letters)
see that the
correctly ascribes it to
whereas the mirrored Keyed Scalar with kind boolean stores and retrieves it without change:
Glean.testOnly.mirrorsForLabeledBools.InvalidLabel.set(true); Assert.equal(true, Glean.testOnly.mirrorsForLabeledBools.__other__.testGetValue()); let snapshot = Services.telemetry.getSnapshotForKeyedScalars().parent; Assert.equal(true, snapshot["telemetry.test.mirror_for_labeled_bool"]["InvalidLabel"]);
A Glean event can be mirrored to a Telemetry Event.
Telemetry Events must be enabled before they can be recorded to via the API
If the Telemetry Event isn’t enabled,
recording to the Glean event will still work,
and the event will be Summarized in Telemetry as all disabled events are.
See the Telemetry Event docs for details on how disabled Telemetry Events behave.