services/healthreport/docs/architecture.rst

branch
TOR_BUG_3246
changeset 5
4ab42b5ab56c
equal deleted inserted replaced
-1:000000000000 0:abdc2a93e59a
1 .. _healthreport_architecture:
2
3 ============
4 Architecture
5 ============
6
7 ``healthreporter.jsm`` contains the main interface for FHR, the
8 ``HealthReporter`` type. An instance of this is created by the
9 :ref:`data_reporting_service`.
10
11 ``providers.jsm`` contains numerous ``Metrics.Provider`` and
12 ``Metrics.Measurement`` used for collecting application metrics. If you
13 are looking for the FHR probes, this is where they are.
14
15 Storage
16 =======
17
18 Firefox Health Report stores data in 3 locations:
19
20 * Metrics measurements and provider state is stored in a SQLite database
21 (via ``Metrics.Storage``).
22 * Service state (such as the IDs of documents uploaded) is stored in a
23 JSON file on disk (via OS.File).
24 * Lesser state and run-time options are stored in preferences.
25
26 Preferences
27 ===========
28
29 Preferences controlling behavior of Firefox Health Report live in the
30 ``datareporting.healthreport.*`` branch.
31
32 Service and Data Control
33 ------------------------
34
35 The follow preferences control behavior of the service and data upload.
36
37 service.enabled
38 Controls whether the entire health report service runs. The overall
39 service performs data collection, storing, and submission.
40
41 This is the primary kill switch for Firefox Health Report
42 outside of the build system variable. i.e. if you are using an
43 official Firefox build and wish to disable FHR, this is what you
44 should set to false to prevent FHR from not only submitting but
45 also collecting data.
46
47 uploadEnabled
48 Whether uploading of data is enabled. This is the preference the
49 checkbox in the preferences UI reflects. If this is
50 disabled, FHR still collects data - it just doesn't upload it.
51
52 service.loadDelayMsec
53 How long (in milliseconds) after initial application start should FHR
54 wait before initializing.
55
56 FHR may initialize sooner than this if the FHR service is requested.
57 This will happen if e.g. the user goes to ``about:healthreport``.
58
59 service.loadDelayFirstRunMsec
60 How long (in milliseconds) FHR should wait to initialize on first
61 application run.
62
63 FHR waits longer than normal to initialize on first application run
64 because first-time initialization can use a lot of I/O to initialize
65 the SQLite database and this I/O should not interfere with the
66 first-run user experience.
67
68 documentServerURI
69 The URI of a Bagheera server that FHR should interface with for
70 submitting documents.
71
72 You typically do not need to change this.
73
74 documentServerNamespace
75 The namespace on the document server FHR should upload documents to.
76
77 You typically do not need to change this.
78
79 infoURL
80 The URL of a page containing more info about FHR, it's privacy
81 policy, etc.
82
83 about.reportUrl
84 The URL to load in ``about:healthreport``.
85
86 service.providerCategories
87 A comma-delimited list of category manager categories that contain
88 registered ``Metrics.Provider`` records. Read below for how provider
89 registration works.
90
91 If the entire service is disabled, you lose data collection. This means
92 that **local** data analysis won't be available because there is no data
93 to analyze! Keep in mind that Firefox Health Report can be useful even
94 if it's not submitting data to remote servers!
95
96 Logging
97 -------
98
99 The following preferences allow you to control the logging behavior of
100 Firefox Health Report.
101
102 logging.consoleEnabled
103 Whether to write log messages to the web console. This is true by
104 default.
105
106 logging.consoleLevel
107 The minimum log level FHR messages must have to be written to the
108 web console. By default, only FHR warnings or errors will be written
109 to the web console. During normal/expected operation, no messages of
110 this type should be produced.
111
112 logging.dumpEnabled
113 Whether to write log messages via ``dump()``. If true, FHR will write
114 messages to stdout/stderr.
115
116 This is typically only enabled when developing FHR.
117
118 logging.dumpLevel
119 The minimum log level messages must have to be written via
120 ``dump()``.
121
122 State
123 -----
124
125 currentDaySubmissionFailureCount
126 How many submission failures the client has encountered while
127 attempting to upload the most recent document.
128
129 lastDataSubmissionFailureTime
130 The time of the last failed document upload.
131
132 lastDataSubmissionRequestedTime
133 The time of the last document upload attempt.
134
135 lastDataSubmissionSuccessfulTime
136 The time of the last successful document upload.
137
138 nextDataSubmissionTime
139 The time the next data submission is scheduled for. FHR will not
140 attempt to upload a new document before this time.
141
142 pendingDeleteRemoteData
143 Whether the client currently has a pending request to delete remote
144 data. If true, the client will attempt to delete all remote data
145 before an upload is performed.
146
147 FHR stores various state in preferences.
148
149 Registering Providers
150 =====================
151
152 Firefox Health Report providers are registered via the category manager.
153 See ``HealthReportComponents.manifest`` for providers defined in this
154 directory.
155
156 Essentially, the category manager receives the name of a JS type and the
157 URI of a JSM to import that exports this symbol. At run-time, the
158 providers registered in the category manager are instantiated.
159
160 Providers are registered via the category manager to make registration
161 simple and less prone to errors. Any XPCOM component can create a
162 category manager entry. Therefore, new data providers can be added
163 without having to touch core Firefox Health Report code. Additionally,
164 category manager registration means providers are more likely to be
165 registered on FHR's terms, when it wants. If providers were registered
166 in code at application run-time, there would be the risk of other
167 components prematurely instantiating FHR (causing a performance hit if
168 performed at an inopportune time) or semi-complicated code around
169 observers or listeners. Category manager entries are only 1 line per
170 provider and leave FHR in control: they are simple and safe.
171
172 Document Generation and Lifecycle
173 =================================
174
175 FHR will attempt to submit a JSON document containing data every 24 wall
176 clock hours.
177
178 At upload time, FHR will query the database for **all** information from
179 the last 180 days and assemble this data into a JSON document. We
180 attempt to upload this JSON document with a client-generated UUID to the
181 configured server.
182
183 Before we attempt upload, the generated UUID is stored in the JSON state
184 file on local disk. At this point, the client assumes the document with
185 that UUID has been successfully stored on the server.
186
187 If the client is aware of other document UUIDs that presumably exist on
188 the server, those UUIDs are sent with the upload request so the client
189 can request those UUIDs be deleted. This helps ensure that each client
190 only has 1 document/UUID on the server at any one time.
191
192 Importance of Persisting UUIDs
193 ------------------------------
194
195 The choices of how, where, and when document UUIDs are stored and updated
196 are very important. One should not attempt to change things unless she
197 has a very detailed understanding of why things are the way they are.
198
199 The client is purposefully very conservative about forgetting about
200 generated UUIDs. In other words, once a UUID is generated, the client
201 deliberately holds on to that UUID until it's very confident that UUID
202 is no longer stored on the server. The reason we do this is because
203 *orphaned* documents/UUIDs on the server can lead to faulty analysis,
204 such as over-reporting the number of Firefox installs that stop being
205 used.
206
207 When uploading a new UUID, we update the state and save the state file
208 to disk *before* an upload attempt because if the upload succeeds but
209 the response never makes it back to the client, we want the client to
210 know about the uploaded UUID so it can delete it later to prevent an
211 orphan.
212
213 We maintain a list of UUIDs locally (not simply the last UUID) because
214 multiple upload attempts could fail the same way as the previous
215 paragraph describes and we have no way of knowing which (if any)
216 actually succeeded. The safest approach is to assume every document
217 produced managed to get uploaded some how.
218
219 We store the UUIDs on a file on disk and not anywhere else because we
220 want storage to be robust. We originally stored UUIDs in preferences,
221 which only flush to disk periodically. Writes to preferences were
222 apparently getting lost. We switched to writing directly to files to
223 eliminate this window.

mercurial