michael@0: .. _services_metrics: michael@0: michael@0: ============================ michael@0: Metrics Collection Framework michael@0: ============================ michael@0: michael@0: The ``services/metrics`` directory contains a generic data metrics michael@0: collecting and persisting framework for Gecko applications. michael@0: michael@0: Overview michael@0: ======== michael@0: michael@0: The Metrics framework by itself doesn't do much: it simply provides a michael@0: generic mechanism for collecting and persisting data. It is up to users michael@0: of this framework to drive collection and do something with the obtained michael@0: data. A consumer of this framework is :ref:`firefox_health_report`. michael@0: michael@0: Relationship to Telemetry michael@0: ------------------------- michael@0: michael@0: Telemetry provides similar features to code in this directory. The two michael@0: may be unified in the future. michael@0: michael@0: Usage michael@0: ===== michael@0: michael@0: To use the code in this directory, import Metrics.jsm. e.g. michael@0: michael@0: Components.utils.import("resource://gre/modules/Metrics.jsm"); michael@0: michael@0: This exports a *Metrics* object which holds references to the main JS michael@0: types and functions provided by this feature. Read below for what those michael@0: types are. michael@0: michael@0: Metrics Types michael@0: ============= michael@0: michael@0: ``Metrics.jsm`` exports a number of types. They are documented in the michael@0: sections below. michael@0: michael@0: Metrics.Provider michael@0: ---------------- michael@0: michael@0: ``Metrics.Provider`` is an entity that collects and manages data. Providers michael@0: are typically domain-specific: if you need to collect a new type of data, michael@0: you create a ``Metrics.Provider`` type that does this. michael@0: michael@0: Metrics.Measurement michael@0: ------------------- michael@0: michael@0: A ``Metrics.Measurement`` represents a collection of related pieces/fields michael@0: of data. michael@0: michael@0: All data recorded by the metrics framework is modeled as michael@0: ``Metrics.Measurement`` instances. Instances of ``Metrics.Measurement`` michael@0: are essentially data structure descriptors. michael@0: michael@0: Each ``Metrics.Measurement`` consists of a name and version to identify michael@0: itself (and its data) as well as a list of *fields* that this measurement michael@0: holds. A *field* is effectively an entry in a data structure. It consists michael@0: of a name and strongly enumerated type. michael@0: michael@0: Metrics.Storage michael@0: --------------- michael@0: michael@0: This entity is responsible for persisting collected data and state. michael@0: michael@0: It currently uses SQLite to store data, but this detail is abstracted away michael@0: in order to facilitate swapping of storage backends. michael@0: michael@0: Metrics.ProviderManager michael@0: ----------------------- michael@0: michael@0: High-level entity coordinating activity among several ``Metrics.Provider`` michael@0: instances. michael@0: michael@0: Providers and Measurements michael@0: ========================== michael@0: michael@0: The most important types in this framework are ``Metrics.Provider`` and michael@0: ``Metrics.Measurement``, henceforth known as ``Provider`` and michael@0: ``Measurement``, respectively. As you will see, these two types go michael@0: hand in hand. michael@0: michael@0: A ``Provider`` is an entity that *provides* data about a specific subsystem michael@0: or feature. They do this by recording data to specific ``Measurement`` michael@0: types. Both ``Provider`` and ``Measurement`` are abstract base types. michael@0: michael@0: A ``Measurement`` implementation defines a name and version. More michael@0: importantly, it also defines its storage requirements and how michael@0: previously-stored values are serialized. michael@0: michael@0: Storage allocation is performed by communicating with the SQLite michael@0: backend. There is a startup function that tells SQLite what fields the michael@0: measurement is recording. The storage backend then registers these in michael@0: the database. Internally, this is creating a new primary key for michael@0: individual fields so later storage operations can directly reference michael@0: these primary keys in order to retrieve data without having to perform michael@0: complicated joins. michael@0: michael@0: A ``Provider`` can be thought of as a collection of ``Measurement`` michael@0: implementations. e.g. an Addons provider may consist of a measurement michael@0: for all *current* add-ons as well as a separate measurement for michael@0: historical counts of add-ons. A provider's primary role is to take michael@0: metrics data and write it to various measurements. This effectively michael@0: persists the data to SQLite. michael@0: michael@0: Data is emitted from providers in either a push or pull based mechanism. michael@0: In push-based scenarios, the provider likely subscribes to external michael@0: events (e.g. observer notifications). An event of interest can occur at michael@0: any time. When it does, the provider immediately writes the event of michael@0: interest to storage or buffers it for eventual writing. In pull-based michael@0: scenarios, the provider is periodically queried and asked to populate michael@0: data. michael@0: michael@0: SQLite Storage michael@0: ============== michael@0: michael@0: ``Metrics.Storage`` provides an interface for persisting metrics data to a michael@0: SQLite database. michael@0: michael@0: The storage API organizes values by fields. A field is a named member of michael@0: a ``Measurement`` that has specific type and retention characteristics. michael@0: Some example field types include: michael@0: michael@0: * Last text value michael@0: * Last numeric value for a given day michael@0: * Discrete text values for a given day michael@0: michael@0: See ``storage.jsm`` for more.