forked from mirrors/gecko-dev
Bug 1869870 - Add a migration guide in the Firefox Source docs r=chutten DONTBUILD
Differential Revision: https://phabricator.services.mozilla.com/D196333
This commit is contained in:
parent
90c34fbbd0
commit
158a2bcb39
1 changed files with 262 additions and 0 deletions
|
|
@ -0,0 +1,262 @@
|
|||
# Migrating Telemetry Collected via Geckoview Streaming to Glean
|
||||
|
||||
With Geckoview Streaming (GVST) having been deprecated,
|
||||
this is a guide to migrating collections to [Glean][book-of-glean]
|
||||
via [Firefox on Glean](../index.md).
|
||||
|
||||
```{contents}
|
||||
```
|
||||
|
||||
## Before we Begin
|
||||
|
||||
You should familiarize yourself with the guide on
|
||||
[Adding New Metrics to Firefox Desktop](./new_definitions_file.md).
|
||||
|
||||
You should also read through the guide for
|
||||
[Migrating Metrics from Legacy Telemetry to Glean](./migration.md).
|
||||
|
||||
This guide assumes some basic familiarity with the above.
|
||||
The [Glean book][book-of-glean] has a full API reference, as well.
|
||||
|
||||
## Process
|
||||
|
||||
There are 3 main steps:
|
||||
|
||||
1. Move the metric definition and make necessary updates
|
||||
2. Update the call to use the Glean API
|
||||
3. Update the tests to use the Glean test API
|
||||
|
||||
### Move and Update the Metric Definition
|
||||
|
||||
Existing metrics that make use of the GVST will already have a fully specified YAML
|
||||
entry that we will use as a starting point.
|
||||
This is convenient, but we want to make some minor updates rather than take it fully as is.
|
||||
At a minimum we need to move the definition out of the
|
||||
[Geckoview metrics.yaml][gv-metrics-yaml] file and change from GVST to [GIFFT](./gifft.md).
|
||||
It can go into whichever metrics.yaml file you feel is most appropriate.
|
||||
If an appropriate one does not exist, create a new one [following this guide][new-yaml].
|
||||
Completely remove the metric definition from the Geckoview `metrics.yaml`.
|
||||
|
||||
For all metric types other than `labeled counters` the first step is to change the key
|
||||
of the `gecko_datapoint` entry to `telemetry_mirror`.
|
||||
Next, update the value as per the rules outlined in the [GIFFT guide][telemetry-mirror-doc].
|
||||
This change is required to keep data flowing in the Legacy Telemetry version of the metric.
|
||||
Doing so will ensure that downstream analyses do not break unintentionally.
|
||||
It is not necessary to modify the [Histograms.json][histograms-json] or
|
||||
[Scalars.yaml][scalars-yaml] file.
|
||||
|
||||
To migrate `labeled counters` instead fully remove the `gecko_datapoint` entry.
|
||||
Note that our overall treatment of this type is slightly different.
|
||||
|
||||
Next add the bug that covers the migration to the `bugs` field.
|
||||
Update the `description` field as well to indicate the metric used to be collected
|
||||
via the Geckoview Streaming API. Other fields should be updated as makes sense.
|
||||
For example, you may need to update the field for `notification_emails`.
|
||||
Since you are not changing the collection a new data review is not necessary.
|
||||
However, if you notice a metric is set to expire soon and it should continue to be collected,
|
||||
complete a [data review renewal][dr-renewal] form.
|
||||
|
||||
Do not change the name or metric type.
|
||||
**If you need to change or one both you are creating a new collection.**
|
||||
|
||||
### Update Calls to Use the Glean API
|
||||
|
||||
The next step is to update the metric calls to the Glean API.
|
||||
Fortunately, for the vast matjority of metricsthis is a 1:1 swapout,
|
||||
or for `labeled counters` (which are `categorical histograms` in legacy) we add a second call.
|
||||
We identify the Glean API, remove the old call, and put in its place the Glean call.
|
||||
You can find a full API reference in the [Glean][book-of-glean], but we'll look at how to record
|
||||
values for the types that have existing GVST metrics.
|
||||
|
||||
One way to mentally organize the metrics is to break them into two groups, those that are set,
|
||||
and those that are accumulated to. As when you use the Legacy Telemetry API for GVST,
|
||||
they are invoked slightly differently.
|
||||
|
||||
To record in C++, you need to include `#include "mozilla/glean/GleanMetrics.h"`.
|
||||
In Javascript, it is extremely unlikely that you will not already have access to `Glean`.
|
||||
If you do not, please reach out to a Data Collection Tools team member on
|
||||
[the #glean:mozilla.org Matrix channel](https://chat.mozilla.org/#/room/#glean:mozilla.org).
|
||||
|
||||
Let's try a few examples.
|
||||
|
||||
#### Migrating a Set Value (string) in C++
|
||||
|
||||
Let's look at the case of the Graphics Adaptor Vendor ID.
|
||||
This is a String,
|
||||
and it's recorded via GVST in C++
|
||||
|
||||
GVST YAML entry (slightly truncated):
|
||||
|
||||
```YAML
|
||||
geckoview:
|
||||
version:
|
||||
description: >
|
||||
The version of the Gecko engine, example: 74.0a1
|
||||
type: string
|
||||
gecko_datapoint: gecko.version
|
||||
```
|
||||
|
||||
And this is recorded:
|
||||
|
||||
```CPP
|
||||
Telemetry::ScalarSet(Telemetry::ScalarID::GECKO_VERSION,
|
||||
NS_ConvertASCIItoUTF16(gAppData->version));
|
||||
```
|
||||
|
||||
To migrate this, let's update our YAML entry, again moving it out of the GVST
|
||||
metrics.yaml into the most appropriate one:
|
||||
|
||||
```YAML
|
||||
geckoview:
|
||||
version:
|
||||
description: >
|
||||
The version of the Gecko engine, example: 74.0a1
|
||||
(Migrated from geckoview.gfx.adapter.primary)
|
||||
type: string
|
||||
telemetry_mirror: GECKO_VERSION
|
||||
```
|
||||
|
||||
Notice how we've checked all of our boxes:
|
||||
|
||||
* Made sure our category makes sense
|
||||
* Changed gecko_datapoint to telemetry_mirror
|
||||
* Updated the description to note that it was migrated from another collection
|
||||
* Kept the type identical.
|
||||
|
||||
Now we can update our call:
|
||||
|
||||
```CPP
|
||||
mozilla::glean::geckoview::version.Set(nsDependentCString(gAppData->version));
|
||||
```
|
||||
|
||||
#### Migrating a Labeled Counter in C++
|
||||
|
||||
Let's look at probably the most complicated scenario, one where we need to accumulate
|
||||
to a labeled collection. Because the glean `labeled counter` and legacy `categorical histogram`
|
||||
type do not support GIFFT, we will add a second call.
|
||||
Let's take a look at an elided version of how this would be done with GVST:
|
||||
|
||||
```CPP
|
||||
switch (aResult.as<NonDecoderResult>()) {
|
||||
case NonDecoderResult::SizeOverflow:
|
||||
AccumulateCategorical(LABELS_AVIF_DECODE_RESULT::size_overflow);
|
||||
return;
|
||||
case NonDecoderResult::OutOfMemory:
|
||||
AccumulateCategorical(LABELS_AVIF_DECODE_RESULT::out_of_memory);
|
||||
return;
|
||||
case NonDecoderResult::PipeInitError:
|
||||
AccumulateCategorical(LABELS_AVIF_DECODE_RESULT::pipe_init_error);
|
||||
return;
|
||||
}
|
||||
```
|
||||
|
||||
And we update it by adding a call with the FOG API:
|
||||
|
||||
```CPP
|
||||
switch (aResult.as<NonDecoderResult>()) {
|
||||
case NonDecoderResult::SizeOverflow:
|
||||
AccumulateCategorical(LABELS_AVIF_DECODE_RESULT::size_overflow);
|
||||
mozilla::glean::avif::decode_result.EnumGet(avif::DecodeResult::eSizeOverflow).Add();
|
||||
return;
|
||||
case NonDecoderResult::OutOfMemory:
|
||||
AccumulateCategorical(LABELS_AVIF_DECODE_RESULT::out_of_memory);
|
||||
mozilla::glean::avif::decode_result.EnumGet(avif::DecodeResult::eOutOfMemory).Add();
|
||||
return;
|
||||
case NonDecoderResult::PipeInitError:
|
||||
AccumulateCategorical(LABELS_AVIF_DECODE_RESULT::pipe_init_error);
|
||||
mozilla::glean::avif::decode_result.EnumGet(avif::DecodeResult::ePipeInitError).Add();
|
||||
return;
|
||||
}
|
||||
```
|
||||
|
||||
#### Migrating an Accumulated Value (Histogram) in Javascript
|
||||
|
||||
Javascript follows the same pattern. Consider the case when want to record the number
|
||||
of uniqiue site origins. Here's the original JS implementation:
|
||||
|
||||
```Javascript
|
||||
let originCount = this.computeSiteOriginCount(aWindows, aIsGeckoView);
|
||||
let histogram = Services.telemetry.getHistogramById(
|
||||
"FX_NUMBER_OF_UNIQUE_SITE_ORIGINS_ALL_TABS",
|
||||
);
|
||||
|
||||
if (!this._lastRecordSiteOrigin) {
|
||||
this._lastRecordSiteOrigin = currentTime;
|
||||
} else if (currentTime >= this._lastRecordSiteOrigin + this.min_interval) {
|
||||
this._lastRecordSiteOrigin = currentTime;
|
||||
|
||||
histogram.add(originCount);
|
||||
}
|
||||
```
|
||||
|
||||
And here is the direct Glean version
|
||||
|
||||
```Javascript
|
||||
let originCount = this.computeSiteOriginCount(aWindows, aIsGeckoView);
|
||||
|
||||
if (!this._lastRecordSiteOrigin) {
|
||||
this._lastRecordSiteOrigin = currentTime;
|
||||
} else if (currentTime >= this._lastRecordSiteOrigin + this.min_interval) {
|
||||
this._lastRecordSiteOrigin = currentTime;
|
||||
|
||||
Glean.tabs.uniqueSiteOriginsAllTabs.accumulateSamples([originCount]);
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
Note that we don't have to call into Services to get the histogram object.
|
||||
|
||||
### Update the tests to use the Glean test API
|
||||
|
||||
The last piece is updating tests. If tests don't exist
|
||||
(which is often the case since testing metrics collected via GVST can be challenging),
|
||||
we recommend that you write them as the
|
||||
[the Glean test API is quite straightforward](./instrumentation_tests.md).
|
||||
|
||||
The main test method is `testGetValue()`. Returning to our earlier example of
|
||||
Number of Unique Site Origins, in a Javascript test we can invoke:
|
||||
|
||||
```Javascript
|
||||
let result = Glean.tabs.uniqueSiteOriginsAllTabs.testGetValue();
|
||||
|
||||
// This collection is a histogram, we can check the sum for this test
|
||||
Assert.equal(result.sum, 144);
|
||||
```
|
||||
|
||||
If your collection is in a child process, it can be helpful to invoke
|
||||
`await Services.fog.testFlushAllChildren();`
|
||||
|
||||
If you wish to write a C++ test, `testGetValue()` is also our main method:
|
||||
|
||||
```CPP
|
||||
#include "mozilla/glean/GleanMetrics.h"
|
||||
|
||||
ASSERT_EQ(1,
|
||||
mozilla::glean::avif::image_decode_result
|
||||
.EnumGet(avif::DecodeResult::eSizeOverflow)
|
||||
.TestGetValue()
|
||||
.unwrap()
|
||||
.ref());
|
||||
|
||||
ASSERT_EQ(3,
|
||||
mozilla::glean::avif::image_decode_result
|
||||
.EnumGet(avif::DecodeResult::eOutOfMemory)
|
||||
.TestGetValue()
|
||||
.unwrap()
|
||||
.ref());
|
||||
|
||||
ASSERT_EQ(0,
|
||||
mozilla::glean::avif::image_decode_result
|
||||
.EnumGet(avif::DecodeResult::ePipeInitError)
|
||||
.TestGetValue()
|
||||
.unwrap()
|
||||
.ref());
|
||||
```
|
||||
|
||||
[book-of-glean]: https://mozilla.github.io/glean/book/index.html
|
||||
[gv-metrics-yaml]: https://searchfox.org/mozilla-central/source/toolkit/components/telemetry/geckoview/streaming/metrics.yaml
|
||||
[histograms-json]: https://searchfox.org/mozilla-central/source/toolkit/components/telemetry/Histograms.json
|
||||
[scalars-yaml]: https://searchfox.org/mozilla-central/source/toolkit/components/telemetry/Scalars.yaml
|
||||
[new-yaml]: ./new_definitions_file.md#where-do-i-define-new-metrics-and-pings
|
||||
[dr-renewal]: https://github.com/mozilla/data-review/blob/main/renewal_request.md
|
||||
[telemetry-mirror-doc]: https://firefox-source-docs.mozilla.org/toolkit/components/glean/user/gifft.html#the-telemetry-mirror-property-in-metrics-yaml
|
||||
Loading…
Reference in a new issue