Pings
Glean-owned pings are submitted automatically
Products do not need to submit Glean built-in pings, as their scheduling is managed internally. The APIs on this page are only relevant for products defining custom pings.
Submission API
submit
Collect and queue a custom ping for eventual uploading.
By default, if the ping doesn't currently have any events or metrics set, submit
will do nothing. However, if the send_if_empty
flag is set to true in the ping definition, it will always be submitted.
It is not necessary for the caller to check if Glean is disabled before calling submit
.
If Glean is disabled submit
is a no-op.
For example, to submit the custom ping defined in Adding new custom pings:
import org.mozilla.yourApplication.GleanMetrics.Pings
Pings.search.submit(
Pings.searchReasonCodes.performed
)
import org.mozilla.yourApplication.GleanMetrics.Pings
Pings.INSTANCE.search.submit(
Pings.INSTANCE.searchReasonCodes.performed
);
import Glean
GleanMetrics.Pings.shared.search.submit(
reason: .performed
)
from glean import load_pings
pings = load_pings("pings.yaml")
pings.search.submit(pings.search_reason_codes.PERFORMED)
use glean::Pings;
pings::search.submit(pings::SearchReasonCodes::Performed);
import * as pings from "./path/to/generated/files/pings.js";
pings.search.submit(pings.searchReasonCodes.Performed);
C++
mozilla::glean_pings::Search.Submit("performed"_ns);
JavaScript
GleanPings.search.submit("performed");
Testing API
getRegisteredPingNames
Gets a set of the currently registered ping names.
Useful when debugging to know which pings are able to be sent.
val knownPings = Glean.getRegisteredPingNames()
let knownPings = Glean.shared.getRegisteredPingNames()
let known_pings = glean.get_registered_ping_names();
testBeforeNextSubmit
Runs a validation function before the ping is collected.
import org.mozilla.yourApplication.GleanMetrics.Search
import org.mozilla.yourApplication.GleanMetrics.Pings
// Record some data.
Search.defaultEngine.add(5);
// Instruct the ping API to validate the ping data.
var validatorRun = false
Pings.search.testBeforeNextSubmit { reason ->
assertEquals(Pings.searchReasonCodes.performed, reason)
assertEquals(5, Search.defaultEngine.testGetValue())
validatorRun = true
}
// Submit the ping.
Pings.search.submit(
Pings.searchReasonCodes.performed
)
// Verify that the validator run.
assertTrue(validatorRun)
import org.mozilla.yourApplication.GleanMetrics.Search
import org.mozilla.yourApplication.GleanMetrics.Pings
// Record some data.
Search.INSTANCE.defaultEngine.add(5);
// Instruct the ping API to validate the ping data.
boolean validatorRun = false;
Pings.INSTANCE.search.testBeforeNextSubmit((reason) -> {
assertEquals(Pings.searchReasonCodes.performed, reason);
assertEquals(5, Search.INSTANCE.defaultEngine.testGetValue());
validatorRun = true;
});
// Submit the ping.
Pings.INSTANCE.search.submit(
Pings.INSTANCE.searchReasonCodes.performed
);
// Verify that the validator run.
assertTrue(validatorRun);
// Record some data.
Search.defaultEngine.add(5)
// Instruct the ping API to validate the ping data.
var validatorRun = false
GleanMetrics.pings.shared.search.testBeforeNextSubmit { reason in
XCTAssertEqual(.performed, reason, "Unexpected reason for search ping submitted")
XCTAssertEqual(5, try Search.defaultEngine.testGetValue(), "Unexpected value for default engine in search ping")
validatorRun = true
}
// Submit the ping.
GleanMetrics.Pings.shared.search.submit(
reason: .performed
)
// Verify that the validator run.
XCTAssert(validatorRun, "Expected validator to be called by now.")
from glean import load_metrics, load_pings
pings = load_pings("pings.yaml")
metrics = load_metrics("metrics.yaml")
# Record some data.
metrics.search.default_engine.add(5)
# Need a mutable object and plain booleans are not.
callback_was_called = [False]
def check_custom_ping(reason):
assert reason == pings.search_reason_codes.PERFORMED
assert 5 == metrics.search.default_engine.test_get_value()
callback_was_called[0] = True
# Instruct the ping API to validate the ping data.
pings.search.test_before_next_submit(check_custom_ping)
# Submit the ping.
pings.search.submit(pings.search_reason_codes.PERFORMED)
# Verify that the validator run.
assert callback_was_called[0]
use glean_metrics::{search, pings};
// Record some data.
search::default_engine.add(5);
// Instruct the ping API to validate the ping data.
pings::search.test_before_next_submit(move |reason| {
assert_eq!(pings::SearchReasonCodes::Performed, reason);
assert_eq!(5, search::default_engine.test_get_value(None).unwrap());
});
// When the `submit` API is not directly called by the
// test code, it may be worth checking that the validator
// function run by using a canary boolean in the closure
// used in `test_before_next_submit` and asserting on its
// value after submission.
// Submit the ping.
pings::search.submit(pings::SearchReasonCodes::Performed);
import * as search from "./path/to/generated/files/search.js";
import * as pings from "./path/to/generated/files/pings.js";
// Record some data.
search.defaultEngine.add(5);
// Instruct the ping API to validate the ping data.
let validatorRun = false;
const p = pings.search.testBeforeNextSubmit(async reason => {
assert.strictEqual(reason, "performed");
assert.strictEqual(await search.defaultEngine.testGetValue(), 5);
validatorRun = true;
});
// Submit the ping.
pings.search.submit("performed");
// Wait for the validation to finish.
assert.doesNotThrow(async () => await p);
// Verify that the validator run.
assert.ok(validatorRun);
JavaScript:
Glean.search.defaultEngine.add(5);
let submitted = false;
GleanPings.search.testBeforeNextSubmit(reason => {
submitted = true;
Assert.equal(5, Glean.search.defaultEngine.testGetValue());
});
GleanPings.search.submit();
Assert.ok(submitted);
C++:
mozilla::glean::search::default_engine.Add(5);
bool submitted = false;
mozilla::glean_pings::Search.TestBeforeNextSubmit([&submitted](const nsACString& aReason) {
submitted = true;
ASSERT_EQ(false, mozilla::glean::search::default_engine.TestGetValue().unwrap().ref());
});
mozilla::glean_pings::Search.Submit();
ASSERT_TRUE(submitted);