blob: f8a316aa22530ae7027c78764e879cf716991d85 [file] [log] [blame]
David Zeuthen33bae492014-02-25 16:16:18 -08001// Copyright 2014 The Chromium OS Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "update_engine/metrics.h"
6
7#include <string>
8
9#include <base/logging.h>
10
11#include "update_engine/constants.h"
12#include "update_engine/clock_interface.h"
13#include "update_engine/prefs_interface.h"
14#include "update_engine/system_state.h"
15#include "update_engine/utils.h"
16
17using std::string;
18
19namespace chromeos_update_engine {
20
21namespace metrics {
22
23// UpdateEngine.Daily.* metrics.
24const char kMetricDailyOSAgeDays[] = "UpdateEngine.Daily.OSAgeDays";
25
26// UpdateEngine.Check.* metrics.
27const char kMetricCheckDownloadErrorCode[] =
28 "UpdateEngine.Check.DownloadErrorCode";
29const char kMetricCheckReaction[] = "UpdateEngine.Check.Reaction";
30const char kMetricCheckResult[] = "UpdateEngine.Check.Result";
31const char kMetricCheckTimeSinceLastCheckMinutes[] =
32 "UpdateEngine.Check.TimeSinceLastCheckMinutes";
33const char kMetricCheckTimeSinceLastCheckUptimeMinutes[] =
34 "UpdateEngine.Check.TimeSinceLastCheckUptimeMinutes";
35
36// UpdateEngine.Attempt.* metrics.
37const char kMetricAttemptNumber[] = "UpdateEngine.Attempt.Number";
38const char kMetricAttemptPayloadType[] =
39 "UpdateEngine.Attempt.PayloadType";
40const char kMetricAttemptPayloadSizeMiB[] =
41 "UpdateEngine.Attempt.PayloadSizeMiB";
David Zeuthenb281f072014-04-02 10:20:19 -070042const char kMetricAttemptConnectionType[] =
43 "UpdateEngine.Attempt.ConnectionType";
David Zeuthen33bae492014-02-25 16:16:18 -080044const char kMetricAttemptDurationMinutes[] =
45 "UpdateEngine.Attempt.DurationMinutes";
46const char kMetricAttemptDurationUptimeMinutes[] =
47 "UpdateEngine.Attempt.DurationUptimeMinutes";
48const char kMetricAttemptTimeSinceLastAttemptMinutes[] =
49 "UpdateEngine.Attempt.TimeSinceLastAttemptMinutes";
50const char kMetricAttemptTimeSinceLastAttemptUptimeMinutes[] =
51 "UpdateEngine.Attempt.TimeSinceLastAttemptUptimeMinutes";
David Zeuthen33bae492014-02-25 16:16:18 -080052const char kMetricAttemptPayloadBytesDownloadedMiB[] =
53 "UpdateEngine.Attempt.PayloadBytesDownloadedMiB";
54const char kMetricAttemptPayloadDownloadSpeedKBps[] =
55 "UpdateEngine.Attempt.PayloadDownloadSpeedKBps";
56const char kMetricAttemptDownloadSource[] =
57 "UpdateEngine.Attempt.DownloadSource";
58const char kMetricAttemptResult[] =
59 "UpdateEngine.Attempt.Result";
60const char kMetricAttemptInternalErrorCode[] =
61 "UpdateEngine.Attempt.InternalErrorCode";
62const char kMetricAttemptDownloadErrorCode[] =
63 "UpdateEngine.Attempt.DownloadErrorCode";
64
65// UpdateEngine.SuccessfulUpdate.* metrics.
66const char kMetricSuccessfulUpdateAttemptCount[] =
67 "UpdateEngine.SuccessfulUpdate.AttemptCount";
68const char kMetricSuccessfulUpdateBytesDownloadedMiB[] =
69 "UpdateEngine.SuccessfulUpdate.BytesDownloadedMiB";
70const char kMetricSuccessfulUpdateDownloadOverheadPercentage[] =
71 "UpdateEngine.SuccessfulUpdate.DownloadOverheadPercentage";
72const char kMetricSuccessfulUpdateDownloadSourcesUsed[] =
73 "UpdateEngine.SuccessfulUpdate.DownloadSourcesUsed";
74const char kMetricSuccessfulUpdatePayloadType[] =
75 "UpdateEngine.SuccessfulUpdate.PayloadType";
76const char kMetricSuccessfulUpdatePayloadSizeMiB[] =
77 "UpdateEngine.SuccessfulUpdate.PayloadSizeMiB";
78const char kMetricSuccessfulUpdateRebootCount[] =
79 "UpdateEngine.SuccessfulUpdate.RebootCount";
80const char kMetricSuccessfulUpdateTotalDurationMinutes[] =
81 "UpdateEngine.SuccessfulUpdate.TotalDurationMinutes";
82const char kMetricSuccessfulUpdateUpdatesAbandonedCount[] =
83 "UpdateEngine.SuccessfulUpdate.UpdatesAbandonedCount";
84const char kMetricSuccessfulUpdateUrlSwitchCount[] =
85 "UpdateEngine.SuccessfulUpdate.UrlSwitchCount";
86
David Zeuthen96197df2014-04-16 12:22:39 -070087// UpdateEngine.Rollback.* metric.
88const char kMetricRollbackResult[] = "UpdateEngine.Rollback.Result";
89
David Zeuthen33bae492014-02-25 16:16:18 -080090// UpdateEngine.* metrics.
91const char kMetricFailedUpdateCount[] = "UpdateEngine.FailedUpdateCount";
92const char kMetricInstallDateProvisioningSource[] =
93 "UpdateEngine.InstallDateProvisioningSource";
94const char kMetricTimeToRebootMinutes[] =
95 "UpdateEngine.TimeToRebootMinutes";
96
97void ReportDailyMetrics(SystemState *system_state,
98 base::TimeDelta os_age) {
99 string metric = metrics::kMetricDailyOSAgeDays;
100 LOG(INFO) << "Uploading " << utils::FormatTimeDelta(os_age)
101 << " for metric " << metric;
102 system_state->metrics_lib()->SendToUMA(
103 metric,
104 static_cast<int>(os_age.InDays()),
105 0, // min: 0 days
106 6*30, // max: 6 months (approx)
107 50); // num_buckets
108}
109
110void ReportUpdateCheckMetrics(SystemState *system_state,
111 CheckResult result,
112 CheckReaction reaction,
113 DownloadErrorCode download_error_code) {
114 string metric;
115 int value;
116 int max_value;
117
118 if (result != metrics::CheckResult::kUnset) {
119 metric = metrics::kMetricCheckResult;
120 value = static_cast<int>(result);
121 max_value = static_cast<int>(metrics::CheckResult::kNumConstants) - 1;
122 LOG(INFO) << "Sending " << value << " for metric " << metric << " (enum)";
123 system_state->metrics_lib()->SendEnumToUMA(metric, value, max_value);
124 }
125 if (reaction != metrics::CheckReaction::kUnset) {
126 metric = metrics::kMetricCheckReaction;
127 value = static_cast<int>(reaction);
128 max_value = static_cast<int>(metrics::CheckReaction::kNumConstants) - 1;
129 LOG(INFO) << "Sending " << value << " for metric " << metric << " (enum)";
130 system_state->metrics_lib()->SendEnumToUMA(metric, value, max_value);
131 }
132 if (download_error_code != metrics::DownloadErrorCode::kUnset) {
133 metric = metrics::kMetricCheckDownloadErrorCode;
134 value = static_cast<int>(download_error_code);
David Zeuthenc0dd0212014-04-04 14:49:49 -0700135 LOG(INFO) << "Sending " << value << " for metric " << metric << " (sparse)";
136 system_state->metrics_lib()->SendSparseToUMA(metric, value);
David Zeuthen33bae492014-02-25 16:16:18 -0800137 }
138
139 base::TimeDelta time_since_last;
140 if (utils::WallclockDurationHelper(system_state,
141 kPrefsMetricsCheckLastReportingTime,
142 &time_since_last)) {
143 metric = kMetricCheckTimeSinceLastCheckMinutes;
144 LOG(INFO) << "Sending " << utils::FormatTimeDelta(time_since_last)
145 << " for metric " << metric;
146 system_state->metrics_lib()->SendToUMA(
147 metric,
148 time_since_last.InMinutes(),
149 0, // min: 0 min
150 30*24*60, // max: 30 days
151 50); // num_buckets
152 }
153
154 base::TimeDelta uptime_since_last;
155 static int64_t uptime_since_last_storage = 0;
156 if (utils::MonotonicDurationHelper(system_state,
157 &uptime_since_last_storage,
158 &uptime_since_last)) {
159 metric = kMetricCheckTimeSinceLastCheckUptimeMinutes;
160 LOG(INFO) << "Sending " << utils::FormatTimeDelta(uptime_since_last)
161 << " for metric " << metric;
162 system_state->metrics_lib()->SendToUMA(
163 metric,
164 uptime_since_last.InMinutes(),
165 0, // min: 0 min
166 30*24*60, // max: 30 days
167 50); // num_buckets
168 }
169}
170
David Zeuthen4e1d1492014-04-25 13:12:27 -0700171void ReportAbnormallyTerminatedUpdateAttemptMetrics(
172 SystemState *system_state) {
173
174 string metric = metrics::kMetricAttemptResult;
175 AttemptResult attempt_result = AttemptResult::kAbnormalTermination;
176
177 LOG(INFO) << "Uploading " << static_cast<int>(attempt_result)
178 << " for metric " << metric;
179 system_state->metrics_lib()->SendEnumToUMA(
180 metric,
181 static_cast<int>(attempt_result),
182 static_cast<int>(AttemptResult::kNumConstants));
183}
184
David Zeuthen33bae492014-02-25 16:16:18 -0800185void ReportUpdateAttemptMetrics(
186 SystemState *system_state,
187 int attempt_number,
188 PayloadType payload_type,
189 base::TimeDelta duration,
190 base::TimeDelta duration_uptime,
191 int64_t payload_size,
192 int64_t payload_bytes_downloaded,
193 int64_t payload_download_speed_bps,
194 DownloadSource download_source,
195 AttemptResult attempt_result,
196 ErrorCode internal_error_code,
David Zeuthenb281f072014-04-02 10:20:19 -0700197 DownloadErrorCode payload_download_error_code,
198 ConnectionType connection_type) {
David Zeuthen33bae492014-02-25 16:16:18 -0800199 string metric;
200
201 metric = metrics::kMetricAttemptNumber;
202 LOG(INFO) << "Uploading " << attempt_number << " for metric " << metric;
203 system_state->metrics_lib()->SendToUMA(metric,
204 attempt_number,
205 0, // min: 0 attempts
206 49, // max: 49 attempts
207 50); // num_buckets
208
209 metric = metrics::kMetricAttemptPayloadType;
210 LOG(INFO) << "Uploading " << utils::ToString(payload_type)
211 << " for metric " << metric;
212 system_state->metrics_lib()->SendEnumToUMA(metric,
213 payload_type,
214 kNumPayloadTypes);
215
216 metric = metrics::kMetricAttemptDurationMinutes;
217 LOG(INFO) << "Uploading " << utils::FormatTimeDelta(duration)
218 << " for metric " << metric;
219 system_state->metrics_lib()->SendToUMA(metric,
220 duration.InMinutes(),
221 0, // min: 0 min
222 10*24*60, // max: 10 days
223 50); // num_buckets
224
225 metric = metrics::kMetricAttemptDurationUptimeMinutes;
226 LOG(INFO) << "Uploading " << utils::FormatTimeDelta(duration_uptime)
227 << " for metric " << metric;
228 system_state->metrics_lib()->SendToUMA(metric,
229 duration_uptime.InMinutes(),
230 0, // min: 0 min
231 10*24*60, // max: 10 days
232 50); // num_buckets
233
234 metric = metrics::kMetricAttemptPayloadSizeMiB;
235 int64_t payload_size_mib = payload_size / kNumBytesInOneMiB;
236 LOG(INFO) << "Uploading " << payload_size_mib << " for metric " << metric;
237 system_state->metrics_lib()->SendToUMA(metric,
238 payload_size_mib,
239 0, // min: 0 MiB
240 1024, // max: 1024 MiB = 1 GiB
241 50); // num_buckets
242
243 metric = metrics::kMetricAttemptPayloadBytesDownloadedMiB;
244 int64_t payload_bytes_downloaded_mib =
245 payload_bytes_downloaded / kNumBytesInOneMiB;
246 LOG(INFO) << "Uploading " << payload_bytes_downloaded_mib
247 << " for metric " << metric;
248 system_state->metrics_lib()->SendToUMA(metric,
249 payload_bytes_downloaded_mib,
250 0, // min: 0 MiB
251 1024, // max: 1024 MiB = 1 GiB
252 50); // num_buckets
253
254 metric = metrics::kMetricAttemptPayloadDownloadSpeedKBps;
255 int64_t payload_download_speed_kbps = payload_download_speed_bps / 1000;
256 LOG(INFO) << "Uploading " << payload_download_speed_kbps
257 << " for metric " << metric;
258 system_state->metrics_lib()->SendToUMA(metric,
259 payload_download_speed_kbps,
260 0, // min: 0 kB/s
261 10*1000, // max: 10000 kB/s = 10 MB/s
262 50); // num_buckets
263
264 metric = metrics::kMetricAttemptDownloadSource;
265 LOG(INFO) << "Uploading " << download_source
266 << " for metric " << metric;
267 system_state->metrics_lib()->SendEnumToUMA(metric,
268 download_source,
269 kNumDownloadSources);
270
271 metric = metrics::kMetricAttemptResult;
272 LOG(INFO) << "Uploading " << static_cast<int>(attempt_result)
273 << " for metric " << metric;
274 system_state->metrics_lib()->SendEnumToUMA(
275 metric,
276 static_cast<int>(attempt_result),
277 static_cast<int>(AttemptResult::kNumConstants));
278
279 if (internal_error_code != kErrorCodeSuccess) {
280 metric = metrics::kMetricAttemptInternalErrorCode;
281 LOG(INFO) << "Uploading " << internal_error_code
282 << " for metric " << metric;
283 system_state->metrics_lib()->SendEnumToUMA(
284 metric,
285 internal_error_code,
286 kErrorCodeUmaReportedMax);
287 }
288
289 if (payload_download_error_code != DownloadErrorCode::kUnset) {
290 metric = metrics::kMetricAttemptDownloadErrorCode;
291 LOG(INFO) << "Uploading " << static_cast<int>(payload_download_error_code)
David Zeuthenc0dd0212014-04-04 14:49:49 -0700292 << " for metric " << metric << " (sparse)";
293 system_state->metrics_lib()->SendSparseToUMA(
David Zeuthen33bae492014-02-25 16:16:18 -0800294 metric,
David Zeuthenc0dd0212014-04-04 14:49:49 -0700295 static_cast<int>(payload_download_error_code));
David Zeuthen33bae492014-02-25 16:16:18 -0800296 }
297
298 base::TimeDelta time_since_last;
299 if (utils::WallclockDurationHelper(system_state,
300 kPrefsMetricsAttemptLastReportingTime,
301 &time_since_last)) {
302 metric = kMetricAttemptTimeSinceLastAttemptMinutes;
303 LOG(INFO) << "Sending " << utils::FormatTimeDelta(time_since_last)
304 << " for metric " << metric;
305 system_state->metrics_lib()->SendToUMA(
306 metric,
307 time_since_last.InMinutes(),
308 0, // min: 0 min
309 30*24*60, // max: 30 days
310 50); // num_buckets
311 }
312
313 static int64_t uptime_since_last_storage = 0;
314 base::TimeDelta uptime_since_last;
315 if (utils::MonotonicDurationHelper(system_state,
316 &uptime_since_last_storage,
317 &uptime_since_last)) {
318 metric = kMetricAttemptTimeSinceLastAttemptUptimeMinutes;
319 LOG(INFO) << "Sending " << utils::FormatTimeDelta(uptime_since_last)
320 << " for metric " << metric;
321 system_state->metrics_lib()->SendToUMA(
322 metric,
323 uptime_since_last.InMinutes(),
324 0, // min: 0 min
325 30*24*60, // max: 30 days
326 50); // num_buckets
327 }
David Zeuthenb281f072014-04-02 10:20:19 -0700328
329 metric = metrics::kMetricAttemptConnectionType;
330 LOG(INFO) << "Uploading " << static_cast<int>(connection_type)
331 << " for metric " << metric;
332 system_state->metrics_lib()->SendEnumToUMA(
333 metric,
334 static_cast<int>(connection_type),
335 static_cast<int>(ConnectionType::kNumConstants));
David Zeuthen33bae492014-02-25 16:16:18 -0800336}
337
338
339void ReportSuccessfulUpdateMetrics(
340 SystemState *system_state,
341 int attempt_count,
342 int updates_abandoned_count,
343 PayloadType payload_type,
344 int64_t payload_size,
345 int64_t num_bytes_downloaded[kNumDownloadSources],
346 int download_overhead_percentage,
347 base::TimeDelta total_duration,
348 int reboot_count,
349 int url_switch_count) {
350 string metric;
351 int64_t mbs;
352
353 metric = kMetricSuccessfulUpdatePayloadSizeMiB;
354 mbs = payload_size / kNumBytesInOneMiB;
355 LOG(INFO) << "Uploading " << mbs << " (MiBs) for metric " << metric;
356 system_state->metrics_lib()->SendToUMA(metric,
357 mbs,
358 0, // min: 0 MiB
359 1024, // max: 1024 MiB = 1 GiB
360 50); // num_buckets
361
362 int64_t total_bytes = 0;
363 int download_sources_used = 0;
364 for (int i = 0; i < kNumDownloadSources + 1; i++) {
365 DownloadSource source = static_cast<DownloadSource>(i);
366
367 // Only consider this download source (and send byte counts) as
368 // having been used if we downloaded a non-trivial amount of bytes
369 // (e.g. at least 1 MiB) that contributed to the the
370 // update. Otherwise we're going to end up with a lot of zero-byte
371 // events in the histogram.
372
373 metric = metrics::kMetricSuccessfulUpdateBytesDownloadedMiB;
374 if (i < kNumDownloadSources) {
375 metric += utils::ToString(source);
376 mbs = num_bytes_downloaded[i] / kNumBytesInOneMiB;
377 total_bytes += num_bytes_downloaded[i];
378 if (mbs > 0)
379 download_sources_used |= (1 << i);
380 } else {
381 mbs = total_bytes / kNumBytesInOneMiB;
382 }
383
384 if (mbs > 0) {
385 LOG(INFO) << "Uploading " << mbs << " (MiBs) for metric " << metric;
386 system_state->metrics_lib()->SendToUMA(metric,
387 mbs,
388 0, // min: 0 MiB
389 1024, // max: 1024 MiB = 1 GiB
390 50); // num_buckets
391 }
392 }
393
394 metric = metrics::kMetricSuccessfulUpdateDownloadSourcesUsed;
395 LOG(INFO) << "Uploading 0x" << std::hex << download_sources_used
396 << " (bit flags) for metric " << metric;
397 system_state->metrics_lib()->SendToUMA(
398 metric,
399 download_sources_used,
400 0, // min
401 (1 << kNumDownloadSources) - 1, // max
402 1 << kNumDownloadSources); // num_buckets
403
404 metric = metrics::kMetricSuccessfulUpdateDownloadOverheadPercentage;
405 LOG(INFO) << "Uploading " << download_overhead_percentage
406 << "% for metric " << metric;
407 system_state->metrics_lib()->SendToUMA(metric,
408 download_overhead_percentage,
409 0, // min: 0% overhead
410 1000, // max: 1000% overhead
411 50); // num_buckets
412
413 metric = metrics::kMetricSuccessfulUpdateUrlSwitchCount;
414 LOG(INFO) << "Uploading " << url_switch_count
415 << " (count) for metric " << metric;
416 system_state->metrics_lib()->SendToUMA(metric,
417 url_switch_count,
418 0, // min: 0 URL switches
419 49, // max: 49 URL switches
420 50); // num_buckets
421
422 metric = metrics::kMetricSuccessfulUpdateTotalDurationMinutes;
423 LOG(INFO) << "Uploading " << utils::FormatTimeDelta(total_duration)
424 << " for metric " << metric;
425 system_state->metrics_lib()->SendToUMA(
426 metric,
427 static_cast<int>(total_duration.InMinutes()),
428 0, // min: 0 min
429 365*24*60, // max: 365 days ~= 1 year
430 50); // num_buckets
431
432 metric = metrics::kMetricSuccessfulUpdateRebootCount;
433 LOG(INFO) << "Uploading reboot count of " << reboot_count << " for metric "
434 << metric;
435 system_state->metrics_lib()->SendToUMA(metric,
436 reboot_count,
437 0, // min: 0 reboots
438 49, // max: 49 reboots
439 50); // num_buckets
440
441 metric = metrics::kMetricSuccessfulUpdatePayloadType;
442 system_state->metrics_lib()->SendEnumToUMA(metric,
443 payload_type,
444 kNumPayloadTypes);
445 LOG(INFO) << "Uploading " << utils::ToString(payload_type)
446 << " for metric " << metric;
447
448 metric = metrics::kMetricSuccessfulUpdateAttemptCount;
449 system_state->metrics_lib()->SendToUMA(metric,
450 attempt_count,
451 1, // min: 1 attempt
452 50, // max: 50 attempts
453 50); // num_buckets
454 LOG(INFO) << "Uploading " << attempt_count
455 << " for metric " << metric;
456
457 metric = metrics::kMetricSuccessfulUpdateUpdatesAbandonedCount;
458 LOG(INFO) << "Uploading " << updates_abandoned_count
459 << " (count) for metric " << metric;
460 system_state->metrics_lib()->SendToUMA(metric,
461 updates_abandoned_count,
462 0, // min: 0 counts
463 49, // max: 49 counts
464 50); // num_buckets
465}
466
David Zeuthen96197df2014-04-16 12:22:39 -0700467void ReportRollbackMetrics(SystemState *system_state,
468 RollbackResult result) {
469 string metric;
470 int value;
471
472 metric = metrics::kMetricRollbackResult;
473 value = static_cast<int>(result);
474 LOG(INFO) << "Sending " << value << " for metric " << metric << " (enum)";
475 system_state->metrics_lib()->SendEnumToUMA(
476 metric,
477 value,
478 static_cast<int>(metrics::RollbackResult::kNumConstants));
479}
480
David Zeuthen33bae492014-02-25 16:16:18 -0800481} // namespace metrics
482
483} // namespace chromeos_update_engine