blob: 65093a1e0e6650b149f8f4a89fda43e82cf2fd73 [file] [log] [blame]
Alex Deymoaea4c1c2015-08-19 20:24:43 -07001//
2// Copyright (C) 2014 The Android Open Source Project
3//
4// Licensed under the Apache License, Version 2.0 (the "License");
5// you may not use this file except in compliance with the License.
6// You may obtain a copy of the License at
7//
8// http://www.apache.org/licenses/LICENSE-2.0
9//
10// Unless required by applicable law or agreed to in writing, software
11// distributed under the License is distributed on an "AS IS" BASIS,
12// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13// See the License for the specific language governing permissions and
14// limitations under the License.
15//
David Zeuthen33bae492014-02-25 16:16:18 -080016
Amin Hassaniec7bc112020-10-29 16:47:58 -070017#include "update_engine/cros/metrics_reporter_omaha.h"
David Zeuthen33bae492014-02-25 16:16:18 -080018
Tianjie Xu98333a82017-09-22 21:29:29 -070019#include <memory>
David Zeuthen33bae492014-02-25 16:16:18 -080020
21#include <base/logging.h>
Marton Hunyadya0302682018-05-16 18:52:13 +020022#include <base/strings/string_number_conversions.h>
Alex Deymoa2591792015-11-17 00:39:40 -030023#include <metrics/metrics_library.h>
David Zeuthen33bae492014-02-25 16:16:18 -080024
Alex Deymo39910dc2015-11-09 17:04:30 -080025#include "update_engine/common/clock_interface.h"
26#include "update_engine/common/constants.h"
27#include "update_engine/common/prefs_interface.h"
Amin Hassaniec7bc112020-10-29 16:47:58 -070028#include "update_engine/common/system_state.h"
Alex Deymo39910dc2015-11-09 17:04:30 -080029#include "update_engine/common/utils.h"
Amin Hassaniec7bc112020-10-29 16:47:58 -070030#include "update_engine/cros/omaha_request_params.h"
Alex Deymoa2591792015-11-17 00:39:40 -030031#include "update_engine/metrics_utils.h"
David Zeuthen33bae492014-02-25 16:16:18 -080032
Amin Hassaniec7bc112020-10-29 16:47:58 -070033using base::Time;
34using base::TimeDelta;
David Zeuthen33bae492014-02-25 16:16:18 -080035using std::string;
36
37namespace chromeos_update_engine {
Tianjie Xu98333a82017-09-22 21:29:29 -070038namespace metrics {
39
David Zeuthen33bae492014-02-25 16:16:18 -080040// UpdateEngine.Daily.* metrics.
Tianjie Xu98333a82017-09-22 21:29:29 -070041const char kMetricDailyOSAgeDays[] = "UpdateEngine.Daily.OSAgeDays";
David Zeuthen33bae492014-02-25 16:16:18 -080042
43// UpdateEngine.Check.* metrics.
Tianjie Xu98333a82017-09-22 21:29:29 -070044const char kMetricCheckDownloadErrorCode[] =
David Zeuthen33bae492014-02-25 16:16:18 -080045 "UpdateEngine.Check.DownloadErrorCode";
Tianjie Xu98333a82017-09-22 21:29:29 -070046const char kMetricCheckReaction[] = "UpdateEngine.Check.Reaction";
47const char kMetricCheckResult[] = "UpdateEngine.Check.Result";
Marton Hunyadya0302682018-05-16 18:52:13 +020048const char kMetricCheckTargetVersion[] = "UpdateEngine.Check.TargetVersion";
49const char kMetricCheckRollbackTargetVersion[] =
50 "UpdateEngine.Check.RollbackTargetVersion";
Tianjie Xu98333a82017-09-22 21:29:29 -070051const char kMetricCheckTimeSinceLastCheckMinutes[] =
David Zeuthen33bae492014-02-25 16:16:18 -080052 "UpdateEngine.Check.TimeSinceLastCheckMinutes";
Tianjie Xu98333a82017-09-22 21:29:29 -070053const char kMetricCheckTimeSinceLastCheckUptimeMinutes[] =
David Zeuthen33bae492014-02-25 16:16:18 -080054 "UpdateEngine.Check.TimeSinceLastCheckUptimeMinutes";
55
56// UpdateEngine.Attempt.* metrics.
Tianjie Xu98333a82017-09-22 21:29:29 -070057const char kMetricAttemptNumber[] = "UpdateEngine.Attempt.Number";
58const char kMetricAttemptPayloadType[] = "UpdateEngine.Attempt.PayloadType";
59const char kMetricAttemptPayloadSizeMiB[] =
David Zeuthen33bae492014-02-25 16:16:18 -080060 "UpdateEngine.Attempt.PayloadSizeMiB";
Tianjie Xu98333a82017-09-22 21:29:29 -070061const char kMetricAttemptConnectionType[] =
David Zeuthenb281f072014-04-02 10:20:19 -070062 "UpdateEngine.Attempt.ConnectionType";
Tianjie Xu98333a82017-09-22 21:29:29 -070063const char kMetricAttemptDurationMinutes[] =
David Zeuthen33bae492014-02-25 16:16:18 -080064 "UpdateEngine.Attempt.DurationMinutes";
Tianjie Xu98333a82017-09-22 21:29:29 -070065const char kMetricAttemptDurationUptimeMinutes[] =
David Zeuthen33bae492014-02-25 16:16:18 -080066 "UpdateEngine.Attempt.DurationUptimeMinutes";
Tianjie Xu98333a82017-09-22 21:29:29 -070067const char kMetricAttemptTimeSinceLastAttemptMinutes[] =
David Zeuthen33bae492014-02-25 16:16:18 -080068 "UpdateEngine.Attempt.TimeSinceLastAttemptMinutes";
Tianjie Xu98333a82017-09-22 21:29:29 -070069const char kMetricAttemptTimeSinceLastAttemptUptimeMinutes[] =
David Zeuthen33bae492014-02-25 16:16:18 -080070 "UpdateEngine.Attempt.TimeSinceLastAttemptUptimeMinutes";
Tianjie Xu98333a82017-09-22 21:29:29 -070071const char kMetricAttemptPayloadBytesDownloadedMiB[] =
David Zeuthen33bae492014-02-25 16:16:18 -080072 "UpdateEngine.Attempt.PayloadBytesDownloadedMiB";
Tianjie Xu98333a82017-09-22 21:29:29 -070073const char kMetricAttemptPayloadDownloadSpeedKBps[] =
David Zeuthen33bae492014-02-25 16:16:18 -080074 "UpdateEngine.Attempt.PayloadDownloadSpeedKBps";
Tianjie Xu98333a82017-09-22 21:29:29 -070075const char kMetricAttemptDownloadSource[] =
David Zeuthen33bae492014-02-25 16:16:18 -080076 "UpdateEngine.Attempt.DownloadSource";
Tianjie Xu98333a82017-09-22 21:29:29 -070077const char kMetricAttemptResult[] = "UpdateEngine.Attempt.Result";
78const char kMetricAttemptInternalErrorCode[] =
David Zeuthen33bae492014-02-25 16:16:18 -080079 "UpdateEngine.Attempt.InternalErrorCode";
Tianjie Xu98333a82017-09-22 21:29:29 -070080const char kMetricAttemptDownloadErrorCode[] =
David Zeuthen33bae492014-02-25 16:16:18 -080081 "UpdateEngine.Attempt.DownloadErrorCode";
82
83// UpdateEngine.SuccessfulUpdate.* metrics.
Tianjie Xu98333a82017-09-22 21:29:29 -070084const char kMetricSuccessfulUpdateAttemptCount[] =
David Zeuthen33bae492014-02-25 16:16:18 -080085 "UpdateEngine.SuccessfulUpdate.AttemptCount";
Tianjie Xu98333a82017-09-22 21:29:29 -070086const char kMetricSuccessfulUpdateBytesDownloadedMiB[] =
David Zeuthen33bae492014-02-25 16:16:18 -080087 "UpdateEngine.SuccessfulUpdate.BytesDownloadedMiB";
Tianjie Xu98333a82017-09-22 21:29:29 -070088const char kMetricSuccessfulUpdateDownloadOverheadPercentage[] =
David Zeuthen33bae492014-02-25 16:16:18 -080089 "UpdateEngine.SuccessfulUpdate.DownloadOverheadPercentage";
Tianjie Xu98333a82017-09-22 21:29:29 -070090const char kMetricSuccessfulUpdateDownloadSourcesUsed[] =
David Zeuthen33bae492014-02-25 16:16:18 -080091 "UpdateEngine.SuccessfulUpdate.DownloadSourcesUsed";
May Lippert60aa3ca2018-08-15 16:55:29 -070092const char kMetricSuccessfulUpdateDurationFromSeenDays[] =
93 "UpdateEngine.SuccessfulUpdate.DurationFromSeenDays.NoTimeRestriction";
94const char kMetricSuccessfulUpdateDurationFromSeenTimeRestrictedDays[] =
95 "UpdateEngine.SuccessfulUpdate.DurationFromSeenDays.TimeRestricted";
Tianjie Xu98333a82017-09-22 21:29:29 -070096const char kMetricSuccessfulUpdatePayloadType[] =
David Zeuthen33bae492014-02-25 16:16:18 -080097 "UpdateEngine.SuccessfulUpdate.PayloadType";
Tianjie Xu98333a82017-09-22 21:29:29 -070098const char kMetricSuccessfulUpdatePayloadSizeMiB[] =
David Zeuthen33bae492014-02-25 16:16:18 -080099 "UpdateEngine.SuccessfulUpdate.PayloadSizeMiB";
Tianjie Xu98333a82017-09-22 21:29:29 -0700100const char kMetricSuccessfulUpdateRebootCount[] =
David Zeuthen33bae492014-02-25 16:16:18 -0800101 "UpdateEngine.SuccessfulUpdate.RebootCount";
Tianjie Xu98333a82017-09-22 21:29:29 -0700102const char kMetricSuccessfulUpdateTotalDurationMinutes[] =
David Zeuthen33bae492014-02-25 16:16:18 -0800103 "UpdateEngine.SuccessfulUpdate.TotalDurationMinutes";
Sen Jiang8712e962018-05-08 12:12:28 -0700104const char kMetricSuccessfulUpdateTotalDurationUptimeMinutes[] =
105 "UpdateEngine.SuccessfulUpdate.TotalDurationUptimeMinutes";
Tianjie Xu98333a82017-09-22 21:29:29 -0700106const char kMetricSuccessfulUpdateUpdatesAbandonedCount[] =
David Zeuthen33bae492014-02-25 16:16:18 -0800107 "UpdateEngine.SuccessfulUpdate.UpdatesAbandonedCount";
Tianjie Xu98333a82017-09-22 21:29:29 -0700108const char kMetricSuccessfulUpdateUrlSwitchCount[] =
David Zeuthen33bae492014-02-25 16:16:18 -0800109 "UpdateEngine.SuccessfulUpdate.UrlSwitchCount";
110
David Zeuthen96197df2014-04-16 12:22:39 -0700111// UpdateEngine.Rollback.* metric.
Tianjie Xu98333a82017-09-22 21:29:29 -0700112const char kMetricRollbackResult[] = "UpdateEngine.Rollback.Result";
David Zeuthen96197df2014-04-16 12:22:39 -0700113
Marton Hunyadya0302682018-05-16 18:52:13 +0200114// UpdateEngine.EnterpriseRollback.* metrics.
115const char kMetricEnterpriseRollbackFailure[] =
116 "UpdateEngine.EnterpriseRollback.Failure";
117const char kMetricEnterpriseRollbackSuccess[] =
118 "UpdateEngine.EnterpriseRollback.Success";
119
Alex Deymoc1c17b42015-11-23 03:53:15 -0300120// UpdateEngine.CertificateCheck.* metrics.
Tianjie Xu98333a82017-09-22 21:29:29 -0700121const char kMetricCertificateCheckUpdateCheck[] =
Alex Deymoc1c17b42015-11-23 03:53:15 -0300122 "UpdateEngine.CertificateCheck.UpdateCheck";
Tianjie Xu98333a82017-09-22 21:29:29 -0700123const char kMetricCertificateCheckDownload[] =
Alex Deymoc1c17b42015-11-23 03:53:15 -0300124 "UpdateEngine.CertificateCheck.Download";
125
Marton Hunyadyffbfdfb2018-05-30 13:03:29 +0200126// UpdateEngine.KernelKey.* metrics.
127const char kMetricKernelMinVersion[] = "UpdateEngine.KernelKey.MinVersion";
128const char kMetricKernelMaxRollforwardVersion[] =
129 "UpdateEngine.KernelKey.MaxRollforwardVersion";
130const char kMetricKernelMaxRollforwardSetSuccess[] =
131 "UpdateEngine.KernelKey.MaxRollforwardSetSuccess";
132
David Zeuthen33bae492014-02-25 16:16:18 -0800133// UpdateEngine.* metrics.
Tianjie Xu98333a82017-09-22 21:29:29 -0700134const char kMetricFailedUpdateCount[] = "UpdateEngine.FailedUpdateCount";
135const char kMetricInstallDateProvisioningSource[] =
David Zeuthen33bae492014-02-25 16:16:18 -0800136 "UpdateEngine.InstallDateProvisioningSource";
Tianjie Xu98333a82017-09-22 21:29:29 -0700137const char kMetricTimeToRebootMinutes[] = "UpdateEngine.TimeToRebootMinutes";
138
Tianjie Xud4c5deb2017-10-24 11:17:03 -0700139std::unique_ptr<MetricsReporterInterface> CreateMetricsReporter() {
140 return std::make_unique<MetricsReporterOmaha>();
141}
142
Tianjie Xu98333a82017-09-22 21:29:29 -0700143} // namespace metrics
144
145MetricsReporterOmaha::MetricsReporterOmaha()
146 : metrics_lib_(new MetricsLibrary()) {}
David Zeuthen33bae492014-02-25 16:16:18 -0800147
Tianjie Xu282aa1f2017-09-05 13:42:45 -0700148void MetricsReporterOmaha::ReportDailyMetrics(base::TimeDelta os_age) {
Tianjie Xu98333a82017-09-22 21:29:29 -0700149 string metric = metrics::kMetricDailyOSAgeDays;
Tianjie Xu98333a82017-09-22 21:29:29 -0700150 metrics_lib_->SendToUMA(metric,
151 static_cast<int>(os_age.InDays()),
152 0, // min: 0 days
153 6 * 30, // max: 6 months (approx)
154 50); // num_buckets
Tianjie Xu282aa1f2017-09-05 13:42:45 -0700155}
156
157void MetricsReporterOmaha::ReportUpdateCheckMetrics(
Tianjie Xu282aa1f2017-09-05 13:42:45 -0700158 metrics::CheckResult result,
159 metrics::CheckReaction reaction,
160 metrics::DownloadErrorCode download_error_code) {
David Zeuthen33bae492014-02-25 16:16:18 -0800161 string metric;
162 int value;
163 int max_value;
164
165 if (result != metrics::CheckResult::kUnset) {
Tianjie Xu98333a82017-09-22 21:29:29 -0700166 metric = metrics::kMetricCheckResult;
David Zeuthen33bae492014-02-25 16:16:18 -0800167 value = static_cast<int>(result);
168 max_value = static_cast<int>(metrics::CheckResult::kNumConstants) - 1;
Tianjie Xu98333a82017-09-22 21:29:29 -0700169 metrics_lib_->SendEnumToUMA(metric, value, max_value);
David Zeuthen33bae492014-02-25 16:16:18 -0800170 }
171 if (reaction != metrics::CheckReaction::kUnset) {
Tianjie Xu98333a82017-09-22 21:29:29 -0700172 metric = metrics::kMetricCheckReaction;
David Zeuthen33bae492014-02-25 16:16:18 -0800173 value = static_cast<int>(reaction);
174 max_value = static_cast<int>(metrics::CheckReaction::kNumConstants) - 1;
Tianjie Xu98333a82017-09-22 21:29:29 -0700175 metrics_lib_->SendEnumToUMA(metric, value, max_value);
David Zeuthen33bae492014-02-25 16:16:18 -0800176 }
177 if (download_error_code != metrics::DownloadErrorCode::kUnset) {
Tianjie Xu98333a82017-09-22 21:29:29 -0700178 metric = metrics::kMetricCheckDownloadErrorCode;
David Zeuthen33bae492014-02-25 16:16:18 -0800179 value = static_cast<int>(download_error_code);
Tianjie Xu98333a82017-09-22 21:29:29 -0700180 metrics_lib_->SendSparseToUMA(metric, value);
David Zeuthen33bae492014-02-25 16:16:18 -0800181 }
182
183 base::TimeDelta time_since_last;
Amin Hassani538bd592020-11-04 20:46:08 -0800184 if (WallclockDurationHelper(kPrefsMetricsCheckLastReportingTime,
Amin Hassaniec7bc112020-10-29 16:47:58 -0700185 &time_since_last)) {
Tianjie Xu98333a82017-09-22 21:29:29 -0700186 metric = metrics::kMetricCheckTimeSinceLastCheckMinutes;
Tianjie Xu98333a82017-09-22 21:29:29 -0700187 metrics_lib_->SendToUMA(metric,
188 time_since_last.InMinutes(),
189 0, // min: 0 min
190 30 * 24 * 60, // max: 30 days
191 50); // num_buckets
David Zeuthen33bae492014-02-25 16:16:18 -0800192 }
193
194 base::TimeDelta uptime_since_last;
195 static int64_t uptime_since_last_storage = 0;
Amin Hassani538bd592020-11-04 20:46:08 -0800196 if (MonotonicDurationHelper(&uptime_since_last_storage, &uptime_since_last)) {
Tianjie Xu98333a82017-09-22 21:29:29 -0700197 metric = metrics::kMetricCheckTimeSinceLastCheckUptimeMinutes;
Tianjie Xu98333a82017-09-22 21:29:29 -0700198 metrics_lib_->SendToUMA(metric,
199 uptime_since_last.InMinutes(),
200 0, // min: 0 min
201 30 * 24 * 60, // max: 30 days
202 50); // num_buckets
David Zeuthen33bae492014-02-25 16:16:18 -0800203 }
Marton Hunyadya0302682018-05-16 18:52:13 +0200204
205 // First section of target version specified for the update.
Amin Hassani538bd592020-11-04 20:46:08 -0800206 if (SystemState::Get()->request_params()) {
Marton Hunyadya0302682018-05-16 18:52:13 +0200207 string target_version =
Amin Hassani538bd592020-11-04 20:46:08 -0800208 SystemState::Get()->request_params()->target_version_prefix();
Marton Hunyadya0302682018-05-16 18:52:13 +0200209 value = utils::VersionPrefix(target_version);
210 if (value != 0) {
211 metric = metrics::kMetricCheckTargetVersion;
Marton Hunyadya0302682018-05-16 18:52:13 +0200212 metrics_lib_->SendSparseToUMA(metric, value);
Amin Hassani538bd592020-11-04 20:46:08 -0800213 if (SystemState::Get()->request_params()->rollback_allowed()) {
Marton Hunyadya0302682018-05-16 18:52:13 +0200214 metric = metrics::kMetricCheckRollbackTargetVersion;
Marton Hunyadya0302682018-05-16 18:52:13 +0200215 metrics_lib_->SendSparseToUMA(metric, value);
216 }
217 }
218 }
David Zeuthen33bae492014-02-25 16:16:18 -0800219}
220
Tianjie Xu282aa1f2017-09-05 13:42:45 -0700221void MetricsReporterOmaha::ReportAbnormallyTerminatedUpdateAttemptMetrics() {
Tianjie Xu98333a82017-09-22 21:29:29 -0700222 string metric = metrics::kMetricAttemptResult;
Tianjie Xu282aa1f2017-09-05 13:42:45 -0700223 metrics::AttemptResult attempt_result =
224 metrics::AttemptResult::kAbnormalTermination;
David Zeuthen4e1d1492014-04-25 13:12:27 -0700225
Tianjie Xu98333a82017-09-22 21:29:29 -0700226 metrics_lib_->SendEnumToUMA(
David Zeuthen4e1d1492014-04-25 13:12:27 -0700227 metric,
228 static_cast<int>(attempt_result),
Tianjie Xu282aa1f2017-09-05 13:42:45 -0700229 static_cast<int>(metrics::AttemptResult::kNumConstants));
David Zeuthen4e1d1492014-04-25 13:12:27 -0700230}
231
Tianjie Xu282aa1f2017-09-05 13:42:45 -0700232void MetricsReporterOmaha::ReportUpdateAttemptMetrics(
David Zeuthen33bae492014-02-25 16:16:18 -0800233 int attempt_number,
234 PayloadType payload_type,
235 base::TimeDelta duration,
236 base::TimeDelta duration_uptime,
237 int64_t payload_size,
Tianjie Xu282aa1f2017-09-05 13:42:45 -0700238 metrics::AttemptResult attempt_result,
Tianjie Xu1f93d092017-10-09 12:13:29 -0700239 ErrorCode internal_error_code) {
Tianjie Xu98333a82017-09-22 21:29:29 -0700240 string metric = metrics::kMetricAttemptNumber;
Tianjie Xu98333a82017-09-22 21:29:29 -0700241 metrics_lib_->SendToUMA(metric,
242 attempt_number,
243 0, // min: 0 attempts
244 49, // max: 49 attempts
245 50); // num_buckets
David Zeuthen33bae492014-02-25 16:16:18 -0800246
Tianjie Xu98333a82017-09-22 21:29:29 -0700247 metric = metrics::kMetricAttemptPayloadType;
Tianjie Xu98333a82017-09-22 21:29:29 -0700248 metrics_lib_->SendEnumToUMA(metric, payload_type, kNumPayloadTypes);
David Zeuthen33bae492014-02-25 16:16:18 -0800249
Tianjie Xu98333a82017-09-22 21:29:29 -0700250 metric = metrics::kMetricAttemptDurationMinutes;
Tianjie Xu98333a82017-09-22 21:29:29 -0700251 metrics_lib_->SendToUMA(metric,
252 duration.InMinutes(),
253 0, // min: 0 min
254 10 * 24 * 60, // max: 10 days
255 50); // num_buckets
David Zeuthen33bae492014-02-25 16:16:18 -0800256
Tianjie Xu98333a82017-09-22 21:29:29 -0700257 metric = metrics::kMetricAttemptDurationUptimeMinutes;
Tianjie Xu98333a82017-09-22 21:29:29 -0700258 metrics_lib_->SendToUMA(metric,
259 duration_uptime.InMinutes(),
260 0, // min: 0 min
261 10 * 24 * 60, // max: 10 days
262 50); // num_buckets
David Zeuthen33bae492014-02-25 16:16:18 -0800263
Tianjie Xu98333a82017-09-22 21:29:29 -0700264 metric = metrics::kMetricAttemptPayloadSizeMiB;
David Zeuthen33bae492014-02-25 16:16:18 -0800265 int64_t payload_size_mib = payload_size / kNumBytesInOneMiB;
Tianjie Xu98333a82017-09-22 21:29:29 -0700266 metrics_lib_->SendToUMA(metric,
267 payload_size_mib,
268 0, // min: 0 MiB
269 1024, // max: 1024 MiB = 1 GiB
270 50); // num_buckets
David Zeuthen33bae492014-02-25 16:16:18 -0800271
Tianjie Xu98333a82017-09-22 21:29:29 -0700272 metric = metrics::kMetricAttemptResult;
Tianjie Xu98333a82017-09-22 21:29:29 -0700273 metrics_lib_->SendEnumToUMA(
David Zeuthen33bae492014-02-25 16:16:18 -0800274 metric,
275 static_cast<int>(attempt_result),
Tianjie Xu282aa1f2017-09-05 13:42:45 -0700276 static_cast<int>(metrics::AttemptResult::kNumConstants));
David Zeuthen33bae492014-02-25 16:16:18 -0800277
Gilad Arnoldd1c4d2d2014-06-05 14:07:53 -0700278 if (internal_error_code != ErrorCode::kSuccess) {
Amin Hassani80f4d4c2018-05-16 13:34:00 -0700279 ReportInternalErrorCode(internal_error_code);
David Zeuthen33bae492014-02-25 16:16:18 -0800280 }
281
David Zeuthen33bae492014-02-25 16:16:18 -0800282 base::TimeDelta time_since_last;
Amin Hassani538bd592020-11-04 20:46:08 -0800283 if (WallclockDurationHelper(kPrefsMetricsAttemptLastReportingTime,
Amin Hassaniec7bc112020-10-29 16:47:58 -0700284 &time_since_last)) {
Tianjie Xu98333a82017-09-22 21:29:29 -0700285 metric = metrics::kMetricAttemptTimeSinceLastAttemptMinutes;
Tianjie Xu98333a82017-09-22 21:29:29 -0700286 metrics_lib_->SendToUMA(metric,
287 time_since_last.InMinutes(),
288 0, // min: 0 min
289 30 * 24 * 60, // max: 30 days
290 50); // num_buckets
David Zeuthen33bae492014-02-25 16:16:18 -0800291 }
292
293 static int64_t uptime_since_last_storage = 0;
294 base::TimeDelta uptime_since_last;
Amin Hassani538bd592020-11-04 20:46:08 -0800295 if (MonotonicDurationHelper(&uptime_since_last_storage, &uptime_since_last)) {
Tianjie Xu98333a82017-09-22 21:29:29 -0700296 metric = metrics::kMetricAttemptTimeSinceLastAttemptUptimeMinutes;
Tianjie Xu98333a82017-09-22 21:29:29 -0700297 metrics_lib_->SendToUMA(metric,
298 uptime_since_last.InMinutes(),
299 0, // min: 0 min
300 30 * 24 * 60, // max: 30 days
301 50); // num_buckets
David Zeuthen33bae492014-02-25 16:16:18 -0800302 }
Tianjie Xu1f93d092017-10-09 12:13:29 -0700303}
304
305void MetricsReporterOmaha::ReportUpdateAttemptDownloadMetrics(
306 int64_t payload_bytes_downloaded,
307 int64_t payload_download_speed_bps,
308 DownloadSource download_source,
309 metrics::DownloadErrorCode payload_download_error_code,
310 metrics::ConnectionType connection_type) {
311 string metric = metrics::kMetricAttemptPayloadBytesDownloadedMiB;
312 int64_t payload_bytes_downloaded_mib =
313 payload_bytes_downloaded / kNumBytesInOneMiB;
Tianjie Xu1f93d092017-10-09 12:13:29 -0700314 metrics_lib_->SendToUMA(metric,
315 payload_bytes_downloaded_mib,
316 0, // min: 0 MiB
317 1024, // max: 1024 MiB = 1 GiB
318 50); // num_buckets
319
320 metric = metrics::kMetricAttemptPayloadDownloadSpeedKBps;
321 int64_t payload_download_speed_kbps = payload_download_speed_bps / 1000;
Tianjie Xu1f93d092017-10-09 12:13:29 -0700322 metrics_lib_->SendToUMA(metric,
323 payload_download_speed_kbps,
324 0, // min: 0 kB/s
325 10 * 1000, // max: 10000 kB/s = 10 MB/s
326 50); // num_buckets
327
328 metric = metrics::kMetricAttemptDownloadSource;
Tianjie Xu1f93d092017-10-09 12:13:29 -0700329 metrics_lib_->SendEnumToUMA(metric, download_source, kNumDownloadSources);
330
331 if (payload_download_error_code != metrics::DownloadErrorCode::kUnset) {
332 metric = metrics::kMetricAttemptDownloadErrorCode;
Tianjie Xu1f93d092017-10-09 12:13:29 -0700333 metrics_lib_->SendSparseToUMA(
334 metric, static_cast<int>(payload_download_error_code));
335 }
David Zeuthenb281f072014-04-02 10:20:19 -0700336
Tianjie Xu98333a82017-09-22 21:29:29 -0700337 metric = metrics::kMetricAttemptConnectionType;
Tianjie Xu98333a82017-09-22 21:29:29 -0700338 metrics_lib_->SendEnumToUMA(
David Zeuthenb281f072014-04-02 10:20:19 -0700339 metric,
340 static_cast<int>(connection_type),
Tianjie Xu282aa1f2017-09-05 13:42:45 -0700341 static_cast<int>(metrics::ConnectionType::kNumConstants));
David Zeuthen33bae492014-02-25 16:16:18 -0800342}
343
Tianjie Xu282aa1f2017-09-05 13:42:45 -0700344void MetricsReporterOmaha::ReportSuccessfulUpdateMetrics(
345 int attempt_count,
346 int updates_abandoned_count,
347 PayloadType payload_type,
348 int64_t payload_size,
349 int64_t num_bytes_downloaded[kNumDownloadSources],
350 int download_overhead_percentage,
351 base::TimeDelta total_duration,
Sen Jiang8712e962018-05-08 12:12:28 -0700352 base::TimeDelta total_duration_uptime,
Tianjie Xu282aa1f2017-09-05 13:42:45 -0700353 int reboot_count,
354 int url_switch_count) {
Tianjie Xu98333a82017-09-22 21:29:29 -0700355 string metric = metrics::kMetricSuccessfulUpdatePayloadSizeMiB;
Tianjie Xu282aa1f2017-09-05 13:42:45 -0700356 int64_t mbs = payload_size / kNumBytesInOneMiB;
Tianjie Xu98333a82017-09-22 21:29:29 -0700357 metrics_lib_->SendToUMA(metric,
358 mbs,
359 0, // min: 0 MiB
360 1024, // max: 1024 MiB = 1 GiB
361 50); // num_buckets
David Zeuthen33bae492014-02-25 16:16:18 -0800362
363 int64_t total_bytes = 0;
364 int download_sources_used = 0;
365 for (int i = 0; i < kNumDownloadSources + 1; i++) {
366 DownloadSource source = static_cast<DownloadSource>(i);
367
368 // Only consider this download source (and send byte counts) as
369 // having been used if we downloaded a non-trivial amount of bytes
Alex Vakulenko072359c2014-07-18 11:41:07 -0700370 // (e.g. at least 1 MiB) that contributed to the
David Zeuthen33bae492014-02-25 16:16:18 -0800371 // update. Otherwise we're going to end up with a lot of zero-byte
372 // events in the histogram.
373
Tianjie Xu98333a82017-09-22 21:29:29 -0700374 metric = metrics::kMetricSuccessfulUpdateBytesDownloadedMiB;
David Zeuthen33bae492014-02-25 16:16:18 -0800375 if (i < kNumDownloadSources) {
376 metric += utils::ToString(source);
377 mbs = num_bytes_downloaded[i] / kNumBytesInOneMiB;
378 total_bytes += num_bytes_downloaded[i];
379 if (mbs > 0)
380 download_sources_used |= (1 << i);
381 } else {
382 mbs = total_bytes / kNumBytesInOneMiB;
383 }
384
385 if (mbs > 0) {
Tianjie Xu98333a82017-09-22 21:29:29 -0700386 metrics_lib_->SendToUMA(metric,
387 mbs,
388 0, // min: 0 MiB
389 1024, // max: 1024 MiB = 1 GiB
390 50); // num_buckets
David Zeuthen33bae492014-02-25 16:16:18 -0800391 }
392 }
393
Tianjie Xu98333a82017-09-22 21:29:29 -0700394 metric = metrics::kMetricSuccessfulUpdateDownloadSourcesUsed;
Tianjie Xu98333a82017-09-22 21:29:29 -0700395 metrics_lib_->SendToUMA(metric,
396 download_sources_used,
397 0, // min
398 (1 << kNumDownloadSources) - 1, // max
399 1 << kNumDownloadSources); // num_buckets
David Zeuthen33bae492014-02-25 16:16:18 -0800400
Tianjie Xu98333a82017-09-22 21:29:29 -0700401 metric = metrics::kMetricSuccessfulUpdateDownloadOverheadPercentage;
Tianjie Xu98333a82017-09-22 21:29:29 -0700402 metrics_lib_->SendToUMA(metric,
403 download_overhead_percentage,
404 0, // min: 0% overhead
405 1000, // max: 1000% overhead
406 50); // num_buckets
David Zeuthen33bae492014-02-25 16:16:18 -0800407
Tianjie Xu98333a82017-09-22 21:29:29 -0700408 metric = metrics::kMetricSuccessfulUpdateUrlSwitchCount;
Tianjie Xu98333a82017-09-22 21:29:29 -0700409 metrics_lib_->SendToUMA(metric,
410 url_switch_count,
411 0, // min: 0 URL switches
412 49, // max: 49 URL switches
413 50); // num_buckets
David Zeuthen33bae492014-02-25 16:16:18 -0800414
Tianjie Xu98333a82017-09-22 21:29:29 -0700415 metric = metrics::kMetricSuccessfulUpdateTotalDurationMinutes;
Tianjie Xu98333a82017-09-22 21:29:29 -0700416 metrics_lib_->SendToUMA(metric,
417 static_cast<int>(total_duration.InMinutes()),
418 0, // min: 0 min
419 365 * 24 * 60, // max: 365 days ~= 1 year
420 50); // num_buckets
David Zeuthen33bae492014-02-25 16:16:18 -0800421
Sen Jiang8712e962018-05-08 12:12:28 -0700422 metric = metrics::kMetricSuccessfulUpdateTotalDurationUptimeMinutes;
Sen Jiang8712e962018-05-08 12:12:28 -0700423 metrics_lib_->SendToUMA(metric,
424 static_cast<int>(total_duration_uptime.InMinutes()),
425 0, // min: 0 min
426 30 * 24 * 60, // max: 30 days
427 50); // num_buckets
428
Tianjie Xu98333a82017-09-22 21:29:29 -0700429 metric = metrics::kMetricSuccessfulUpdateRebootCount;
Tianjie Xu98333a82017-09-22 21:29:29 -0700430 metrics_lib_->SendToUMA(metric,
431 reboot_count,
432 0, // min: 0 reboots
433 49, // max: 49 reboots
434 50); // num_buckets
David Zeuthen33bae492014-02-25 16:16:18 -0800435
Tianjie Xu98333a82017-09-22 21:29:29 -0700436 metric = metrics::kMetricSuccessfulUpdatePayloadType;
437 metrics_lib_->SendEnumToUMA(metric, payload_type, kNumPayloadTypes);
David Zeuthen33bae492014-02-25 16:16:18 -0800438
Tianjie Xu98333a82017-09-22 21:29:29 -0700439 metric = metrics::kMetricSuccessfulUpdateAttemptCount;
440 metrics_lib_->SendToUMA(metric,
441 attempt_count,
442 1, // min: 1 attempt
443 50, // max: 50 attempts
444 50); // num_buckets
David Zeuthen33bae492014-02-25 16:16:18 -0800445
Tianjie Xu98333a82017-09-22 21:29:29 -0700446 metric = metrics::kMetricSuccessfulUpdateUpdatesAbandonedCount;
Tianjie Xu98333a82017-09-22 21:29:29 -0700447 metrics_lib_->SendToUMA(metric,
448 updates_abandoned_count,
449 0, // min: 0 counts
450 49, // max: 49 counts
451 50); // num_buckets
David Zeuthen33bae492014-02-25 16:16:18 -0800452}
453
Tianjie Xu282aa1f2017-09-05 13:42:45 -0700454void MetricsReporterOmaha::ReportRollbackMetrics(
455 metrics::RollbackResult result) {
Tianjie Xu98333a82017-09-22 21:29:29 -0700456 string metric = metrics::kMetricRollbackResult;
Tianjie Xu282aa1f2017-09-05 13:42:45 -0700457 int value = static_cast<int>(result);
Tianjie Xu98333a82017-09-22 21:29:29 -0700458 metrics_lib_->SendEnumToUMA(
Tianjie Xu282aa1f2017-09-05 13:42:45 -0700459 metric, value, static_cast<int>(metrics::RollbackResult::kNumConstants));
David Zeuthen96197df2014-04-16 12:22:39 -0700460}
461
Marton Hunyadya0302682018-05-16 18:52:13 +0200462void MetricsReporterOmaha::ReportEnterpriseRollbackMetrics(
463 bool success, const string& rollback_version) {
464 int value = utils::VersionPrefix(rollback_version);
465 string metric = metrics::kMetricEnterpriseRollbackSuccess;
466 if (!success)
467 metric = metrics::kMetricEnterpriseRollbackFailure;
Marton Hunyadya0302682018-05-16 18:52:13 +0200468 metrics_lib_->SendSparseToUMA(metric, value);
469}
470
Tianjie Xu282aa1f2017-09-05 13:42:45 -0700471void MetricsReporterOmaha::ReportCertificateCheckMetrics(
472 ServerToCheck server_to_check, CertificateCheckResult result) {
Alex Deymoc1c17b42015-11-23 03:53:15 -0300473 string metric;
474 switch (server_to_check) {
475 case ServerToCheck::kUpdate:
Tianjie Xu98333a82017-09-22 21:29:29 -0700476 metric = metrics::kMetricCertificateCheckUpdateCheck;
Alex Deymoc1c17b42015-11-23 03:53:15 -0300477 break;
478 case ServerToCheck::kDownload:
Tianjie Xu98333a82017-09-22 21:29:29 -0700479 metric = metrics::kMetricCertificateCheckDownload;
Alex Deymoc1c17b42015-11-23 03:53:15 -0300480 break;
Alex Deymo33e91e72015-12-01 18:26:08 -0300481 case ServerToCheck::kNone:
482 return;
Alex Deymoc1c17b42015-11-23 03:53:15 -0300483 }
Tianjie Xu98333a82017-09-22 21:29:29 -0700484 metrics_lib_->SendEnumToUMA(
Tianjie Xu282aa1f2017-09-05 13:42:45 -0700485 metric,
486 static_cast<int>(result),
Alex Deymoc1c17b42015-11-23 03:53:15 -0300487 static_cast<int>(CertificateCheckResult::kNumConstants));
488}
489
Tianjie Xu282aa1f2017-09-05 13:42:45 -0700490void MetricsReporterOmaha::ReportFailedUpdateCount(int target_attempt) {
Tianjie Xu98333a82017-09-22 21:29:29 -0700491 string metric = metrics::kMetricFailedUpdateCount;
492 metrics_lib_->SendToUMA(metric,
493 target_attempt,
494 1, // min value
495 50, // max value
496 kNumDefaultUmaBuckets);
Tianjie Xu282aa1f2017-09-05 13:42:45 -0700497}
498
499void MetricsReporterOmaha::ReportTimeToReboot(int time_to_reboot_minutes) {
Tianjie Xu98333a82017-09-22 21:29:29 -0700500 string metric = metrics::kMetricTimeToRebootMinutes;
501 metrics_lib_->SendToUMA(metric,
502 time_to_reboot_minutes,
503 0, // min: 0 minute
504 30 * 24 * 60, // max: 1 month (approx)
505 kNumDefaultUmaBuckets);
Tianjie Xu282aa1f2017-09-05 13:42:45 -0700506}
507
508void MetricsReporterOmaha::ReportInstallDateProvisioningSource(int source,
509 int max) {
Tianjie Xu98333a82017-09-22 21:29:29 -0700510 metrics_lib_->SendEnumToUMA(metrics::kMetricInstallDateProvisioningSource,
511 source, // Sample.
512 max);
Tianjie Xu282aa1f2017-09-05 13:42:45 -0700513}
David Zeuthen33bae492014-02-25 16:16:18 -0800514
Amin Hassani80f4d4c2018-05-16 13:34:00 -0700515void MetricsReporterOmaha::ReportInternalErrorCode(ErrorCode error_code) {
516 auto metric = metrics::kMetricAttemptInternalErrorCode;
Amin Hassani80f4d4c2018-05-16 13:34:00 -0700517 metrics_lib_->SendEnumToUMA(metric,
518 static_cast<int>(error_code),
519 static_cast<int>(ErrorCode::kUmaReportedMax));
520}
521
Marton Hunyadyffbfdfb2018-05-30 13:03:29 +0200522void MetricsReporterOmaha::ReportKeyVersionMetrics(
523 int kernel_min_version,
524 int kernel_max_rollforward_version,
525 bool kernel_max_rollforward_success) {
526 int value = kernel_min_version;
527 string metric = metrics::kMetricKernelMinVersion;
Marton Hunyadyffbfdfb2018-05-30 13:03:29 +0200528 metrics_lib_->SendSparseToUMA(metric, value);
529
530 value = kernel_max_rollforward_version;
531 metric = metrics::kMetricKernelMaxRollforwardVersion;
Marton Hunyadyffbfdfb2018-05-30 13:03:29 +0200532 metrics_lib_->SendSparseToUMA(metric, value);
533
534 bool bool_value = kernel_max_rollforward_success;
535 metric = metrics::kMetricKernelMaxRollforwardSetSuccess;
Marton Hunyadyffbfdfb2018-05-30 13:03:29 +0200536 metrics_lib_->SendBoolToUMA(metric, bool_value);
537}
538
May Lippert60aa3ca2018-08-15 16:55:29 -0700539void MetricsReporterOmaha::ReportEnterpriseUpdateSeenToDownloadDays(
540 bool has_time_restriction_policy, int time_to_update_days) {
541 string metric =
542 has_time_restriction_policy
543 ? metrics::kMetricSuccessfulUpdateDurationFromSeenTimeRestrictedDays
544 : metrics::kMetricSuccessfulUpdateDurationFromSeenDays;
May Lippert60aa3ca2018-08-15 16:55:29 -0700545
546 metrics_lib_->SendToUMA(metric,
547 time_to_update_days,
548 1, // min: 1 days
549 6 * 30, // max: 6 months (approx)
550 50); // num_buckets
551}
552
Amin Hassaniec7bc112020-10-29 16:47:58 -0700553bool MetricsReporterOmaha::WallclockDurationHelper(
Amin Hassaniec7bc112020-10-29 16:47:58 -0700554 const std::string& state_variable_key,
555 TimeDelta* out_duration) {
556 bool ret = false;
Amin Hassani538bd592020-11-04 20:46:08 -0800557 Time now = SystemState::Get()->clock()->GetWallclockTime();
Amin Hassaniec7bc112020-10-29 16:47:58 -0700558 int64_t stored_value;
Amin Hassani538bd592020-11-04 20:46:08 -0800559 if (SystemState::Get()->prefs()->GetInt64(state_variable_key,
560 &stored_value)) {
Amin Hassaniec7bc112020-10-29 16:47:58 -0700561 Time stored_time = Time::FromInternalValue(stored_value);
562 if (stored_time > now) {
563 LOG(ERROR) << "Stored time-stamp used for " << state_variable_key
564 << " is in the future.";
565 } else {
566 *out_duration = now - stored_time;
567 ret = true;
568 }
569 }
570
Amin Hassani538bd592020-11-04 20:46:08 -0800571 if (!SystemState::Get()->prefs()->SetInt64(state_variable_key,
572 now.ToInternalValue())) {
Amin Hassaniec7bc112020-10-29 16:47:58 -0700573 LOG(ERROR) << "Error storing time-stamp in " << state_variable_key;
574 }
575
576 return ret;
577}
578
Amin Hassani538bd592020-11-04 20:46:08 -0800579bool MetricsReporterOmaha::MonotonicDurationHelper(int64_t* storage,
Amin Hassaniec7bc112020-10-29 16:47:58 -0700580 TimeDelta* out_duration) {
581 bool ret = false;
Amin Hassani538bd592020-11-04 20:46:08 -0800582 Time now = SystemState::Get()->clock()->GetMonotonicTime();
Amin Hassaniec7bc112020-10-29 16:47:58 -0700583 if (*storage != 0) {
584 Time stored_time = Time::FromInternalValue(*storage);
585 *out_duration = now - stored_time;
586 ret = true;
587 }
588 *storage = now.ToInternalValue();
589
590 return ret;
591}
592
David Zeuthen33bae492014-02-25 16:16:18 -0800593} // namespace chromeos_update_engine