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_
|