зеркало из https://github.com/mozilla/glean.git
Merge pull request #1642 from brizental/1698800-metrics-docs
Bug 1698800 - Update labeled metrics docs to new structure and add Glean.js docs
This commit is contained in:
Коммит
9809b93c13
|
@ -64,6 +64,7 @@ a.header code:hover {
|
|||
border: 1px solid #ccc;
|
||||
border-top: none;
|
||||
padding: 6px 12px;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.tab.active {
|
||||
|
|
|
@ -0,0 +1,26 @@
|
|||
#### `labels`
|
||||
|
||||
Labeled metrics may have an optional `labels` parameter, containing a list of known labels.
|
||||
The labels in this list must match the following requirements:
|
||||
|
||||
* Conform to the [label formatting regular expression](index.md#label-format).
|
||||
|
||||
* Each label must have a maximum of 60 bytes, when encoded as UTF-8.
|
||||
|
||||
* This list itself is limited to 100 labels.
|
||||
|
||||
{{#include ../../shared/blockquote-warning.html}}
|
||||
|
||||
##### Important
|
||||
|
||||
> If the labels are specified in the `metrics.yaml`, using any label not listed in that file
|
||||
> will be replaced with the special value `__other__`.
|
||||
>
|
||||
> If the labels are **not** specified in the `metrics.yaml`, only 16 different dynamic labels
|
||||
> may be used, after which the special value `__other__` will be used.
|
||||
|
||||
Removing or changing labels, including their order in the registry file, is permitted. Avoid reusing labels
|
||||
that were removed in the past. It is best practice to add documentation about removed labels to the
|
||||
description field so that analysts will know of their existence and meaning in historical data.
|
||||
Special care must be taken when changing GeckoView metrics sent through the Glean SDK, as the
|
||||
index of the labels is used to report Gecko data through the Glean SDK.
|
|
@ -2,27 +2,11 @@
|
|||
|
||||
Labeled booleans are used to record different related boolean flags.
|
||||
|
||||
## Configuration
|
||||
## Recording API
|
||||
|
||||
For example, you may want to record a set of flags related to accessibility (a11y).
|
||||
### `set`
|
||||
|
||||
```YAML
|
||||
accessibility:
|
||||
features:
|
||||
type: labeled_boolean
|
||||
description: >
|
||||
a11y features enabled on the device. ...
|
||||
labels:
|
||||
- screen_reader
|
||||
- high_contrast
|
||||
...
|
||||
```
|
||||
|
||||
> **Note:** removing or changing labels, including their order in the registry file, is permitted. Avoid reusing labels that were removed in the past. It is best practice to add documentation about removed labels to the description field so that analysts will know of their existence and meaning in historical data. Special care must be taken when changing GeckoView metrics sent through the Glean SDK, as the index of the labels is used to report Gecko data through the Glean SDK.
|
||||
|
||||
## API
|
||||
|
||||
Now you can use the labeled boolean from the application's code:
|
||||
Sets one of the labels in a labeled boolean metric to a specific value.
|
||||
|
||||
{{#include ../../../shared/tab_header.md}}
|
||||
|
||||
|
@ -30,24 +14,20 @@ Now you can use the labeled boolean from the application's code:
|
|||
|
||||
```Kotlin
|
||||
import org.mozilla.yourApplication.GleanMetrics.Accessibility
|
||||
|
||||
Accessibility.features["screen_reader"].set(isScreenReaderEnabled())
|
||||
Accessibility.features["high_contrast"].set(isHighContrastEnabled())
|
||||
```
|
||||
</div>
|
||||
|
||||
There are test APIs available too:
|
||||
<div data-lang="Java" class="tab">
|
||||
|
||||
```Kotlin
|
||||
import org.mozilla.yourApplication.GleanMetrics.Accessibility
|
||||
// Was anything recorded?
|
||||
assertTrue(Accessibility.features["screen_reader"].testHasValue())
|
||||
assertTrue(Accessibility.features["high_contrast"].testHasValue())
|
||||
// Do the booleans have the expected values?
|
||||
assertEquals(True, Accessibility.features["screen_reader"].testGetValue())
|
||||
assertEquals(False, Accessibility.features["high_contrast"].testGetValue())
|
||||
// Did we record any invalid labels?
|
||||
assertEquals(0, Accessibility.features.testGetNumRecordedErrors(ErrorType.InvalidLabel))
|
||||
```Java
|
||||
import org.mozilla.yourApplication.GleanMetrics.Accessibility;
|
||||
|
||||
Acessibility.INSTANCE.features["screen_reader"].set(isScreenReaderEnabled());
|
||||
Acessibility.INSTANCE.features["high_contrast"].set(isHighContrastEnabled());
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
<div data-lang="Swift" class="tab">
|
||||
|
@ -56,22 +36,6 @@ assertEquals(0, Accessibility.features.testGetNumRecordedErrors(ErrorType.Invali
|
|||
Accessibility.features["screen_reader"].set(isScreenReaderEnabled())
|
||||
Accessibility.features["high_contrast"].set(isHighContrastEnabled())
|
||||
```
|
||||
|
||||
There are test APIs available too:
|
||||
|
||||
```Swift
|
||||
@testable import Glean
|
||||
|
||||
// Was anything recorded?
|
||||
XCTAssert(Accessibility.features["screen_reader"].testHasValue())
|
||||
XCTAssert(Accessibility.features["high_contrast"].testHasValue())
|
||||
// Do the booleans have the expected values?
|
||||
XCTAssertEqual(true, try Accessibility.features["screen_reader"].testGetValue())
|
||||
XCTAssertEqual(false, try Accessibility.features["high_contrast"].testGetValue())
|
||||
// Were there any invalid labels?
|
||||
XCTAssertEqual(0, Accessibility.features.testGetNumRecordedErrors(.invalidLabel))
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
<div data-lang="Python" class="tab">
|
||||
|
@ -80,54 +44,9 @@ XCTAssertEqual(0, Accessibility.features.testGetNumRecordedErrors(.invalidLabel)
|
|||
from glean import load_metrics
|
||||
metrics = load_metrics("metrics.yaml")
|
||||
|
||||
metrics.accessibility.features["screen_reader"].set(
|
||||
is_screen_reader_enabled()
|
||||
)
|
||||
metrics.accessibility.features["high_contrast"].set(
|
||||
is_high_contrast_enabled()
|
||||
)
|
||||
metrics.accessibility.features["screen_reader"].set(is_screen_reader_enabled())
|
||||
metrics.accessibility.features["high_contrast"].set(is_high_contrast_enabled())
|
||||
```
|
||||
|
||||
There are test APIs available too:
|
||||
|
||||
```Python
|
||||
# Was anything recorded?
|
||||
assert metrics.accessibility.features["screen_reader"].test_has_value()
|
||||
assert metrics.accessibility.features["high_contrast"].test_has_value()
|
||||
# Do the booleans have the expected values?
|
||||
assert metrics.accessibility.features["screen_reader"].test_get_value()
|
||||
assert not metrics.accessibility.features["high_contrast"].test_get_value()
|
||||
# Did we record any invalid labels?
|
||||
assert 0 == metrics.accessibility.features.test_get_num_recorded_errors(
|
||||
ErrorType.INVALID_LABEL
|
||||
)
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
<div data-lang="C#" class="tab">
|
||||
|
||||
```C#
|
||||
using static Mozilla.YourApplication.GleanMetrics.Accessibility;
|
||||
|
||||
Accessibility.features["screen_reader"].Set(isScreenReaderEnabled());
|
||||
Accessibility.features["high_contrast"].Set(isHighContrastEnabled());
|
||||
```
|
||||
|
||||
There are test APIs available too:
|
||||
|
||||
```C#
|
||||
using static Mozilla.YourApplication.GleanMetrics.Accessibility;
|
||||
// Was anything recorded?
|
||||
Assert.True(Accessibility.features["screen_reader"].TestHasValue());
|
||||
Assert.True(Accessibility.features["high_contrast"].TestHasValue());
|
||||
// Do the booleans have the expected values?
|
||||
Assert.Equal(true, Accessibility.features["screen_reader"].TestGetValue());
|
||||
Assert.Equal(false, Accessibility.features["high_contrast"].TestGetValue());
|
||||
// Did we record any invalid labels?
|
||||
Assert.Equal(0, Accessibility.features.TestGetNumRecordedErrors(ErrorType.InvalidLabel));
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
<div data-lang="Rust" class="tab">
|
||||
|
@ -138,20 +57,222 @@ use glean_metrics;
|
|||
accessibility::features.get("screen_reader").set(is_screen_reader_enabled());
|
||||
accessibility::features.get("high_contrast").set(is_high_contrast_enabled());
|
||||
```
|
||||
</div>
|
||||
|
||||
There are test APIs available too:
|
||||
<div data-lang="Javascript" class="tab">
|
||||
|
||||
```js
|
||||
import * as acessibility from "./path/to/generated/files/acessibility.js";
|
||||
|
||||
acessibility.features["screen_reader"].set(this.isScreenReaderEnabled());
|
||||
acessibility.features["high_contrast"].set(this.isHighContrastEnabled());
|
||||
```
|
||||
</div>
|
||||
|
||||
<div data-lang="Firefox Desktop" class="tab"></div>
|
||||
|
||||
{{#include ../../../shared/tab_footer.md}}
|
||||
|
||||
#### Recorded Errors
|
||||
|
||||
* [`invalid_label`](../../user/metrics/error-reporting.md):
|
||||
* If the label contains invalid characters. Data is still recorded to the special label `__other__`.
|
||||
* If the label exceeds the maximum number of allowed characters. Data is still recorded to the special label `__other__`.
|
||||
|
||||
## Testing API
|
||||
|
||||
### `testGetValue`
|
||||
|
||||
Gets the recorded value for a given label in a labeled boolean metric.
|
||||
|
||||
{{#include ../../../shared/tab_header.md}}
|
||||
|
||||
<div data-lang="Kotlin" class="tab">
|
||||
|
||||
```Kotlin
|
||||
import org.mozilla.yourApplication.GleanMetrics.Accessibility
|
||||
|
||||
// Do the booleans have the expected values?
|
||||
assertEquals(True, Accessibility.features["screen_reader"].testGetValue())
|
||||
assertEquals(False, Accessibility.features["high_contrast"].testGetValue())
|
||||
```
|
||||
</div>
|
||||
|
||||
<div data-lang="Java" class="tab">
|
||||
|
||||
```Java
|
||||
import org.mozilla.yourApplication.GleanMetrics.Accessibility;
|
||||
|
||||
// Do the booleans have the expected values?
|
||||
assertEquals(True, Acessibility.INSTANCE.features["screen_reader"].testGetValue());
|
||||
assertEquals(False, Acessibility.INSTANCE.features["high_contrast"].testGetValue());
|
||||
```
|
||||
</div>
|
||||
|
||||
<div data-lang="Swift" class="tab">
|
||||
|
||||
```Swift
|
||||
@testable import Glean
|
||||
|
||||
// Do the booleans have the expected values?
|
||||
XCTAssertEqual(true, try Accessibility.features["screen_reader"].testGetValue())
|
||||
XCTAssertEqual(false, try Accessibility.features["high_contrast"].testGetValue())
|
||||
```
|
||||
</div>
|
||||
|
||||
<div data-lang="Python" class="tab">
|
||||
|
||||
```Python
|
||||
from glean import load_metrics
|
||||
metrics = load_metrics("metrics.yaml")
|
||||
|
||||
# Do the booleans have the expected values?
|
||||
assert metrics.accessibility.features["screen_reader"].test_get_value()
|
||||
assert not metrics.accessibility.features["high_contrast"].test_get_value()
|
||||
```
|
||||
</div>
|
||||
|
||||
<div data-lang="Rust" class="tab">
|
||||
|
||||
```rust
|
||||
use glean_metrics;
|
||||
|
||||
// Do the booleans have the expected values?
|
||||
assert!(accessibility::features.get("screen_reader").test_get_value(None).unwrap());
|
||||
assert!(!accessibility::features.get("high_contrast").test_get_value(None).unwrap());
|
||||
```
|
||||
</div>
|
||||
|
||||
<div data-lang="Javascript" class="tab">
|
||||
|
||||
```js
|
||||
import * as accessibility from "./path/to/generated/files/acessibility.js";
|
||||
|
||||
assert(await accessibility.features["screen_reader"].testGetValue());
|
||||
assert(!(await accessibility.features["high_contrast"].testGetValue()));
|
||||
```
|
||||
</div>
|
||||
|
||||
<div data-lang="Firefox Desktop" class="tab"></div>
|
||||
|
||||
{{#include ../../../shared/tab_footer.md}}
|
||||
|
||||
### `testHasValue`
|
||||
|
||||
Whether or not **any** value was recorded for a given label in a labeled boolean metric.
|
||||
|
||||
{{#include ../../../shared/tab_header.md}}
|
||||
|
||||
<div data-lang="Kotlin" class="tab">
|
||||
|
||||
```Kotlin
|
||||
import org.mozilla.yourApplication.GleanMetrics.Accessibility
|
||||
|
||||
// Was anything recorded?
|
||||
assertTrue(Accessibility.features["screen_reader"].testHasValue())
|
||||
assertTrue(Accessibility.features["high_contrast"].testHasValue())
|
||||
```
|
||||
</div>
|
||||
|
||||
<div data-lang="Java" class="tab">
|
||||
|
||||
```Java
|
||||
import org.mozilla.yourApplication.GleanMetrics.Accessibility;
|
||||
|
||||
// Was anything recorded?
|
||||
assertEquals(True, Acessibility.INSTANCE.features["screen_reader"].testHasValue());
|
||||
assertEquals(True, Acessibility.INSTANCE.features["high_contrast"].testHasValue());
|
||||
```
|
||||
</div>
|
||||
|
||||
|
||||
<div data-lang="Swift" class="tab">
|
||||
|
||||
```Swift
|
||||
@testable import Glean
|
||||
|
||||
// Was anything recorded?
|
||||
XCTAssert(Accessibility.features["screen_reader"].testHasValue())
|
||||
XCTAssert(Accessibility.features["high_contrast"].testHasValue())
|
||||
```
|
||||
</div>
|
||||
|
||||
<div data-lang="Python" class="tab">
|
||||
|
||||
```Python
|
||||
from glean import load_metrics
|
||||
metrics = load_metrics("metrics.yaml")
|
||||
|
||||
# Was anything recorded?
|
||||
assert metrics.accessibility.features["screen_reader"].test_has_value()
|
||||
assert metrics.accessibility.features["high_contrast"].test_has_value()
|
||||
```
|
||||
</div>
|
||||
|
||||
<div data-lang="Rust" class="tab"></div>
|
||||
|
||||
<div data-lang="Javascript" class="tab"></div>
|
||||
|
||||
<div data-lang="Firefox Desktop" class="tab"></div>
|
||||
|
||||
{{#include ../../../shared/tab_footer.md}}
|
||||
|
||||
### `testGetNumRecordedErrors`
|
||||
|
||||
Gets the number of errors recorded for a given labeled boolean metric in total.
|
||||
|
||||
{{#include ../../../shared/tab_header.md}}
|
||||
|
||||
<div data-lang="Kotlin" class="tab">
|
||||
|
||||
```Kotlin
|
||||
import org.mozilla.yourApplication.GleanMetrics.Accessibility
|
||||
|
||||
// Did we record any invalid labels?
|
||||
assertEquals(0, Accessibility.features.testGetNumRecordedErrors(ErrorType.InvalidLabel))
|
||||
```
|
||||
</div>
|
||||
|
||||
<div data-lang="Java" class="tab">
|
||||
|
||||
```Java
|
||||
import org.mozilla.yourApplication.GleanMetrics.Accessibility;
|
||||
|
||||
// Did we record any invalid labels?
|
||||
assertEquals(0, Acessibility.INSTANCE.features.testGetNumRecordedErrors());
|
||||
```
|
||||
</div>
|
||||
|
||||
<div data-lang="Swift" class="tab">
|
||||
|
||||
```Swift
|
||||
@testable import Glean
|
||||
|
||||
// Were there any invalid labels?
|
||||
XCTAssertEqual(0, Accessibility.features.testGetNumRecordedErrors(.invalidLabel))
|
||||
```
|
||||
</div>
|
||||
|
||||
<div data-lang="Python" class="tab">
|
||||
|
||||
```Python
|
||||
from glean import load_metrics
|
||||
metrics = load_metrics("metrics.yaml")
|
||||
|
||||
# Did we record any invalid labels?
|
||||
assert 0 == metrics.accessibility.features.test_get_num_recorded_errors(
|
||||
ErrorType.INVALID_LABEL
|
||||
)
|
||||
```
|
||||
</div>
|
||||
|
||||
<div data-lang="Rust" class="tab">
|
||||
|
||||
```rust
|
||||
use glean::ErrorType;
|
||||
|
||||
use glean_metrics;
|
||||
|
||||
// Was anything recorded?
|
||||
assert!(accessibility::features.get("screen_reader").test_get_value(None).is_some());
|
||||
assert!(accessibility::features.get("high_contrast").test_get_value(None).is_some());
|
||||
// Do the booleans have the expected values?
|
||||
assert!(accessibility::features.get("screen_reader").test_get_value(None).unwrap());
|
||||
assert!(!accessibility::features.get("high_contrast").test_get_value(None).unwrap());
|
||||
// Did we record any invalid labels?
|
||||
assert_eq!(
|
||||
1,
|
||||
|
@ -160,37 +281,56 @@ assert_eq!(
|
|||
)
|
||||
);
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
<div data-lang="Javascript" class="tab">
|
||||
|
||||
```js
|
||||
import * as accessibility from "./path/to/generated/files/acessibility.js";
|
||||
|
||||
assert(await accessibility.features.testGetNumRecordedErrors("invalid_label"));
|
||||
```
|
||||
</div>
|
||||
|
||||
<div data-lang="Firefox Desktop" class="tab"></div>
|
||||
|
||||
{{#include ../../../shared/tab_footer.md}}
|
||||
|
||||
## Limits
|
||||
## Metric parameters
|
||||
|
||||
* Labels must conform to the [label formatting regular expression](index.md#label-format).
|
||||
Example labeled boolean metric definition:
|
||||
|
||||
* Labels support lowercase alphanumeric characters; they additionally allow for dots (`.`), underscores (`_`) and/or hyphens (`-`).
|
||||
```YAML
|
||||
accessibility:
|
||||
features:
|
||||
type: labeled_boolean
|
||||
description: >
|
||||
a11y features enabled on the device.
|
||||
bugs:
|
||||
- https://bugzilla.mozilla.org/000000
|
||||
data_reviews:
|
||||
- https://bugzilla.mozilla.org/show_bug.cgi?id=000000#c3
|
||||
notification_emails:
|
||||
- me@mozilla.com
|
||||
expires: 2020-10-01
|
||||
labels:
|
||||
- screen_reader
|
||||
- high_contrast
|
||||
...
|
||||
```
|
||||
|
||||
* Each label must have a maximum of 60 bytes, when encoded as UTF-8.
|
||||
### Extra metric parameters
|
||||
|
||||
* If the labels are specified in the `metrics.yaml`, using any label not listed in that file will be replaced with the special value `__other__`.
|
||||
{{#include ../../_includes/labels-parameter.md}}
|
||||
|
||||
* The number of labels specified in the `metrics.yaml` is limited to 100.
|
||||
## Data questions
|
||||
|
||||
* If the labels aren't specified in the `metrics.yaml`, only 16 different dynamic labels may be used, after which the special value `__other__` will be used.
|
||||
|
||||
## Examples
|
||||
|
||||
* Record a related set of boolean flags.
|
||||
|
||||
## Recorded Errors
|
||||
|
||||
* `invalid_label`: If the label contains invalid characters. Data is still recorded to the special label `__other__`.
|
||||
|
||||
* `invalid_label`: If the label exceeds the maximum number of allowed characters. Data is still recorded to the special label `__other__`.
|
||||
* Which accessibility features are enabled?
|
||||
|
||||
## Reference
|
||||
|
||||
* Kotlin API docs [`LabeledMetricType`](../../../javadoc/glean/mozilla.telemetry.glean.private/-labeled-metric-type/index.html), [`BooleanMetricType`](../../../javadoc/glean/mozilla.telemetry.glean.private/-boolean-metric-type/index.html)
|
||||
* Swift API docs: [`LabeledMetricType`](../../../swift/Classes/LabeledMetricType.html), [`BooleanMetricType`](../../../swift/Classes/BooleanMetricType.html)
|
||||
* Python API docs: [`LabeledMetricBase`](../../../python/glean/metrics/labeled.html), [`BooleanMetricType`](../../../python/glean/metrics/boolean.html)
|
||||
* Rust API docs: [`LabeledMetric`](../../../docs/glean/private/struct.LabeledMetric.html), [`BooleanMetricType`](../../../docs/glean/private/struct.BooleanMetric.html)
|
||||
* Javascript API docs: [`LabeledMetricType`](https://mozilla.github.io/glean.js/classes/core_metrics_types_labeled.default.html), [`BooleanMetricType`](https://mozilla.github.io/glean.js/classes/core_metrics_types_boolean.default.html)
|
||||
|
|
|
@ -6,28 +6,12 @@ Each time you record to a labeled counter, its value is incremented.
|
|||
Unless incremented by a positive value, a counter will not be reported in pings,
|
||||
that means: the value `0` is never sent in a ping.
|
||||
|
||||
## Recording API
|
||||
|
||||
## Configuration
|
||||
### `add`
|
||||
|
||||
For example, you may want to record a count of different types of crashes for your Android application, such as native code crashes and uncaught exceptions:
|
||||
|
||||
```YAML
|
||||
stability:
|
||||
crash_count:
|
||||
type: labeled_counter
|
||||
description: >
|
||||
Counts the number of crashes that occur in the application. ...
|
||||
labels:
|
||||
- uncaught_exception
|
||||
- native_code_crash
|
||||
...
|
||||
```
|
||||
|
||||
> **Note:** removing or changing labels, including their order in the registry file, is permitted. Avoid reusing labels that were removed in the past. It is best practice to add documentation about removed labels to the description field so that analysts will know of their existence and meaning in historical data. Special care must be taken when changing GeckoView metrics sent through the Glean SDK, as the index of the labels is used to report Gecko data through the Glean SDK.
|
||||
|
||||
## API
|
||||
|
||||
Now you can use the labeled counter from the application's code:
|
||||
Increases one of the labels in a labeled counter metric by a certain amount.
|
||||
If no amount is passed it defaults to `1`.
|
||||
|
||||
{{#include ../../../shared/tab_header.md}}
|
||||
|
||||
|
@ -35,24 +19,20 @@ Now you can use the labeled counter from the application's code:
|
|||
|
||||
```Kotlin
|
||||
import org.mozilla.yourApplication.GleanMetrics.Stability
|
||||
|
||||
Stability.crashCount["uncaught_exception"].add() // Adds 1 to the "uncaught_exception" counter.
|
||||
Stability.crashCount["native_code_crash"].add(3) // Adds 3 to the "native_code_crash" counter.
|
||||
```
|
||||
</div>
|
||||
|
||||
There are test APIs available too:
|
||||
<div data-lang="Java" class="tab">
|
||||
|
||||
```Kotlin
|
||||
import org.mozilla.yourApplication.GleanMetrics.Stability
|
||||
// Was anything recorded?
|
||||
assertTrue(Stability.crashCount["uncaught_exception"].testHasValue())
|
||||
assertTrue(Stability.crashCount["native_code_crash"].testHasValue())
|
||||
// Do the counters have the expected values?
|
||||
assertEquals(1, Stability.crashCount["uncaught_exception"].testGetValue())
|
||||
assertEquals(3, Stability.crashCount["native_code_crash"].testGetValue())
|
||||
// Were there any invalid labels?
|
||||
assertEquals(0, Stability.crashCount.testGetNumRecordedErrors(ErrorType.InvalidLabel))
|
||||
```Java
|
||||
import org.mozilla.yourApplication.GleanMetrics.Stability;
|
||||
|
||||
Stability.INSTANCE.crashCount["uncaught_exception"].add(); // Adds 1 to the "uncaught_exception" counter.
|
||||
Stability.INSTANCE.crashCount["native_code_crash"].add(3); // Adds 3 to the "native_code_crash" counter.
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
<div data-lang="Swift" class="tab">
|
||||
|
@ -61,22 +41,6 @@ assertEquals(0, Stability.crashCount.testGetNumRecordedErrors(ErrorType.InvalidL
|
|||
Stability.crashCount["uncaught_exception"].add() // Adds 1 to the "uncaught_exception" counter.
|
||||
Stability.crashCount["native_code_crash"].add(3) // Adds 3 to the "native_code_crash" counter.
|
||||
```
|
||||
|
||||
There are test APIs available too:
|
||||
|
||||
```Swift
|
||||
@testable import Glean
|
||||
|
||||
// Was anything recorded?
|
||||
XCTAssert(Stability.crashCount["uncaught_exception"].testHasValue())
|
||||
XCTAssert(Stability.crashCount["native_code_crash"].testHasValue())
|
||||
// Do the counters have the expected values?
|
||||
XCTAssertEqual(1, try Stability.crashCount["uncaught_exception"].testGetValue())
|
||||
XCTAssertEqual(3, try Stability.crashCount["native_code_crash"].testGetValue())
|
||||
// Were there any invalid labels?
|
||||
XCTAssertEqual(0, Stability.crashCount.testGetNumRecordedErrors(.invalidLabel))
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
<div data-lang="Python" class="tab">
|
||||
|
@ -90,46 +54,6 @@ metrics.stability.crash_count["uncaught_exception"].add()
|
|||
# Adds 3 to the "native_code_crash" counter.
|
||||
metrics.stability.crash_count["native_code_crash"].add(3)
|
||||
```
|
||||
|
||||
There are test APIs available too:
|
||||
|
||||
```Python
|
||||
# Was anything recorded?
|
||||
assert metrics.stability.crash_count["uncaught_exception"].test_has_value()
|
||||
assert metrics.stability.crash_count["native_code_crash"].test_has_value()
|
||||
# Do the counters have the expected values?
|
||||
assert 1 == metrics.stability.crash_count["uncaught_exception"].test_get_value()
|
||||
assert 3 == metrics.stability.crash_count["native_code_crash"].test_get_value()
|
||||
# Were there any invalid labels?
|
||||
assert 0 == metrics.stability.crash_count.test_get_num_recorded_errors(
|
||||
ErrorType.INVALID_LABEL
|
||||
)
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
<div data-lang="C#" class="tab">
|
||||
|
||||
```C#
|
||||
using static Mozilla.YourApplication.GleanMetrics.Stability;
|
||||
Stability.crashCount["uncaught_exception"].Add(); // Adds 1 to the "uncaught_exception" counter.
|
||||
Stability.crashCount["native_code_crash"].Add(3); // Adds 3 to the "native_code_crash" counter.
|
||||
```
|
||||
|
||||
There are test APIs available too:
|
||||
|
||||
```C#
|
||||
using static Mozilla.YourApplication.GleanMetrics.Stability;
|
||||
// Was anything recorded?
|
||||
Assert.True(Stability.crashCount["uncaught_exception"].TestHasValue());
|
||||
Assert.True(Stability.crashCount["native_code_crash"].TestHasValue());
|
||||
// Do the counters have the expected values?
|
||||
Assert.Equal(1, Stability.crashCount["uncaught_exception"].TestGetValue());
|
||||
Assert.Equal(3, Stability.crashCount["native_code_crash"].TestGetValue());
|
||||
// Were there any invalid labels?
|
||||
Assert.Equal(0, Stability.crashCount.TestGetNumRecordedErrors(ErrorType.InvalidLabel));
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
<div data-lang="Rust" class="tab">
|
||||
|
@ -140,19 +64,230 @@ use glean_metrics;
|
|||
stability::crash_count.get("uncaught_exception").add(1); // Adds 1 to the "uncaught_exception" counter.
|
||||
stability::crash_count.get("native_code_crash").add(3); // Adds 3 to the "native_code_crash" counter.
|
||||
```
|
||||
</div>
|
||||
|
||||
There are test APIs available too:
|
||||
<div data-lang="Javascript" class="tab">
|
||||
|
||||
```js
|
||||
import * as stability from "./path/to/generated/files/stability.js";
|
||||
|
||||
// Adds 1 to the "uncaught_exception" counter.
|
||||
stability.crashCount["uncaught_exception"].add();
|
||||
// Adds 3 to the "native_code_crash" counter.
|
||||
stability.crashCount["native_code_crash"].add(3);
|
||||
```
|
||||
</div>
|
||||
|
||||
<div data-lang="Firefox Desktop" class="tab"></div>
|
||||
|
||||
{{#include ../../../shared/tab_footer.md}}
|
||||
|
||||
#### Errors recorded
|
||||
|
||||
* [`invalid_value`](../../user/metrics/error-reporting.md): If the counter is incremented by `0` or a negative value.
|
||||
* [`invalid_label`](../../user/metrics/error-reporting.md):
|
||||
* If the label contains invalid characters. Data is still recorded to the special label `__other__`.
|
||||
* If the label exceeds the maximum number of allowed characters. Data is still recorded to the special label `__other__`.
|
||||
|
||||
#### Limits
|
||||
|
||||
* Only increments;
|
||||
* Saturates at the largest value that can be represented as a 32-bit signed integer.
|
||||
|
||||
## Testing API
|
||||
|
||||
### `testGetValue`
|
||||
|
||||
Gets the recorded value for a given label in a labeled counter metric.
|
||||
|
||||
{{#include ../../../shared/tab_header.md}}
|
||||
|
||||
<div data-lang="Kotlin" class="tab">
|
||||
|
||||
```Kotlin
|
||||
import org.mozilla.yourApplication.GleanMetrics.Stability
|
||||
|
||||
// Do the counters have the expected values?
|
||||
assertEquals(1, Stability.crashCount["uncaught_exception"].testGetValue())
|
||||
assertEquals(3, Stability.crashCount["native_code_crash"].testGetValue())
|
||||
```
|
||||
</div>
|
||||
|
||||
<div data-lang="Java" class="tab">
|
||||
|
||||
```Java
|
||||
import org.mozilla.yourApplication.GleanMetrics.Stability;
|
||||
|
||||
// Do the counters have the expected values?
|
||||
assertEquals(1, Stability.INSTANCE.crashCount["uncaught_exception"].testGetValue());
|
||||
assertEquals(3, Stability.INSTANCE.crashCount["native_code_crash"].testGetValue());
|
||||
```
|
||||
</div>
|
||||
|
||||
<div data-lang="Swift" class="tab">
|
||||
|
||||
```Swift
|
||||
@testable import Glean
|
||||
|
||||
// Do the counters have the expected values?
|
||||
XCTAssertEqual(1, try Stability.crashCount["uncaught_exception"].testGetValue())
|
||||
XCTAssertEqual(3, try Stability.crashCount["native_code_crash"].testGetValue())
|
||||
```
|
||||
</div>
|
||||
|
||||
<div data-lang="Python" class="tab">
|
||||
|
||||
```Python
|
||||
from glean import load_metrics
|
||||
metrics = load_metrics("metrics.yaml")
|
||||
|
||||
# Do the counters have the expected values?
|
||||
assert 1 == metrics.stability.crash_count["uncaught_exception"].test_get_value()
|
||||
assert 3 == metrics.stability.crash_count["native_code_crash"].test_get_value()
|
||||
```
|
||||
</div>
|
||||
|
||||
<div data-lang="Rust" class="tab">
|
||||
|
||||
```rust
|
||||
use glean_metrics;
|
||||
|
||||
// Do the counters have the expected values?
|
||||
assert_eq!(1, stability::crash_count.get("uncaught_exception").test_get_value().unwrap());
|
||||
assert_eq!(3, stability::crash_count.get("native_code_crash").test_get_value().unwrap());
|
||||
```
|
||||
</div>
|
||||
|
||||
<div data-lang="Javascript" class="tab">
|
||||
|
||||
```js
|
||||
import * as stability from "./path/to/generated/files/stability.js";
|
||||
|
||||
// Do the counters have the expected values?
|
||||
assert.strictEqual(1, await stability.crashCount["uncaught_exception"].testGetValue());
|
||||
assert.strictEqual(3, await stability.crashCount["native_code_crash"].testGetValue());
|
||||
```
|
||||
</div>
|
||||
|
||||
<div data-lang="Firefox Desktop" class="tab"></div>
|
||||
|
||||
{{#include ../../../shared/tab_footer.md}}
|
||||
|
||||
### `testHasValue`
|
||||
|
||||
Whether or not **any** value was recorded for a given label in a labeled counter metric.
|
||||
|
||||
{{#include ../../../shared/tab_header.md}}
|
||||
|
||||
<div data-lang="Kotlin" class="tab">
|
||||
|
||||
```Kotlin
|
||||
import org.mozilla.yourApplication.GleanMetrics.Stability
|
||||
|
||||
// Was anything recorded?
|
||||
assertTrue(Stability.crashCount["uncaught_exception"].testHasValue())
|
||||
assertTrue(Stability.crashCount["native_code_crash"].testHasValue())
|
||||
```
|
||||
</div>
|
||||
|
||||
<div data-lang="Java" class="tab">
|
||||
|
||||
```Java
|
||||
import org.mozilla.yourApplication.GleanMetrics.Stability;
|
||||
|
||||
// Was anything recorded?
|
||||
assertTrue(Stability.INSTANCE.crashCount["uncaught_exception"].testHasValue());
|
||||
assertTrue(Stability.INSTANCE.crashCount["native_code_crash"].testHasValue());
|
||||
```
|
||||
</div>
|
||||
|
||||
<div data-lang="Swift" class="tab">
|
||||
|
||||
```Swift
|
||||
@testable import Glean
|
||||
|
||||
// Was anything recorded?
|
||||
XCTAssert(Stability.crashCount["uncaught_exception"].testHasValue())
|
||||
XCTAssert(Stability.crashCount["native_code_crash"].testHasValue())
|
||||
```
|
||||
</div>
|
||||
|
||||
<div data-lang="Python" class="tab">
|
||||
|
||||
```Python
|
||||
from glean import load_metrics
|
||||
metrics = load_metrics("metrics.yaml")
|
||||
|
||||
# Was anything recorded?
|
||||
assert metrics.stability.crash_count["uncaught_exception"].test_has_value()
|
||||
assert metrics.stability.crash_count["native_code_crash"].test_has_value()
|
||||
```
|
||||
</div>
|
||||
|
||||
<div data-lang="Rust" class="tab"></div>
|
||||
|
||||
<div data-lang="Javascript" class="tab"></div>
|
||||
|
||||
<div data-lang="Firefox Desktop" class="tab"></div>
|
||||
|
||||
{{#include ../../../shared/tab_footer.md}}
|
||||
|
||||
### `testGetNumRecordedErrors`
|
||||
|
||||
Gets the number of errors recorded for a given labeled counter metric in total.
|
||||
|
||||
{{#include ../../../shared/tab_header.md}}
|
||||
|
||||
<div data-lang="Kotlin" class="tab">
|
||||
|
||||
```Kotlin
|
||||
import org.mozilla.yourApplication.GleanMetrics.Stabilit
|
||||
|
||||
// Were there any invalid labels?
|
||||
assertEquals(0, Stability.crashCount.testGetNumRecordedErrors(ErrorType.InvalidLabel))
|
||||
```
|
||||
</div>
|
||||
|
||||
<div data-lang="Java" class="tab">
|
||||
|
||||
```Java
|
||||
import org.mozilla.yourApplication.GleanMetrics.Stability;
|
||||
|
||||
// Were there any invalid labels?
|
||||
assertEquals(0, Stability.INSTANCE.crashCount.testGetNumRecordedErrors(ErrorType.InvalidLabel));
|
||||
```
|
||||
</div>
|
||||
|
||||
<div data-lang="Swift" class="tab">
|
||||
|
||||
```Swift
|
||||
@testable import Glean
|
||||
|
||||
// Were there any invalid labels?
|
||||
XCTAssertEqual(0, Stability.crashCount.testGetNumRecordedErrors(.invalidLabel))
|
||||
```
|
||||
</div>
|
||||
|
||||
<div data-lang="Python" class="tab">
|
||||
|
||||
```Python
|
||||
from glean import load_metrics
|
||||
metrics = load_metrics("metrics.yaml")
|
||||
|
||||
# Were there any invalid labels?
|
||||
assert 0 == metrics.stability.crash_count.test_get_num_recorded_errors(
|
||||
ErrorType.INVALID_LABEL
|
||||
)
|
||||
```
|
||||
</div>
|
||||
|
||||
<div data-lang="Rust" class="tab">
|
||||
|
||||
```rust
|
||||
use glean::ErrorType;
|
||||
|
||||
use glean_metrics;
|
||||
// Was anything recorded?
|
||||
assert!(stability::crash_count.get("uncaught_exception").test_get_value().is_some());
|
||||
assert!(stability::crash_count.get("native_code_crash").test_get_value().is_some());
|
||||
// Do the counters have the expected values?
|
||||
assert_eq!(1, stability::crash_count.get("uncaught_exception").test_get_value().unwrap());
|
||||
assert_eq!(3, stability::crash_count.get("native_code_crash").test_get_value().unwrap());
|
||||
|
||||
// Were there any invalid labels?
|
||||
assert_eq!(
|
||||
0,
|
||||
|
@ -161,37 +296,57 @@ assert_eq!(
|
|||
)
|
||||
);
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
<div data-lang="Javascript" class="tab">
|
||||
|
||||
```js
|
||||
import * as stability from "./path/to/generated/files/stability.js";
|
||||
|
||||
// Were there any invalid labels?
|
||||
assert.strictEqual(0, await stability.crashCount.testGetNumRecordedErrors("invalid_label"));
|
||||
```
|
||||
</div>
|
||||
|
||||
<div data-lang="Firefox Desktop" class="tab"></div>
|
||||
|
||||
{{#include ../../../shared/tab_footer.md}}
|
||||
|
||||
## Limits
|
||||
## Metric parameters
|
||||
|
||||
* Labels must conform to the [label formatting regular expression](index.md#label-format).
|
||||
Example labeled counter metric definition:
|
||||
|
||||
* Labels support lowercase alphanumeric characters; they additionally allow for dots (`.`), underscores (`_`) and/or hyphens (`-`).
|
||||
```YAML
|
||||
accessibility:
|
||||
features:
|
||||
type: labeled_counter
|
||||
description: >
|
||||
Counts the number of crashes that occur in the application.
|
||||
bugs:
|
||||
- https://bugzilla.mozilla.org/000000
|
||||
data_reviews:
|
||||
- https://bugzilla.mozilla.org/show_bug.cgi?id=000000#c3
|
||||
notification_emails:
|
||||
- me@mozilla.com
|
||||
expires: 2020-10-01
|
||||
labels:
|
||||
- uncaught_exception
|
||||
- native_code_crash
|
||||
...
|
||||
```
|
||||
|
||||
* Each label must have a maximum of 60 bytes, when encoded as UTF-8.
|
||||
### Extra metric parameters
|
||||
|
||||
* If the labels are specified in the `metrics.yaml`, using any label not listed in that file will be replaced with the special value `__other__`.
|
||||
{{#include ../../_includes/labels-parameter.md}}
|
||||
|
||||
* The number of labels specified in the `metrics.yaml` is limited to 100.
|
||||
## Data questions
|
||||
|
||||
* If the labels aren't specified in the `metrics.yaml`, only 16 different dynamic labels may be used, after which the special value `__other__` will be used.
|
||||
|
||||
## Examples
|
||||
|
||||
* Record the number of times different kinds of crashes occurred.
|
||||
|
||||
## Recorded Errors
|
||||
|
||||
* `invalid_label`: If the label contains invalid characters. Data is still recorded to the special label `__other__`.
|
||||
|
||||
* `invalid_label`: If the label exceeds the maximum number of allowed characters. Data is still recorded to the special label `__other__`.
|
||||
* How many times did different types of crashes occur?
|
||||
|
||||
## Reference
|
||||
|
||||
* Kotlin API docs [`LabeledMetricType`](../../../javadoc/glean/mozilla.telemetry.glean.private/-labeled-metric-type/index.html), [`CounterMetricType`](../../../javadoc/glean/mozilla.telemetry.glean.private/-counter-metric-type/index.html)
|
||||
* Swift API docs: [`LabeledMetricType`](../../../swift/Classes/LabeledMetricType.html), [`CounterMetricType`](../../../swift/Classes/CounterMetricType.html)
|
||||
* Python API docs: [`LabeledMetricBase`](../../../python/glean/metrics/labeled.html), [`CounterMetricType`](../../../python/glean/metrics/counter.html)
|
||||
* Rust API docs: [`LabeledMetric`](../../../docs/glean/private/struct.LabeledMetric.html), [`CounterMetricType`](../../../docs/glean/private/struct.CounterMetric.html)
|
||||
* Javascript API docs: [`LabeledMetricType`](https://mozilla.github.io/glean.js/classes/core_metrics_types_labeled.default.html), [`CounterMetricType`](https://mozilla.github.io/glean.js/classes/core_metrics_types_counter.default.html)
|
||||
|
|
|
@ -2,24 +2,11 @@
|
|||
|
||||
Labeled strings record multiple Unicode string values, each under a different label.
|
||||
|
||||
## Configuration
|
||||
## Recording API
|
||||
|
||||
For example to record which kind of error occurred in different stages of a login process - `"RuntimeException"` in the `"server_auth"` stage or `"invalid_string"` in the `"enter_email"` stage:
|
||||
### `set`
|
||||
|
||||
```YAML
|
||||
login:
|
||||
errors_by_stage:
|
||||
type: labeled_string
|
||||
description: Records the error type, if any, that occur in different stages of the login process.
|
||||
labels:
|
||||
- server_auth
|
||||
- enter_email
|
||||
...
|
||||
```
|
||||
|
||||
## API
|
||||
|
||||
Now you can use the labeled string from the application's code:
|
||||
Sets one of the labels in a labeled string metric to a specific value.
|
||||
|
||||
{{#include ../../../shared/tab_header.md}}
|
||||
|
||||
|
@ -30,19 +17,15 @@ import org.mozilla.yourApplication.GleanMetrics.Login
|
|||
|
||||
Login.errorsByStage["server_auth"].set("Invalid password")
|
||||
```
|
||||
</div>
|
||||
|
||||
There are test APIs available too:
|
||||
<div data-lang="Java" class="tab">
|
||||
|
||||
```Kotlin
|
||||
import org.mozilla.yourApplication.GleanMetrics.Login
|
||||
```Java
|
||||
import org.mozilla.yourApplication.GleanMetrics.Login;
|
||||
|
||||
// Was anything recorded?
|
||||
assertTrue(Login.errorsByStage["server_auth"].testHasValue())
|
||||
|
||||
// Were there any invalid labels?
|
||||
assertEquals(0, Login.errorsByStage.testGetNumRecordedErrors(ErrorType.InvalidLabel))
|
||||
Login.INSTANCE.errorsByStage["server_auth"].set("Invalid password");
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
<div data-lang="Swift" class="tab">
|
||||
|
@ -50,14 +33,202 @@ assertEquals(0, Login.errorsByStage.testGetNumRecordedErrors(ErrorType.InvalidLa
|
|||
```Swift
|
||||
Login.errorsByStage["server_auth"].set("Invalid password")
|
||||
```
|
||||
</div>
|
||||
|
||||
There are test APIs available too:
|
||||
<div data-lang="Python" class="tab">
|
||||
|
||||
```Python
|
||||
from glean import load_metrics
|
||||
metrics = load_metrics("metrics.yaml")
|
||||
|
||||
metrics.login.errors_by_stage["server_auth"].set("Invalid password")
|
||||
```
|
||||
</div>
|
||||
|
||||
<div data-lang="Javascript" class="tab">
|
||||
|
||||
```js
|
||||
import * as login from "./path/to/generated/files/login.js";
|
||||
|
||||
login.errorsByStage["server_auth"].set("Invalid password");
|
||||
```
|
||||
</div>
|
||||
|
||||
<div data-lang="Rust" class="tab">
|
||||
|
||||
```rust
|
||||
use glean_metrics;
|
||||
|
||||
login::errors_by_stage.get("server_auth").set("Invalid password");
|
||||
```
|
||||
</div>
|
||||
|
||||
{{#include ../../../shared/tab_footer.md}}
|
||||
|
||||
#### Limits
|
||||
|
||||
* Fixed maximum string length: 100. Longer strings are truncated. This is measured in the number of bytes when the string is encoded in UTF-8.
|
||||
|
||||
#### Recorded Errors
|
||||
|
||||
* [`invalid_overflow`](../../user/metrics/error-reporting.md): if the string is too long. (Prior to Glean 31.5.0, this recorded an `invalid_value`).
|
||||
* [`invalid_label`](../../user/metrics/error-reporting.md):
|
||||
* If the label contains invalid characters. Data is still recorded to the special label `__other__`.
|
||||
* If the label exceeds the maximum number of allowed characters. Data is still recorded to the special label `__other__`.
|
||||
|
||||
## Testing API
|
||||
|
||||
### `testGetValue`
|
||||
|
||||
Gets the recorded value for a given label in a labeled string metric.
|
||||
|
||||
{{#include ../../../shared/tab_header.md}}
|
||||
|
||||
<div data-lang="Kotlin" class="tab">
|
||||
|
||||
```Kotlin
|
||||
import org.mozilla.yourApplication.GleanMetrics.Login
|
||||
|
||||
// Does the metric have the expected value?
|
||||
assertTrue(Login.errorsByStage["server_auth"].testGetValue())
|
||||
```
|
||||
</div>
|
||||
|
||||
<div data-lang="Java" class="tab">
|
||||
|
||||
```Java
|
||||
import org.mozilla.yourApplication.GleanMetrics.Login;
|
||||
|
||||
// Does the metric have the expected value?
|
||||
assertTrue(Login.INSTANCE.errorsByStage["server_auth"].testGetValue());
|
||||
```
|
||||
</div>
|
||||
|
||||
<div data-lang="Swift" class="tab">
|
||||
|
||||
```Swift
|
||||
@testable import Glean
|
||||
|
||||
// Does the metric have the expected value?
|
||||
XCTAssert(Login.errorsByStage["server_auth"].testGetValue())
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
<div data-lang="Python" class="tab">
|
||||
|
||||
```Python
|
||||
from glean import load_metrics
|
||||
metrics = load_metrics("metrics.yaml")
|
||||
|
||||
# Does the metric have the expected value?
|
||||
assert "Invalid password" == metrics.login.errors_by_stage["server_auth"].testGetValue())
|
||||
```
|
||||
</div>
|
||||
|
||||
<div data-lang="Javascript" class="tab">
|
||||
|
||||
```js
|
||||
import * as login from "./path/to/generated/files/login.js";
|
||||
|
||||
// Does the metric have the expected value?
|
||||
assert.strictEqual("Invalid password", await metrics.login.errorsByStage["server_auth"].testGetValue())
|
||||
```
|
||||
</div>
|
||||
|
||||
<div data-lang="Rust" class="tab">
|
||||
|
||||
```rust
|
||||
use glean_metrics;
|
||||
|
||||
// Does the metric have the expected value?
|
||||
assert!(login::errors_by_stage.get("server_auth").test_get_value());
|
||||
```
|
||||
</div>
|
||||
|
||||
{{#include ../../../shared/tab_footer.md}}
|
||||
|
||||
### `testHasValue`
|
||||
|
||||
Whether or not **any** value was recorded for a given label in a labeled string metric.
|
||||
|
||||
{{#include ../../../shared/tab_header.md}}
|
||||
|
||||
<div data-lang="Kotlin" class="tab">
|
||||
|
||||
```Kotlin
|
||||
import org.mozilla.yourApplication.GleanMetrics.Login
|
||||
|
||||
// Was anything recorded?
|
||||
assertTrue(Login.errorsByStage["server_auth"].testHasValue())
|
||||
```
|
||||
</div>
|
||||
|
||||
<div data-lang="Java" class="tab">
|
||||
|
||||
```Java
|
||||
import org.mozilla.yourApplication.GleanMetrics.Login;
|
||||
|
||||
// Was anything recorded?
|
||||
assertTrue(Login.INSTANCE.errorsByStage["server_auth"].testHasValue());
|
||||
```
|
||||
</div>
|
||||
|
||||
<div data-lang="Swift" class="tab">
|
||||
|
||||
```Swift
|
||||
@testable import Glean
|
||||
|
||||
// Was anything recorded?
|
||||
XCTAssert(Login.errorsByStage["server_auth"].testHasValue())
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
<div data-lang="Python" class="tab">
|
||||
|
||||
```Python
|
||||
# Was anything recorded?
|
||||
assert metrics.login.errors_by_stage["server_auth"].test_has_value()
|
||||
```
|
||||
</div>
|
||||
|
||||
<div data-lang="Javascript" class="tab"></div>
|
||||
|
||||
<div data-lang="Rust" class="tab"></div>
|
||||
|
||||
{{#include ../../../shared/tab_footer.md}}
|
||||
|
||||
### `testGetNumRecordedErrors`
|
||||
|
||||
Gets the number of errors recorded for a given labeled string metric in total.
|
||||
|
||||
{{#include ../../../shared/tab_header.md}}
|
||||
|
||||
<div data-lang="Kotlin" class="tab">
|
||||
|
||||
```Kotlin
|
||||
import org.mozilla.yourApplication.GleanMetrics.Login
|
||||
|
||||
// Were there any invalid labels?
|
||||
assertEquals(0, Login.errorsByStage.testGetNumRecordedErrors(ErrorType.InvalidLabel))
|
||||
```
|
||||
</div>
|
||||
|
||||
<div data-lang="Java" class="tab">
|
||||
|
||||
```Java
|
||||
import org.mozilla.yourApplication.GleanMetrics.Login;
|
||||
|
||||
// Were there any invalid labels?
|
||||
assertEquals(0, Login.INSTANCE.errorsByStage.testGetNumRecordedErrors(ErrorType.InvalidLabel));
|
||||
```
|
||||
</div>
|
||||
|
||||
<div data-lang="Swift" class="tab">
|
||||
|
||||
```Swift
|
||||
@testable import Glean
|
||||
|
||||
// Were there any invalid labels?
|
||||
XCTAssertEqual(0, Login.errorsByStage.testGetNumRecordedErrors(.invalidLabel))
|
||||
|
@ -71,63 +242,30 @@ XCTAssertEqual(0, Login.errorsByStage.testGetNumRecordedErrors(.invalidLabel))
|
|||
from glean import load_metrics
|
||||
metrics = load_metrics("metrics.yaml")
|
||||
|
||||
metrics.login.errors_by_stage["server_auth"].set("Invalid password")
|
||||
```
|
||||
|
||||
There are test APIs available too:
|
||||
|
||||
```Python
|
||||
# Was anything recorded?
|
||||
assert metrics.login.errors_by_stage["server_auth"].test_has_value()
|
||||
|
||||
# Were there any invalid labels?
|
||||
assert 0 == metrics.login.errors_by_stage.test_get_num_recorded_errors(
|
||||
ErrorType.INVALID_LABEL
|
||||
)
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
<div data-lang="C#" class="tab">
|
||||
<div data-lang="Javascript" class="tab">
|
||||
|
||||
```C#
|
||||
using static Mozilla.YourApplication.GleanMetrics.Login;
|
||||
|
||||
Login.errorsByStage["server_auth"].Set("Invalid password");
|
||||
```
|
||||
|
||||
There are test APIs available too:
|
||||
|
||||
```C#
|
||||
using static Mozilla.YourApplication.GleanMetrics.Login;
|
||||
|
||||
// Was anything recorded?
|
||||
Assert.True(Login.errorsByStage["server_auth"].TestHasValue());
|
||||
```js
|
||||
import * as login from "./path/to/generated/files/login.js";
|
||||
|
||||
// Were there any invalid labels?
|
||||
Assert.Equal(0, Login.errorsByStage.TestGetNumRecordedErrors(ErrorType.InvalidLabel));
|
||||
assert.strictEqual(0, await login.errorsByStage["server_auth"].testGetNumRecordedErrors("invalid_label"));
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
<div data-lang="Rust" class="tab">
|
||||
|
||||
```rust
|
||||
use glean_metrics;
|
||||
|
||||
login::errors_by_stage.get("server_auth").set("Invalid password");
|
||||
```
|
||||
|
||||
There are test APIs available too:
|
||||
|
||||
```rust
|
||||
use glean::ErrorType;
|
||||
|
||||
use glean_metrics;
|
||||
|
||||
// Was anything recorded?
|
||||
assert!(login::errors_by_stage.get("server_auth").test_get_value().is_sone());
|
||||
|
||||
// Were there any invalid labels?
|
||||
assert_eq!(
|
||||
0,
|
||||
|
@ -136,38 +274,44 @@ assert_eq!(
|
|||
)
|
||||
);
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
{{#include ../../../shared/tab_footer.md}}
|
||||
|
||||
## Limits
|
||||
## Metric parameters
|
||||
|
||||
Example labeled boolean metric definition:
|
||||
|
||||
* Labels must conform to the [label formatting regular expression](index.md#label-format).
|
||||
```YAML
|
||||
login:
|
||||
errors_by_stage:
|
||||
type: labeled_string
|
||||
description: Records the error type, if any, that occur in different stages of the login process.
|
||||
bugs:
|
||||
- https://bugzilla.mozilla.org/000000
|
||||
data_reviews:
|
||||
- https://bugzilla.mozilla.org/show_bug.cgi?id=000000#c3
|
||||
notification_emails:
|
||||
- me@mozilla.com
|
||||
expires: 2020-10-01
|
||||
labels:
|
||||
- server_auth
|
||||
- enter_email
|
||||
...
|
||||
```
|
||||
|
||||
* Labels support lowercase alphanumeric characters; they additionally allow for dots (`.`), underscores (`_`) and/or hyphens (`-`).
|
||||
### Extra metric parameters
|
||||
|
||||
* Each label must have a maximum of 60 bytes, when encoded as UTF-8.
|
||||
{{#include ../../_includes/labels-parameter.md}}
|
||||
|
||||
* If the labels are specified in the `metrics.yaml`, using any label not listed in that file will be replaced with the special value `__other__`.
|
||||
## Data questions
|
||||
|
||||
* The number of labels specified in the `metrics.yaml` is limited to 100.
|
||||
|
||||
* If the labels aren't specified in the `metrics.yaml`, only 16 different dynamic labels may be used, after which the special value `__other__` will be used.
|
||||
|
||||
## Examples
|
||||
|
||||
* What kind of errors occurred at each step in the login process?
|
||||
|
||||
## Recorded Errors
|
||||
|
||||
* `invalid_label`: If the label contains invalid characters. Data is still recorded to the special label `__other__`.
|
||||
|
||||
* `invalid_label`: If the label exceeds the maximum number of allowed characters. Data is still recorded to the special label `__other__`.
|
||||
* What kinds of errors occurred at each step in the login process?
|
||||
|
||||
## Reference
|
||||
|
||||
* Kotlin API docs: [`LabeledMetricType`](../../../javadoc/glean/mozilla.telemetry.glean.private/-labeled-metric-type/index.html), [`StringMetricType`](../../../javadoc/glean/mozilla.telemetry.glean.private/-string-metric-type/index.html)
|
||||
* Swift API docs: [`LabeledMetricType`](../../../swift/Classes/LabeledMetricType.html), [`StringMetricType`](../../../swift/Classes/StringMetricType.html)
|
||||
* Python API docs: [`LabeledMetricBase`](../../../python/glean/metrics/labeled.html), [`StringMetricType`](../../../python/glean/metrics/string.html)
|
||||
* Rust API docs: [`LabeledMetric`](../../../docs/glean/private/struct.LabeledMetric.html), [`StringMetricType`](../../../docs/glean/private/struct.StringMetric.html)
|
||||
* Javascript API docs: [`LabeledMetricType`](https://mozilla.github.io/glean.js/classes/core_metrics_types_labeled.default.html), [`StringMetricType`](https://mozilla.github.io/glean.js/classes/core_metrics_types_string.default.html)
|
||||
|
|
Загрузка…
Ссылка в новой задаче