summaryrefslogtreecommitdiff
path: root/chromium/components/ukm/ukm_reporting_service.cc
blob: 25f979e91452495fee5dbb4d42d9ac874a1cea79 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
// Copyright 2017 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// ReportingService specialized to report UKM metrics.

#include "components/ukm/ukm_reporting_service.h"

#include <memory>

#include "base/metrics/field_trial_params.h"
#include "base/metrics/histogram_functions.h"
#include "base/metrics/histogram_macros.h"
#include "build/build_config.h"
#include "components/metrics/metrics_service_client.h"
#include "components/prefs/pref_registry_simple.h"
#include "components/ukm/ukm_pref_names.h"
#include "components/ukm/ukm_service.h"
#include "components/ukm/unsent_log_store_metrics_impl.h"
#include "third_party/zlib/google/compression_utils.h"

#if defined(OS_IOS)
#include "components/ukm/ios/ukm_reporting_ios_util.h"
#endif

namespace ukm {

namespace {

// The UKM server's URL.
constexpr char kMimeType[] = "application/vnd.chrome.ukm";

// The number of UKM logs that will be stored in UnsentLogStore before logs
// start being dropped.
constexpr int kMinUnsentLogCount = 8;

// The number of bytes UKM logs that will be stored in UnsentLogStore before
// logs start being dropped.
// This ensures that a reasonable amount of history will be stored even if there
// is a long series of very small logs.
constexpr int kMinUnsentLogBytes = 300000;

// If an upload fails, and the transmission was over this byte count, then we
// will discard the log, and not try to retransmit it.  We also don't persist
// the log to the prefs for transmission during the next chrome session if this
// limit is exceeded.
constexpr size_t kMaxLogRetransmitSize = 100 * 1024;

GURL GetServerUrl() {
  constexpr char kDefaultServerUrl[] = "https://clients4.google.com/ukm";
  std::string server_url =
      base::GetFieldTrialParamValueByFeature(kUkmFeature, "ServerUrl");
  if (!server_url.empty())
    return GURL(server_url);
  return GURL(kDefaultServerUrl);
}

}  // namespace

// static
void UkmReportingService::RegisterPrefs(PrefRegistrySimple* registry) {
  registry->RegisterListPref(prefs::kUkmUnsentLogStore);
  // Base class already registered by MetricsReportingService::RegisterPrefs
  // ReportingService::RegisterPrefs(registry);
}

UkmReportingService::UkmReportingService(metrics::MetricsServiceClient* client,
                                         PrefService* local_state)
    : ReportingService(client, local_state, kMaxLogRetransmitSize),
      unsent_log_store_(std::make_unique<ukm::UnsentLogStoreMetricsImpl>(),
                        local_state,
                        prefs::kUkmUnsentLogStore,
                        nullptr,
                        kMinUnsentLogCount,
                        kMinUnsentLogBytes,
                        kMaxLogRetransmitSize,
                        client->GetUploadSigningKey()) {}

UkmReportingService::~UkmReportingService() {}

metrics::LogStore* UkmReportingService::log_store() {
  return &unsent_log_store_;
}

GURL UkmReportingService::GetUploadUrl() const {
  return GetServerUrl();
}

GURL UkmReportingService::GetInsecureUploadUrl() const {
  return GURL();
}

base::StringPiece UkmReportingService::upload_mime_type() const {
  return kMimeType;
}

metrics::MetricsLogUploader::MetricServiceType
UkmReportingService::service_type() const {
  return metrics::MetricsLogUploader::UKM;
}

void UkmReportingService::LogCellularConstraint(bool upload_canceled) {
  UMA_HISTOGRAM_BOOLEAN("UKM.LogUpload.Canceled.CellularConstraint",
                        upload_canceled);
}

void UkmReportingService::LogResponseOrErrorCode(int response_code,
                                                 int error_code,
                                                 bool was_https) {
  // |was_https| is ignored since all UKM logs are received over HTTPS.
  base::UmaHistogramSparse("UKM.LogUpload.ResponseOrErrorCode",
                           response_code >= 0 ? response_code : error_code);
}

void UkmReportingService::LogSuccessLogSize(size_t log_size) {
#if defined(OS_IOS)
  IncrementUkmLogSizeOnSuccessCounter();
#endif
  UMA_HISTOGRAM_COUNTS_10000("UKM.LogSize.OnSuccess", log_size / 1024);
}

void UkmReportingService::LogSuccessMetadata(const std::string& staged_log) {
  // Recover the report from the compressed staged log.
  std::string uncompressed_log_data;
  bool uncompress_successful =
      compression::GzipUncompress(staged_log, &uncompressed_log_data);
  DCHECK(uncompress_successful);
  Report report;
  report.ParseFromString(uncompressed_log_data);

  // Log the relative size of the report with relevant UKM data omitted. This
  // helps us to estimate the bandwidth usage of logs upload that is not
  // directly attributed to UKM data, for example the system profile info.
  // Note that serialized logs are further compressed before upload, thus the
  // percentages here are not the exact percentage of bandwidth they ended up
  // taking.
  std::string log_without_ukm_data;
  report.clear_sources();
  report.clear_source_counts();
  report.clear_entries();
  report.clear_aggregates();
  report.SerializeToString(&log_without_ukm_data);

  int non_ukm_percentage =
      log_without_ukm_data.length() * 100 / uncompressed_log_data.length();
  DCHECK_GE(non_ukm_percentage, 0);
  DCHECK_LE(non_ukm_percentage, 100);
  base::UmaHistogramPercentage("UKM.ReportSize.NonUkmPercentage",
                               non_ukm_percentage);
}

void UkmReportingService::LogLargeRejection(size_t log_size) {}

}  // namespace ukm