Payload format
The main sections of a Glean ping are described in Ping Sections. This Payload format chapter describes details of the ping payload that are relevant for decoding Glean pings in the pipeline.
NOTE: The payload format is an implementation detail of the Glean SDK and subject to change at any time. External users should not rely on this information. It is provided as a reference for contributing to Glean only.
JSON Schema
Glean's ping payloads have a formal JSON schema defined in the mozilla-pipeline-schemas project. It is written as a set of templates that are expanded by the mozilla-pipeline-schemas build infrastructure into a fully expanded schema.
Metric types
Boolean
A Boolean is represented by its boolean value.
Example
true
Counter
A Counter is represented by its integer value.
Example
17
Quantity
A Quantity is represented by its integer value.
Example
42
String
A String is represented by its string value.
Example
"sample string"
String list
A String List is represented as an array of strings.
Example
["sample string", "another one"]
An empty list is accepted and sent as:
[]
Timespan
A Timespan is represented as an object of their duration as an integer and the time unit.
Field name | Type | Description |
---|---|---|
value | Integer | The value in the marked time unit. |
time_unit | String | The time unit. |
Example
{
"time_unit": "milliseconds",
"value": 10
}
Timing Distribution
A Timing distribution is represented as an object with the following fields.
Field name | Type | Description |
---|---|---|
sum | Integer | The sum of all recorded values. |
values | Map<String, Integer> | The values in each bucket. The key is the minimum value for the range of that bucket. |
A contiguous range of buckets is always sent, so that the server can aggregate and visualize distributions, without knowing anything about the specific bucketing function used. This range starts with the first bucket with a non-zero accumulation, and ends at one bucket beyond the last bucket with a non-zero accumulation (so that the upper bound on the last bucket is retained).
For example, the following shows the recorded values vs. what is sent in the payload.
recorded: 1024: 2, 1116: 1, 1448: 1,
sent: 1024: 2, 1116: 1, 1217: 0, 1327: 0, 1448: 1, 1579: 0
Example:
{
"sum": 4612,
"values": {
"1024": 2,
"1116": 1,
"1217": 0,
"1327": 0,
"1448": 1,
"1579": 0
}
}
Memory Distribution
A Memory distribution is represented as an object with the following fields.
Field name | Type | Description |
---|---|---|
sum | Integer | The sum of all recorded values. |
values | Map<String, Integer> | The values in each bucket. The key is the minimum value for the range of that bucket. |
A contiguous range of buckets is always sent. See timing distribution for more details.
Example:
{
"sum": 3,
"values": {
"0": 1,
"1": 3,
}
}
UUID
A UUID is represented by the string representation of the UUID.
Example
"29711dc8-a954-11e9-898a-eb4ea7e8fd3f"
URL
A URL is represented by the encoded string representation of the URL.
Example
"https://mysearchengine.com/?query=%25s"
Datetime
A Datetime is represented by its ISO8601 string representation, truncated to the metric's time unit. It always includes the timezone offset.
Example
"2019-07-18T14:06:00.000+02:00"
Event
Events are represented as an array of objects, with one object for each event. Each event object has the following keys:
Field name | Type | Description |
---|---|---|
timestamp | Integer | A monotonically increasing timestamp value, in milliseconds. To avoid leaking absolute times, the first timestamp in the array is always zero, and subsequent timestamps in the array are relative to that reference point. |
category | String | The event's category. This comes directly from the category under which the metric was defined in the metrics.yaml file. |
name | String | The event's name, as defined in the metrics.yaml file. |
extra | Object (optional) | Extra data associated with the event. Both the keys and values of this object are strings. The keys must be from the set defined for this event in the metrics.yaml file. The values have a maximum length of 50 bytes, when encoded as UTF-8. |
Example
[
{
"timestamp": 0,
"category": "app",
"name": "ss_menu_opened"
},
{
"timestamp": 124,
"category": "search",
"name": "performed_search",
"extra": {
"source": "default.action"
}
}
]
Also see the JSON schema for events.
To avoid losing events when the application is killed by the operating system, events are queued on disk as they are recorded.
When the application starts up again, there is no good way to determine if the device has rebooted since the last run and therefore any timestamps recorded in the new run could not be guaranteed to be consistent with those recorded in the previous run.
To get around this, on application startup, any queued events are immediately collected into pings and then cleared.
These "startup-triggered pings" are likely to have a very short duration, as recorded in ping_info.start_time
and ping_info.end_time
(see the ping_info
section).
The maximum timestamp of the events in these pings are quite likely to exceed the duration of the ping, but this is to be expected.
Custom Distribution
A Custom distribution is represented as an object with the following fields.
Field name | Type | Description |
---|---|---|
sum | Integer | The sum of all recorded values. |
values | Map<String, Integer> | The values in each bucket. The key is the minimum value for the range of that bucket. |
A contiguous range of buckets is always sent, so that the server can aggregate and visualize distributions, without knowing anything about the specific bucketing function used.
This range starts with the first bucket (as specified in the range_min
parameter), and ends at one bucket beyond the last bucket with a non-zero accumulation (so that the upper bound on the last bucket is retained).
For example, suppose you had a custom distribution defined by the following parameters:
range_min
: 10range_max
: 200bucket_count
: 80histogram_type
:'linear'
The following shows the recorded values vs. what is sent in the payload.
recorded: 12: 2, 22: 1
sent: 10: 0, 12: 2, 14: 0, 17: 0, 19: 0, 22: 1, 24: 0
Example:
{
"sum": 3,
"values": {
"10": 0,
"12": 2,
"14": 0,
"17": 0,
"19": 0,
"22": 1,
"24": 0
}
}
Labeled metrics
Currently several labeled metrics are supported:
All are on the top-level represented in the same way, as an object mapping the label to the metric's value. See the individual metric types for details on the value payload:
Example for Labeled Counters
{
"label1": 2,
"label2": 17
}
Rate
A Rate is represented by its numerator
and denominator
.
Example
{
"numerator": 22,
"denominator": 7,
}
Text
A Text is represented by its string value.
Example
"sample string"
Object
An Object is represented as either a JSON array or JSON object,
depending on the allowed structure.
Missing values (null
) and empty arrays will not be serialized in the payload.
Example
Object:
{
"colour": "red",
"diameter": 5
}
Array with objects:
[
{
"type": "ERROR",
"address": "0x000000"
},
{
"type": "ERROR"
}
]