Events
Events allow recording of e.g. individual occurrences of user actions, say every time a view was open and from where.
Each event contains the following data:
- A timestamp, in milliseconds. The first event in any ping always has a value of
0
, and subsequent event timestamps are relative to it.- If sending events in custom pings, see note on event timestamp calculation throughout restarts.
- The name of the event.
- A set of key-value pairs, where the keys are predefined in the
extra_keys
metric parameter. Values are one ofstring
,boolean
,quantity
, and are converted tostring
for transmission.
Immediate submission or batching?
In the Glean JavaScript SDK (Glean.js), since version 2.0.2, events are submitted immediately by default. In all the other SDKs, events are batched and sent together by default in the events ping.
Recording API
record(object)
Record a new event, with optional typed extra values. See Extra metrics parameters.
Note that an enum
has been generated for handling the extra_keys
: it has the same name as the event metric, with Extra
added.
import org.mozilla.yourApplication.GleanMetrics.Views
Views.loginOpened.record(Views.loginOpenedExtra(sourceOfLogin = "toolbar"))
Note that an enum
has been generated for handling the extra_keys
: it has the same name as the event metric, with Extra
added.
Views.loginOpened.record(LoginOpenedExtra(sourceOfLogin: "toolbar"))
Note that a class
has been generated for handling the extra_keys
: it has the same name as the event metric, with Extra
added.
from glean import load_metrics
metrics = load_metrics("metrics.yaml")
metrics.views.login_opened.record(metrics.views.LoginOpenedExtra(sourceOfLogin="toolbar"))
Note that an enum
has been generated for handling the extra_keys
: it has the same name as the event metric, with Keys
added.
use metrics::views::{self, LoginOpenedExtra};
let extra = LoginOpenedExtra { source_of_login: Some("toolbar".to_string()) };
views::login_opened.record(extra);
import * as views from "./path/to/generated/files/views.js";
views.loginOpened.record({ sourceOfLogin: "toolbar" });
C++
#include "mozilla/glean/GleanMetrics.h"
using mozilla::glean::views::LoginOpenedExtra;
LoginOpenedExtra extra = { .source_of_login = Some("value"_ns) };
mozilla::glean::views::login_opened.Record(std::move(extra))
JavaScript
const extra = { source_of_login: "toolbar" }; // Extra Keys are *NOT* conjugated to camelCase
Glean.views.loginOpened.record(extra);
Recorded errors
invalid_overflow
: if any of the values in theextras
object are greater than 500 bytes in length. (Prior to Glean 31.5.0, this recorded aninvalid_value
).invalid_value
: if there is an attempt to record to an extra key which is not allowed i.e. an extra key that has not been listed in the YAML registry file.invalid_type
: if the extra value given is not the expected type.
Testing API
testGetValue
Get the list of recorded events.
Returns a language-specific empty/null value if no data is stored.
Has an optional argument to specify the name of the ping you wish to retrieve data from, except
in Rust where it's required. None
or no argument will default to the first value found for send_in_pings
.
Note: By default as of
v2.0.2
Glean.js setsmaxEvents=1
by default. If you try and calltestGetValue()
for a recorded event withmaxEvents=1
,snapshot
will not include your event. For your testing instance, you can setmaxEvents
to a value greater than 1 to test recording events withtestGetValue()
.
import org.mozilla.yourApplication.GleanMetrics.Views
val snapshot = Views.loginOpened.testGetValue()
assertEquals(2, snapshot.size)
val first = snapshot.single()
assertEquals("login_opened", first.name)
assertEquals("toolbar", first.extra?.getValue("source_of_login"))
import org.mozilla.yourApplication.GleanMetrics.Views
assertEquals(Views.INSTANCE.loginOpened().testGetValue().size)
val snapshot = try! Views.loginOpened.testGetValue()
XCTAssertEqual(2, snapshot.size)
val first = snapshot[0]
XCTAssertEqual("login_opened", first.name)
XCTAssertEqual("toolbar", first.extra?["source_of_login"])
from glean import load_metrics
metrics = load_metrics("metrics.yaml")
snapshot = metrics.views.login_opened.test_get_value()
assert 2 == len(snapshot)
first = snapshot[0]
assert "login_opened" == first.name
assert "toolbar" == first.extra["source_of_login"]
use metrics::views;
var snapshot = views::login_opened.test_get_value(None).unwrap();
assert_eq!(2, snapshot.len());
let first = &snapshot[0];
assert_eq!("login_opened", first.name);
let extra = event.extra.unwrap();
assert_eq!(Some(&"toolbar".to_string()), extra.get("source_of_login"));
import * as views from "./path/to/generated/files/views.js";
const snapshot = await views.loginOpened.testGetValue();
assert.strictEqual(2, snapshot.length);
const first = snapshot[0];
assert.strictEqual("login_opened", first.name);
assert.strictEqual("toolbar", first.extra.source_of_login);
C++
#include "mozilla/glean/GleanMetrics.h"
auto optEvents = mozilla::glean::views::login_opened.TestGetValue();
auto events = optEvents.extract();
ASSERT_EQ(2UL, events.Length());
ASSERT_STREQ("login_opened", events[0].mName.get());
// Note that the list of extra key/value pairs can be in any order.
ASSERT_EQ(1UL, events[0].mExtra.Length());
auto extra = events[0].mExtra[0];
auto key = std::get<0>(extra);
auto value = std::get<1>(extra);
ASSERT_STREQ("source_of_login"_ns, key.get())
ASSERT_STREQ("toolbar", value.get());
}
JavaScript
var events = Glean.views.loginOpened.testGetValue();
Assert.equal(2, events.length);
Assert.equal("login_opened", events[0].name);
Assert.equal("toolbar", events[0].extra.source_of_login);
testGetNumRecordedErrors
Get the number of errors recorded for a given event metric.
import mozilla.telemetry.glean.testing.ErrorType
import org.mozilla.yourApplication.GleanMetrics.Views
assertEquals(
0,
Views.loginOpened.testGetNumRecordedErrors(ErrorType.INVALID_OVERFLOW)
)
import mozilla.telemetry.glean.testing.ErrorType
import org.mozilla.yourApplication.GleanMetrics.Views
assertEquals(
0,
Views.INSTANCE.loginOpened().testGetNumRecordedErrors(ErrorType.INVALID_OVERFLOW)
)
XCTAssertEqual(0, Views.loginOpened.testGetNumRecordedErrors(.invalidOverflow))
from glean import load_metrics
from glean.testing import ErrorType
metrics = load_metrics("metrics.yaml")
assert 0 == metrics.views.login_opened.test_get_num_recorded_errors(
ErrorType.INVALID_OVERFLOW
)
use glean::ErrorType;
use metrics::views;
assert_eq!(
0,
views::login_opened.test_get_num_recorded_errors(
ErrorType::InvalidOverflow,
None
)
);
import * as views from "./path/to/generated/files/views.js";
import { ErrorType } from "@mozilla/glean/error";
assert.strictEqual(
0,
await views.loginOpened.testGetNumRecordedErrors(ErrorType.InvalidValue)
);
Metric parameters
Example event metric definition:
views:
login_opened:
type: event
description: |
Recorded when the login view is opened.
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
extra_keys:
source_of_login:
description: The source from which the login view was opened, e.g. "toolbar".
type: string
For a full reference on metrics parameters common to all metric types, refer to the metrics YAML registry format reference page.
Events require lifetime: ping
.
Recorded events are always sent in their respective pings and then cleared. They cannot be persisted longer. The
glean_parser
will reject any other lifetime.
Extra metric parameters
extra_keys
The acceptable keys on the "extra" object sent with events. A maximum of 50 extra keys is allowed.
Each extra key contains additional metadata:
description
: Required. A description of the key.
type
: The type of value this extra key can hold. One ofstring
,boolean
,quantity
. Defaults tostring
. Recorded value is converted to string for transmission. Note: If not specified only the legacy API onrecord
is available.
Extras or string metrics?
When designing your metrics, define properties that are slow-changing and common across all events in a given ping as string metrics. Properties specific to a single event or a subset of events should be defined as event extras.
Data questions
- When and from where was the login view opened?
Limits
- In Glean.js the default value for
maxEvents
is 1. In all other SDKs it is 500. - Once the
maxEvents
threshold is reached on the client an "events" ping is immediately sent. - The
extra_keys
allows for a maximum of 50 keys. - The keys in the
extra_keys
list must be written using printable ASCII characters, with a maximum length of 40 bytes, when encoded as UTF-8. - The values in the
extras
object have a maximum length of 500 bytes when serialized and encoded as UTF-8. Longer values are truncated, and aninvalid_overflow
error is recorded.