blob: a4d0a1e9f375b42fd790323ff01fa19b5a206bc7 [file] [log] [blame]
Bertrand SIMONNET52e5b992015-08-10 15:18:00 -07001/*
2 * Copyright (C) 2015 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 */
Bertrand SIMONNET46b49da2014-06-25 14:38:07 -070016
17#ifndef METRICS_UPLOADER_UPLOAD_SERVICE_H_
18#define METRICS_UPLOADER_UPLOAD_SERVICE_H_
19
20#include <string>
21
22#include "base/metrics/histogram_base.h"
23#include "base/metrics/histogram_flattener.h"
24#include "base/metrics/histogram_snapshot_manager.h"
Bertrand SIMONNETe4fa61e2015-02-18 09:38:55 -080025
26#include "metrics/metrics_library.h"
Bertrand SIMONNET1df10c42015-09-09 10:39:51 -070027#include "persistent_integer.h"
Bertrand SIMONNET4b915ae2015-07-28 15:38:14 -070028#include "uploader/metrics_log.h"
29#include "uploader/sender.h"
30#include "uploader/system_profile_cache.h"
Bertrand SIMONNET46b49da2014-06-25 14:38:07 -070031
32namespace metrics {
33class ChromeUserMetricsExtension;
34class CrashSample;
35class HistogramSample;
36class LinearHistogramSample;
37class MetricSample;
38class SparseHistogramSample;
39class UserActionSample;
40}
41
42class SystemProfileSetter;
43
44// Service responsible for uploading the metrics periodically to the server.
45// This service works as a simple 2-state state-machine.
46//
47// The two states are the presence or not of a staged log.
48// A staged log is a compressed protobuffer containing both the aggregated
49// metrics and event and information about the client. (product, hardware id,
50// etc...).
51//
52// At regular intervals, the upload event will be triggered and the following
53// will happen:
54// * if a staged log is present:
55// The previous upload may have failed for various reason. We then retry to
56// upload the same log.
57// - if the upload is successful, we discard the log (therefore
58// transitioning back to no staged log)
59// - if the upload fails, we keep the log to try again later.
60// We do not try to read the metrics that are stored on
61// the disk as we want to avoid storing the metrics in memory.
62//
63// * if no staged logs are present:
64// Read all metrics from the disk, aggregate them and try to send them.
65// - if the upload succeeds, we discard the staged log (transitioning back
66// to the no staged log state)
67// - if the upload fails, we keep the staged log in memory to retry
68// uploading later.
69//
70class UploadService : public base::HistogramFlattener {
71 public:
Bertrand SIMONNET71a62ef2014-10-07 11:26:25 -070072 explicit UploadService(SystemProfileSetter* setter,
Bertrand SIMONNETe4fa61e2015-02-18 09:38:55 -080073 MetricsLibraryInterface* metrics_lib,
Bertrand SIMONNET71a62ef2014-10-07 11:26:25 -070074 const std::string& server);
Bertrand SIMONNET46b49da2014-06-25 14:38:07 -070075
Bertrand SIMONNETcac74e12014-10-09 10:14:13 -070076 void Init(const base::TimeDelta& upload_interval,
Bertrand SIMONNET2765d0a2015-09-09 10:38:20 -070077 const base::FilePath& metrics_directory);
Bertrand SIMONNET46b49da2014-06-25 14:38:07 -070078
79 // Starts a new log. The log needs to be regenerated after each successful
80 // launch as it is destroyed when staging the log.
81 void StartNewLog();
82
Steve Fungae4bdc42015-01-26 17:13:24 -080083 // Event callback for handling MessageLoop events.
84 void UploadEventCallback(const base::TimeDelta& interval);
Bertrand SIMONNET46b49da2014-06-25 14:38:07 -070085
86 // Triggers an upload event.
87 void UploadEvent();
88
89 // Sends the staged log.
90 void SendStagedLog();
91
92 // Implements inconsistency detection to match HistogramFlattener's
93 // interface.
94 void InconsistencyDetected(
Alex Vakulenkoe8a8e302014-08-14 12:56:21 -070095 base::HistogramBase::Inconsistency problem) override {}
Bertrand SIMONNET46b49da2014-06-25 14:38:07 -070096 void UniqueInconsistencyDetected(
Alex Vakulenkoe8a8e302014-08-14 12:56:21 -070097 base::HistogramBase::Inconsistency problem) override {}
98 void InconsistencyDetectedInLoggedCount(int amount) override {}
Bertrand SIMONNET46b49da2014-06-25 14:38:07 -070099
100 private:
101 friend class UploadServiceTest;
102
103 FRIEND_TEST(UploadServiceTest, CanSendMultipleTimes);
104 FRIEND_TEST(UploadServiceTest, DiscardLogsAfterTooManyFailedUpload);
105 FRIEND_TEST(UploadServiceTest, EmptyLogsAreNotSent);
106 FRIEND_TEST(UploadServiceTest, FailedSendAreRetried);
107 FRIEND_TEST(UploadServiceTest, LogContainsAggregatedValues);
108 FRIEND_TEST(UploadServiceTest, LogEmptyAfterUpload);
109 FRIEND_TEST(UploadServiceTest, LogEmptyByDefault);
Bertrand SIMONNET4c8a8ad2015-09-09 13:27:33 -0700110 FRIEND_TEST(UploadServiceTest, LogFromTheMetricsLibrary);
Bertrand SIMONNET46b49da2014-06-25 14:38:07 -0700111 FRIEND_TEST(UploadServiceTest, LogKernelCrash);
112 FRIEND_TEST(UploadServiceTest, LogUncleanShutdown);
113 FRIEND_TEST(UploadServiceTest, LogUserCrash);
114 FRIEND_TEST(UploadServiceTest, UnknownCrashIgnored);
115 FRIEND_TEST(UploadServiceTest, ValuesInConfigFileAreSent);
116
Steve Fungae4bdc42015-01-26 17:13:24 -0800117 // Private constructor for use in unit testing.
118 UploadService(SystemProfileSetter* setter,
Bertrand SIMONNETe4fa61e2015-02-18 09:38:55 -0800119 MetricsLibraryInterface* metrics_lib,
Steve Fungae4bdc42015-01-26 17:13:24 -0800120 const std::string& server,
121 bool testing);
122
Bertrand SIMONNET46b49da2014-06-25 14:38:07 -0700123 // If a staged log fails to upload more than kMaxFailedUpload times, it
124 // will be discarded.
125 static const int kMaxFailedUpload;
126
127 // Resets the internal state.
128 void Reset();
129
130 // Reads all the metrics from the disk.
131 void ReadMetrics();
132
133 // Adds a generic sample to the current log.
134 void AddSample(const metrics::MetricSample& sample);
135
136 // Adds a crash to the current log.
137 void AddCrash(const std::string& crash_name);
138
139 // Aggregates all histogram available in memory and store them in the current
140 // log.
141 void GatherHistograms();
142
143 // Callback for HistogramSnapshotManager to store the histograms.
144 void RecordDelta(const base::HistogramBase& histogram,
Alex Vakulenkoe8a8e302014-08-14 12:56:21 -0700145 const base::HistogramSamples& snapshot) override;
Bertrand SIMONNET46b49da2014-06-25 14:38:07 -0700146
147 // Compiles all the samples received into a single protobuf and adds all
148 // system information.
149 void StageCurrentLog();
150
Bertrand SIMONNET1df10c42015-09-09 10:39:51 -0700151 // Returns true iff a log is staged.
152 bool HasStagedLog();
153
154 // Remove the staged log iff the upload failed more than |kMaxFailedUpload|.
155 void RemoveFailedLog();
156
Bertrand SIMONNET46b49da2014-06-25 14:38:07 -0700157 // Returns the current log. If there is no current log, creates it first.
158 MetricsLog* GetOrCreateCurrentLog();
159
Yunlian Jiange2c2d892014-09-02 10:40:19 -0700160 scoped_ptr<SystemProfileSetter> system_profile_setter_;
Bertrand SIMONNETe4fa61e2015-02-18 09:38:55 -0800161 MetricsLibraryInterface* metrics_lib_;
Bertrand SIMONNET46b49da2014-06-25 14:38:07 -0700162 base::HistogramSnapshotManager histogram_snapshot_manager_;
Yunlian Jiangb1640ee2014-08-27 16:22:19 -0700163 scoped_ptr<Sender> sender_;
Bertrand SIMONNET1df10c42015-09-09 10:39:51 -0700164 chromeos_metrics::PersistentInteger failed_upload_count_;
Bertrand SIMONNET46b49da2014-06-25 14:38:07 -0700165 scoped_ptr<MetricsLog> current_log_;
Steve Fung67906c62014-10-06 15:15:30 -0700166
Bertrand SIMONNET2765d0a2015-09-09 10:38:20 -0700167 base::FilePath metrics_file_;
Bertrand SIMONNET1df10c42015-09-09 10:39:51 -0700168 base::FilePath staged_log_path_;
Steve Fungae4bdc42015-01-26 17:13:24 -0800169
170 bool testing_;
Bertrand SIMONNET46b49da2014-06-25 14:38:07 -0700171};
172
173#endif // METRICS_UPLOADER_UPLOAD_SERVICE_H_