File: upload_service.h

package info (click to toggle)
android-platform-system-core 1%3A7.0.0%2Br33-1
  • links: PTS, VCS
  • area: main
  • in suites: stretch
  • size: 10,464 kB
  • sloc: cpp: 96,742; ansic: 39,563; asm: 3,482; python: 1,571; sh: 666; lex: 311; java: 169; makefile: 65; xml: 19
file content (183 lines) | stat: -rw-r--r-- 6,642 bytes parent folder | download
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
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
/*
 * Copyright (C) 2015 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef METRICS_UPLOADER_UPLOAD_SERVICE_H_
#define METRICS_UPLOADER_UPLOAD_SERVICE_H_

#include <memory>
#include <string>

#include <base/metrics/histogram_base.h>
#include <base/metrics/histogram_flattener.h>
#include <base/metrics/histogram_snapshot_manager.h>
#include <brillo/daemons/daemon.h>

#include "persistent_integer.h"
#include "uploader/crash_counters.h"
#include "uploader/metrics_log.h"
#include "uploader/metricsd_service_runner.h"
#include "uploader/proto/chrome_user_metrics_extension.pb.h"
#include "uploader/sender.h"
#include "uploader/system_profile_cache.h"

class SystemProfileSetter;

// Service responsible for backing up the currently aggregated metrics to disk
// and uploading them periodically to the server.
//
// A given metrics sample can be in one of three locations.
// * in-memory metrics: in memory aggregated metrics, waiting to be staged for
//   upload.
// * saved log: protobuf message, written to disk periodically and on shutdown
//   to make a backup of metrics data for uploading later.
// * staged log: protobuf message waiting to be uploaded.
//
// The service works as follows:
// On startup, we create the in-memory metrics from the saved log if it exists.
//
// Periodically (every |disk_persistence_interval_| seconds), we take a snapshot
// of the in-memory metrics and save them to disk.
//
// Periodically (every |upload_interval| seconds), we:
// * take a snapshot of the in-memory metrics and create the staged log
// * save the staged log to disk to avoid losing it if metricsd or the system
//   crashes between two uploads.
// * delete the last saved log: all the metrics contained in it are also in the
//   newly created staged log.
//
// On shutdown (SIGINT or SIGTERM), we save the in-memory metrics to disk.
//
// Note: the in-memory metrics can be stored in |current_log_| or
// base::StatisticsRecorder.
class UploadService : public base::HistogramFlattener, public brillo::Daemon {
 public:
  UploadService(const std::string& server,
                const base::TimeDelta& upload_interval,
                const base::TimeDelta& disk_persistence_interval,
                const base::FilePath& private_metrics_directory,
                const base::FilePath& shared_metrics_directory);

  // Initializes the upload service.
  int OnInit() override;

  // Cleans up the internal state before exiting.
  void OnShutdown(int* exit_code) override;

  // Starts a new log. The log needs to be regenerated after each successful
  // launch as it is destroyed when staging the log.
  void StartNewLog();

  // Saves the current metrics to a file.
  void PersistToDisk();

  // Triggers an upload event.
  void UploadEvent();

  // Sends the staged log.
  void SendStagedLog();

  // Implements inconsistency detection to match HistogramFlattener's
  // interface.
  void InconsistencyDetected(
      base::HistogramBase::Inconsistency problem) override {}
  void UniqueInconsistencyDetected(
      base::HistogramBase::Inconsistency problem) override {}
  void InconsistencyDetectedInLoggedCount(int amount) override {}

 private:
  friend class UploadServiceTest;

  FRIEND_TEST(UploadServiceTest, CanSendMultipleTimes);
  FRIEND_TEST(UploadServiceTest, CorruptedSavedLog);
  FRIEND_TEST(UploadServiceTest, CurrentLogSavedAndResumed);
  FRIEND_TEST(UploadServiceTest, DiscardLogsAfterTooManyFailedUpload);
  FRIEND_TEST(UploadServiceTest, EmptyLogsAreNotSent);
  FRIEND_TEST(UploadServiceTest, FailedSendAreRetried);
  FRIEND_TEST(UploadServiceTest, LogContainsAggregatedValues);
  FRIEND_TEST(UploadServiceTest, LogContainsCrashCounts);
  FRIEND_TEST(UploadServiceTest, LogEmptyAfterUpload);
  FRIEND_TEST(UploadServiceTest, LogEmptyByDefault);
  FRIEND_TEST(UploadServiceTest, LogFromTheMetricsLibrary);
  FRIEND_TEST(UploadServiceTest, LogKernelCrash);
  FRIEND_TEST(UploadServiceTest, LogUncleanShutdown);
  FRIEND_TEST(UploadServiceTest, LogUserCrash);
  FRIEND_TEST(UploadServiceTest, PersistEmptyLog);
  FRIEND_TEST(UploadServiceTest, UnknownCrashIgnored);
  FRIEND_TEST(UploadServiceTest, ValuesInConfigFileAreSent);

  // Initializes the upload service for testing.
  void InitForTest(SystemProfileSetter* setter);

  // If a staged log fails to upload more than kMaxFailedUpload times, it
  // will be discarded.
  static const int kMaxFailedUpload;

  // Loads the log saved to disk if it exists.
  void LoadSavedLog();

  // Resets the internal state.
  void Reset();

  // Returns true iff metrics reporting is enabled.
  bool AreMetricsEnabled();

  // Event callback for handling Upload events.
  void UploadEventCallback();

  // Event callback for handling Persist events.
  void PersistEventCallback();

  // Aggregates all histogram available in memory and store them in the current
  // log.
  void GatherHistograms();

  // Callback for HistogramSnapshotManager to store the histograms.
  void RecordDelta(const base::HistogramBase& histogram,
                   const base::HistogramSamples& snapshot) override;

  // Compiles all the samples received into a single protobuf and adds all
  // system information.
  void StageCurrentLog();

  // Returns true iff a log is staged.
  bool HasStagedLog();

  // Remove the staged log iff the upload failed more than |kMaxFailedUpload|.
  void RemoveFailedLog();

  // Returns the current log. If there is no current log, creates it first.
  MetricsLog* GetOrCreateCurrentLog();

  std::unique_ptr<SystemProfileSetter> system_profile_setter_;
  base::HistogramSnapshotManager histogram_snapshot_manager_;
  std::unique_ptr<Sender> sender_;
  chromeos_metrics::PersistentInteger failed_upload_count_;
  std::unique_ptr<MetricsLog> current_log_;
  std::shared_ptr<CrashCounters> counters_;

  base::TimeDelta upload_interval_;
  base::TimeDelta disk_persistence_interval_;

  MetricsdServiceRunner metricsd_service_runner_;

  base::FilePath consent_file_;
  base::FilePath staged_log_path_;
  base::FilePath saved_log_path_;

  bool testing_;
};

#endif  // METRICS_UPLOADER_UPLOAD_SERVICE_H_