Upload upstream chromium 114.0.5735.31
[platform/framework/web/chromium-efl.git] / components / ukm / ukm_reporting_service.cc
1 // Copyright 2017 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 // ReportingService specialized to report UKM metrics.
6
7 #include "components/ukm/ukm_reporting_service.h"
8
9 #include <memory>
10
11 #include "base/command_line.h"
12 #include "base/metrics/field_trial_params.h"
13 #include "base/metrics/histogram_functions.h"
14 #include "base/metrics/histogram_macros.h"
15 #include "build/build_config.h"
16 #include "components/metrics/metrics_service_client.h"
17 #include "components/metrics/metrics_switches.h"
18 #include "components/metrics/url_constants.h"
19 #include "components/prefs/pref_registry_simple.h"
20 #include "components/ukm/ukm_pref_names.h"
21 #include "components/ukm/ukm_service.h"
22 #include "components/ukm/unsent_log_store_metrics_impl.h"
23 #include "third_party/zlib/google/compression_utils.h"
24
25 #if BUILDFLAG(IS_IOS)
26 #include "components/ukm/ios/ukm_reporting_ios_util.h"
27 #endif
28
29 namespace ukm {
30
31 namespace {
32
33 // The number of UKM logs that will be stored in UnsentLogStore before logs
34 // start being dropped.
35 constexpr int kMinUnsentLogCount = 8;
36
37 // The number of bytes UKM logs that will be stored in UnsentLogStore before
38 // logs start being dropped.
39 // This ensures that a reasonable amount of history will be stored even if there
40 // is a long series of very small logs.
41 constexpr int kMinUnsentLogBytes = 300000;
42
43 // If an upload fails, and the transmission was over this byte count, then we
44 // will discard the log, and not try to retransmit it.  We also don't persist
45 // the log to the prefs for transmission during the next chrome session if this
46 // limit is exceeded.
47 constexpr size_t kMaxLogRetransmitSize = 100 * 1024;
48
49 GURL GetServerUrl() {
50 #ifndef NDEBUG
51   // Only allow overriding the server URL through the command line in debug
52   // builds. This is to prevent, for example, rerouting metrics due to malware.
53   base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
54   if (command_line->HasSwitch(metrics::switches::kUkmServerUrl)) {
55     return GURL(
56         command_line->GetSwitchValueASCII(metrics::switches::kUkmServerUrl));
57   }
58 #endif  // NDEBUG
59
60   std::string server_url =
61       base::GetFieldTrialParamValueByFeature(kUkmFeature, "ServerUrl");
62   if (!server_url.empty())
63     return GURL(server_url);
64   return GURL(metrics::kDefaultUkmServerUrl);
65 }
66
67 }  // namespace
68
69 // static
70 void UkmReportingService::RegisterPrefs(PrefRegistrySimple* registry) {
71   registry->RegisterListPref(prefs::kUkmUnsentLogStore);
72   // Base class already registered by MetricsReportingService::RegisterPrefs
73   // ReportingService::RegisterPrefs(registry);
74 }
75
76 UkmReportingService::UkmReportingService(metrics::MetricsServiceClient* client,
77                                          PrefService* local_state)
78     : ReportingService(client,
79                        local_state,
80                        kMaxLogRetransmitSize,
81                        /*logs_event_manager=*/nullptr),
82       unsent_log_store_(std::make_unique<ukm::UnsentLogStoreMetricsImpl>(),
83                         local_state,
84                         prefs::kUkmUnsentLogStore,
85                         nullptr,
86                         kMinUnsentLogCount,
87                         kMinUnsentLogBytes,
88                         kMaxLogRetransmitSize,
89                         client->GetUploadSigningKey(),
90                         /*logs_event_manager=*/nullptr) {}
91
92 UkmReportingService::~UkmReportingService() {}
93
94 metrics::LogStore* UkmReportingService::log_store() {
95   return &unsent_log_store_;
96 }
97
98 GURL UkmReportingService::GetUploadUrl() const {
99   return GetServerUrl();
100 }
101
102 GURL UkmReportingService::GetInsecureUploadUrl() const {
103   return GURL();
104 }
105
106 base::StringPiece UkmReportingService::upload_mime_type() const {
107   return metrics::kUkmMimeType;
108 }
109
110 metrics::MetricsLogUploader::MetricServiceType
111 UkmReportingService::service_type() const {
112   return metrics::MetricsLogUploader::UKM;
113 }
114
115 void UkmReportingService::LogCellularConstraint(bool upload_canceled) {
116   UMA_HISTOGRAM_BOOLEAN("UKM.LogUpload.Canceled.CellularConstraint",
117                         upload_canceled);
118 }
119
120 void UkmReportingService::LogResponseOrErrorCode(int response_code,
121                                                  int error_code,
122                                                  bool was_https) {
123   // |was_https| is ignored since all UKM logs are received over HTTPS.
124   base::UmaHistogramSparse("UKM.LogUpload.ResponseOrErrorCode",
125                            response_code >= 0 ? response_code : error_code);
126 }
127
128 void UkmReportingService::LogSuccessLogSize(size_t log_size) {
129 #if BUILDFLAG(IS_IOS)
130   IncrementUkmLogSizeOnSuccessCounter();
131 #endif
132   UMA_HISTOGRAM_COUNTS_10000("UKM.LogSize.OnSuccess", log_size / 1024);
133 }
134
135 void UkmReportingService::LogSuccessMetadata(const std::string& staged_log) {
136   // Recover the report from the compressed staged log.
137   // Note: We don't use metrics::DecodeLogDataToProto() since we to use
138   // |uncompressed_log_data| later in the function.
139   std::string uncompressed_log_data;
140   bool uncompress_successful =
141       compression::GzipUncompress(staged_log, &uncompressed_log_data);
142   DCHECK(uncompress_successful);
143   Report report;
144   report.ParseFromString(uncompressed_log_data);
145
146   // Log the relative size of the report with relevant UKM data omitted. This
147   // helps us to estimate the bandwidth usage of logs upload that is not
148   // directly attributed to UKM data, for example the system profile info.
149   // Note that serialized logs are further compressed before upload, thus the
150   // percentages here are not the exact percentage of bandwidth they ended up
151   // taking.
152   std::string log_without_ukm_data;
153   report.clear_sources();
154   report.clear_source_counts();
155   report.clear_entries();
156   report.clear_aggregates();
157   report.SerializeToString(&log_without_ukm_data);
158
159   int non_ukm_percentage =
160       log_without_ukm_data.length() * 100 / uncompressed_log_data.length();
161   DCHECK_GE(non_ukm_percentage, 0);
162   DCHECK_LE(non_ukm_percentage, 100);
163   base::UmaHistogramPercentage("UKM.ReportSize.NonUkmPercentage",
164                                non_ukm_percentage);
165 }
166
167 void UkmReportingService::LogLargeRejection(size_t log_size) {}
168
169 }  // namespace ukm