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.
  • The name of the event.
  • A set of key-value pairs, where the keys are predefined in the extra_keys metric parameter, and the values are strings.
Important

Events are the most expensive metric type to record, transmit, store and analyze, so they should be used sparingly, and only when none of the other metric types are sufficient for answering your question.

Recording API

record(object)

Added in: v38.0.0

Record a new event, with optional typed extra values. This requires type annotations in the definition. 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 an enum 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(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 = { sourceOfLogin: "toolbar" };
Glean.views.loginOpened.record(extra);

record(map) (deprecated)

Deprecated in: v38.0.0

Record a new event, with optional extra values.

Deprecation notice

This API is used in v38.0.0 if an event has no type annotations in the definition. See Extra metrics parameters.

In future versions extra values will default to a string type and this API will be removed.
In Rust and Firefox Desktop this API is not supported.

Note that an enum has been generated for handling the extra_keys: it has the same name as the event metric, with Keys added.

import org.mozilla.yourApplication.GleanMetrics.Views

Views.loginOpened.record(mapOf(Views.loginOpenedKeys.sourceOfLogin to "toolbar"))
import org.mozilla.yourApplication.GleanMetrics.Views;

Views.INSTANCE.loginOpened.record();

Note that an enum has been generated for handling the extra_keys: it has the same name as the event metric, with Keys added.

Views.loginOpened.record(extra: [.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.

from glean import load_metrics
metrics = load_metrics("metrics.yaml")

metrics.views.login_opened.record(
    {
        metrics.views.login_opened_keys.SOURCE_OF_LOGIN: "toolbar"
    }
)
import * as views from "./path/to/generated/files/views.js";

views.loginOpened.record({ sourceOfLogin: "toolbar" });

Recorded errors

  • invalid_overflow: if any of the values in the extras object are greater than 50 bytes in length. (Prior to Glean 31.5.0, this recorded an invalid_value).

Testing API

testGetValue

Get the list of recorded events.

import org.mozilla.yourApplication.GleanMetrics.Views

val snapshot = Views.loginOpened.testGetValue()
assertEquals(2, snapshot.size)
val first = snapshot.single()
assertEquals("login_opened", first.name)
import org.mozilla.yourApplication.GleanMetrics.Views

assertEquals(Views.INSTANCE.loginOpened.testGetValue().size)
@testable import Glean

val snapshot = try! Views.loginOpened.testGetValue()
XCTAssertEqual(2, snapshot.size)
val first = snapshot[0]
XCTAssertEqual("login_opened", first.name)
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
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);
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)

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());

JavaScript

var events = Glean.views.loginOpened.testGetValue();
Assert.equal(2, events.length);
Assert.equal("login_opened", events[0].name);

testHasValue

Whether or not any event was recorded for a given event metric.

import org.mozilla.yourApplication.GleanMetrics.Views

assertTrue(Views.loginOpened.testHasValue())
import org.mozilla.yourApplication.GleanMetrics.Views

assertTrue(Views.INSTANCE.loginOpened.testHasValue())
@testable import Glean

XCTAssert(Views.loginOpened.testHasValue())
from glean import load_metrics
metrics = load_metrics("metrics.yaml")

assert metrics.views.login_opened.test_has_value()

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.InvalidOverflow))
import mozilla.telemetry.glean.testing.ErrorType
import org.mozilla.yourApplication.GleanMetrics.Views

assertEquals(0, Views.INSTANCE.loginOpened.testGetNumRecordedErrors(ErrorType.InvalidOverflow))
@testable import Glean

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/<platform>";

assert.strictEqual(
  1,
  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 10 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 of string, boolean, quantity. Defaults to string. Note: If not specified only the legacy API on record is available.

Data questions

  • When and from where was the login view opened?

Limits

  • When 500 events are queued on the client an events ping is immediately sent.
  • The extra_keys allows for a maximum of 10 keys.
  • The keys in the extra_keys list must be in dotted snake case, with a maximum length of 40 bytes, when encoded as UTF-8.
  • The values in the extras object have a maximum of 50 bytes, when encoded as UTF-8.

Reference