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
|
// Copyright 2014 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.
#ifndef COMPONENTS_METRICS_PERSISTED_LOGS_H_
#define COMPONENTS_METRICS_PERSISTED_LOGS_H_
#include <stddef.h>
#include <memory>
#include <string>
#include <vector>
#include "base/logging.h"
#include "base/macros.h"
#include "base/values.h"
class PrefService;
namespace metrics {
class PersistedLogsMetrics;
// Maintains a list of unsent logs that are written and restored from disk.
class PersistedLogs {
public:
// Used to produce a histogram that keeps track of the status of recalling
// persisted per logs.
enum LogReadStatus {
RECALL_SUCCESS, // We were able to correctly recall a persisted log.
LIST_EMPTY, // Attempting to recall from an empty list.
LIST_SIZE_MISSING, // Failed to recover list size using GetAsInteger().
LIST_SIZE_TOO_SMALL, // Too few elements in the list (less than 3).
LIST_SIZE_CORRUPTION, // List size is not as expected.
LOG_STRING_CORRUPTION, // Failed to recover log string using GetAsString().
CHECKSUM_CORRUPTION, // Failed to verify checksum.
CHECKSUM_STRING_CORRUPTION, // Failed to recover checksum string using
// GetAsString().
DECODE_FAIL, // Failed to decode log.
DEPRECATED_XML_PROTO_MISMATCH, // The XML and protobuf logs have
// inconsistent data.
END_RECALL_STATUS // Number of bins to use to create the histogram.
};
// Constructs a PersistedLogs that stores data in |local_state| under the
// preference |pref_name|.
// Calling code is responsible for ensuring that the lifetime of |local_state|
// is longer than the lifetime of PersistedLogs.
//
// When saving logs to disk, stores either the first |min_log_count| logs, or
// at least |min_log_bytes| bytes of logs, whichever is greater.
//
// If the optional |max_log_size| parameter is non-zero, all logs larger than
// that limit will be skipped when writing to disk.
PersistedLogs(std::unique_ptr<PersistedLogsMetrics> metrics,
PrefService* local_state,
const char* pref_name,
size_t min_log_count,
size_t min_log_bytes,
size_t max_log_size);
~PersistedLogs();
// Write list to storage.
void SerializeLogs() const;
// Reads the list from the preference.
LogReadStatus DeserializeLogs();
// Adds a log to the list.
void StoreLog(const std::string& log_data);
// Stages the most recent log. The staged_log will remain the same even if
// additional logs are added.
void StageLog();
// Remove the staged log.
void DiscardStagedLog();
// True if a log has been staged.
bool has_staged_log() const { return staged_log_index_ != -1; }
// Returns the element in the front of the list.
const std::string& staged_log() const {
DCHECK(has_staged_log());
return list_[staged_log_index_].compressed_log_data;
}
// Returns the element in the front of the list.
const std::string& staged_log_hash() const {
DCHECK(has_staged_log());
return list_[staged_log_index_].hash;
}
// Returns the timestamp of the element in the front of the list.
const std::string& staged_log_timestamp() const {
DCHECK(has_staged_log());
return list_[staged_log_index_].timestamp;
}
// The number of elements currently stored.
size_t size() const { return list_.size(); }
// True if there are no stored logs.
bool empty() const { return list_.empty(); }
private:
// Writes the list to the ListValue.
void WriteLogsToPrefList(base::ListValue* list) const;
// Reads the list from the ListValue.
LogReadStatus ReadLogsFromPrefList(const base::ListValue& list);
// An object for recording UMA metrics.
std::unique_ptr<PersistedLogsMetrics> metrics_;
// A weak pointer to the PrefService object to read and write the preference
// from. Calling code should ensure this object continues to exist for the
// lifetime of the PersistedLogs object.
PrefService* local_state_;
// The name of the preference to serialize logs to/from.
const char* pref_name_;
// We will keep at least this |min_log_count_| logs or |min_log_bytes_| bytes
// of logs, whichever is greater, when writing to disk. These apply after
// skipping logs greater than |max_log_size_|.
const size_t min_log_count_;
const size_t min_log_bytes_;
// Logs greater than this size will not be written to disk.
const size_t max_log_size_;
struct LogInfo {
// Initializes the members based on uncompressed |log_data| and
// |log_timestamp|.
// |metrics| is the parent's metrics_ object, and should not be held.
void Init(PersistedLogsMetrics* metrics,
const std::string& log_data,
const std::string& log_timestamp);
// Compressed log data - a serialized protobuf that's been gzipped.
std::string compressed_log_data;
// The SHA1 hash of log, stored to catch errors from memory corruption.
std::string hash;
// The timestamp of when the log was created as a time_t value.
std::string timestamp;
};
// A list of all of the stored logs, stored with SHA1 hashes to check for
// corruption while they are stored in memory.
std::vector<LogInfo> list_;
// The index and type of the log staged for upload. If nothing has been
// staged, the index will be -1.
int staged_log_index_;
DISALLOW_COPY_AND_ASSIGN(PersistedLogs);
};
} // namespace metrics
#endif // COMPONENTS_METRICS_PERSISTED_LOGS_H_
|