summaryrefslogtreecommitdiffstats
path: root/toolkit/components/telemetry/docs/fhr/architecture.rst
diff options
context:
space:
mode:
Diffstat (limited to 'toolkit/components/telemetry/docs/fhr/architecture.rst')
-rw-r--r--toolkit/components/telemetry/docs/fhr/architecture.rst226
1 files changed, 226 insertions, 0 deletions
diff --git a/toolkit/components/telemetry/docs/fhr/architecture.rst b/toolkit/components/telemetry/docs/fhr/architecture.rst
new file mode 100644
index 000000000..6a857d329
--- /dev/null
+++ b/toolkit/components/telemetry/docs/fhr/architecture.rst
@@ -0,0 +1,226 @@
+.. _healthreport_architecture:
+
+============
+Architecture
+============
+
+``healthreporter.jsm`` contains the main interface for FHR, the
+``HealthReporter`` type. An instance of this is created by the
+``data_reporting_service`.
+
+``providers.jsm`` contains numerous ``Metrics.Provider`` and
+``Metrics.Measurement`` used for collecting application metrics. If you
+are looking for the FHR probes, this is where they are.
+
+Storage
+=======
+
+Firefox Health Report stores data in 3 locations:
+
+* Metrics measurements and provider state is stored in a SQLite database
+ (via ``Metrics.Storage``).
+* Service state (such as the IDs of documents uploaded) is stored in a
+ JSON file on disk (via OS.File).
+* Lesser state and run-time options are stored in preferences.
+
+Preferences
+===========
+
+Preferences controlling behavior of Firefox Health Report live in the
+``datareporting.healthreport.*`` branch.
+
+Service and Data Control
+------------------------
+
+The follow preferences control behavior of the service and data upload.
+
+service.enabled
+ Controls whether the entire health report service runs. The overall
+ service performs data collection, storing, and submission.
+
+ This is the primary kill switch for Firefox Health Report
+ outside of the build system variable. i.e. if you are using an
+ official Firefox build and wish to disable FHR, this is what you
+ should set to false to prevent FHR from not only submitting but
+ also collecting data.
+
+uploadEnabled
+ Whether uploading of data is enabled. This is the preference the
+ checkbox in the preferences UI reflects. If this is
+ disabled, FHR still collects data - it just doesn't upload it.
+
+service.loadDelayMsec
+ How long (in milliseconds) after initial application start should FHR
+ wait before initializing.
+
+ FHR may initialize sooner than this if the FHR service is requested.
+ This will happen if e.g. the user goes to ``about:healthreport``.
+
+service.loadDelayFirstRunMsec
+ How long (in milliseconds) FHR should wait to initialize on first
+ application run.
+
+ FHR waits longer than normal to initialize on first application run
+ because first-time initialization can use a lot of I/O to initialize
+ the SQLite database and this I/O should not interfere with the
+ first-run user experience.
+
+documentServerURI
+ The URI of a Bagheera server that FHR should interface with for
+ submitting documents.
+
+ You typically do not need to change this.
+
+documentServerNamespace
+ The namespace on the document server FHR should upload documents to.
+
+ You typically do not need to change this.
+
+infoURL
+ The URL of a page containing more info about FHR, it's privacy
+ policy, etc.
+
+about.reportUrl
+ The URL to load in ``about:healthreport``.
+
+about.reportUrlUnified
+ The URL to load in ``about:healthreport``. This is used instead of ``reportUrl`` for UnifiedTelemetry when it is not opt-in.
+
+service.providerCategories
+ A comma-delimited list of category manager categories that contain
+ registered ``Metrics.Provider`` records. Read below for how provider
+ registration works.
+
+If the entire service is disabled, you lose data collection. This means
+that **local** data analysis won't be available because there is no data
+to analyze! Keep in mind that Firefox Health Report can be useful even
+if it's not submitting data to remote servers!
+
+Logging
+-------
+
+The following preferences allow you to control the logging behavior of
+Firefox Health Report.
+
+logging.consoleEnabled
+ Whether to write log messages to the web console. This is true by
+ default.
+
+logging.consoleLevel
+ The minimum log level FHR messages must have to be written to the
+ web console. By default, only FHR warnings or errors will be written
+ to the web console. During normal/expected operation, no messages of
+ this type should be produced.
+
+logging.dumpEnabled
+ Whether to write log messages via ``dump()``. If true, FHR will write
+ messages to stdout/stderr.
+
+ This is typically only enabled when developing FHR.
+
+logging.dumpLevel
+ The minimum log level messages must have to be written via
+ ``dump()``.
+
+State
+-----
+
+currentDaySubmissionFailureCount
+ How many submission failures the client has encountered while
+ attempting to upload the most recent document.
+
+lastDataSubmissionFailureTime
+ The time of the last failed document upload.
+
+lastDataSubmissionRequestedTime
+ The time of the last document upload attempt.
+
+lastDataSubmissionSuccessfulTime
+ The time of the last successful document upload.
+
+nextDataSubmissionTime
+ The time the next data submission is scheduled for. FHR will not
+ attempt to upload a new document before this time.
+
+pendingDeleteRemoteData
+ Whether the client currently has a pending request to delete remote
+ data. If true, the client will attempt to delete all remote data
+ before an upload is performed.
+
+FHR stores various state in preferences.
+
+Registering Providers
+=====================
+
+Firefox Health Report providers are registered via the category manager.
+See ``HealthReportComponents.manifest`` for providers defined in this
+directory.
+
+Essentially, the category manager receives the name of a JS type and the
+URI of a JSM to import that exports this symbol. At run-time, the
+providers registered in the category manager are instantiated.
+
+Providers are registered via the category manager to make registration
+simple and less prone to errors. Any XPCOM component can create a
+category manager entry. Therefore, new data providers can be added
+without having to touch core Firefox Health Report code. Additionally,
+category manager registration means providers are more likely to be
+registered on FHR's terms, when it wants. If providers were registered
+in code at application run-time, there would be the risk of other
+components prematurely instantiating FHR (causing a performance hit if
+performed at an inopportune time) or semi-complicated code around
+observers or listeners. Category manager entries are only 1 line per
+provider and leave FHR in control: they are simple and safe.
+
+Document Generation and Lifecycle
+=================================
+
+FHR will attempt to submit a JSON document containing data every 24 wall
+clock hours.
+
+At upload time, FHR will query the database for **all** information from
+the last 180 days and assemble this data into a JSON document. We
+attempt to upload this JSON document with a client-generated UUID to the
+configured server.
+
+Before we attempt upload, the generated UUID is stored in the JSON state
+file on local disk. At this point, the client assumes the document with
+that UUID has been successfully stored on the server.
+
+If the client is aware of other document UUIDs that presumably exist on
+the server, those UUIDs are sent with the upload request so the client
+can request those UUIDs be deleted. This helps ensure that each client
+only has 1 document/UUID on the server at any one time.
+
+Importance of Persisting UUIDs
+------------------------------
+
+The choices of how, where, and when document UUIDs are stored and updated
+are very important. One should not attempt to change things unless she
+has a very detailed understanding of why things are the way they are.
+
+The client is purposefully very conservative about forgetting about
+generated UUIDs. In other words, once a UUID is generated, the client
+deliberately holds on to that UUID until it's very confident that UUID
+is no longer stored on the server. The reason we do this is because
+*orphaned* documents/UUIDs on the server can lead to faulty analysis,
+such as over-reporting the number of Firefox installs that stop being
+used.
+
+When uploading a new UUID, we update the state and save the state file
+to disk *before* an upload attempt because if the upload succeeds but
+the response never makes it back to the client, we want the client to
+know about the uploaded UUID so it can delete it later to prevent an
+orphan.
+
+We maintain a list of UUIDs locally (not simply the last UUID) because
+multiple upload attempts could fail the same way as the previous
+paragraph describes and we have no way of knowing which (if any)
+actually succeeded. The safest approach is to assume every document
+produced managed to get uploaded some how.
+
+We store the UUIDs on a file on disk and not anywhere else because we
+want storage to be robust. We originally stored UUIDs in preferences,
+which only flush to disk periodically. Writes to preferences were
+apparently getting lost. We switched to writing directly to files to
+eliminate this window.