1 // Copyright 2014 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef COMPONENTS_METRICS_PERSISTED_LOGS_H_ 6 #define COMPONENTS_METRICS_PERSISTED_LOGS_H_ 7 8 #include <string> 9 #include <vector> 10 11 #include "base/basictypes.h" 12 #include "base/logging.h" 13 #include "base/values.h" 14 15 class PrefService; 16 17 namespace metrics { 18 19 // Maintains a list of unsent logs that are written and restored from disk. 20 class PersistedLogs { 21 public: 22 // Used to produce a histogram that keeps track of the status of recalling 23 // persisted per logs. 24 enum LogReadStatus { 25 RECALL_SUCCESS, // We were able to correctly recall a persisted log. 26 LIST_EMPTY, // Attempting to recall from an empty list. 27 LIST_SIZE_MISSING, // Failed to recover list size using GetAsInteger(). 28 LIST_SIZE_TOO_SMALL, // Too few elements in the list (less than 3). 29 LIST_SIZE_CORRUPTION, // List size is not as expected. 30 LOG_STRING_CORRUPTION, // Failed to recover log string using GetAsString(). 31 CHECKSUM_CORRUPTION, // Failed to verify checksum. 32 CHECKSUM_STRING_CORRUPTION, // Failed to recover checksum string using 33 // GetAsString(). 34 DECODE_FAIL, // Failed to decode log. 35 DEPRECATED_XML_PROTO_MISMATCH, // The XML and protobuf logs have 36 // inconsistent data. 37 END_RECALL_STATUS // Number of bins to use to create the histogram. 38 }; 39 40 // Constructs a PersistedLogs that stores data in |local_state| under the 41 // preference |pref_name|. 42 // Calling code is responsible for ensuring that the lifetime of |local_state| 43 // is longer than the lifetime of PersistedLogs. 44 // 45 // When saving logs to disk, stores either the first |min_log_count| logs, or 46 // at least |min_log_bytes| bytes of logs, whichever is greater. 47 // 48 // If the optional |max_log_size| parameter is non-zero, all logs larger than 49 // that limit will be skipped when writing to disk. 50 PersistedLogs(PrefService* local_state, 51 const char* pref_name, 52 size_t min_log_count, 53 size_t min_log_bytes, 54 size_t max_log_size); 55 ~PersistedLogs(); 56 57 // Write list to storage. 58 void SerializeLogs() const; 59 60 // Reads the list from the preference. 61 LogReadStatus DeserializeLogs(); 62 63 // Adds a log to the list. 64 void StoreLog(const std::string& log_data); 65 66 // Stages the most recent log. The staged_log will remain the same even if 67 // additional logs are added. 68 void StageLog(); 69 70 // Remove the staged log. 71 void DiscardStagedLog(); 72 73 // True if a log has been staged. 74 bool has_staged_log() const { return staged_log_index_ != -1; } 75 76 // Returns the element in the front of the list. 77 const std::string& staged_log() const { 78 DCHECK(has_staged_log()); 79 return list_[staged_log_index_].compressed_log_data; 80 } 81 82 // Returns the element in the front of the list. 83 const std::string& staged_log_hash() const { 84 DCHECK(has_staged_log()); 85 return list_[staged_log_index_].hash; 86 } 87 88 // The number of elements currently stored. 89 size_t size() const { return list_.size(); } 90 91 // True if there are no stored logs. 92 bool empty() const { return list_.empty(); } 93 94 private: 95 // Writes the list to the ListValue. 96 void WriteLogsToPrefList(base::ListValue* list) const; 97 98 // Reads the list from the ListValue. 99 LogReadStatus ReadLogsFromPrefList(const base::ListValue& list); 100 101 // A weak pointer to the PrefService object to read and write the preference 102 // from. Calling code should ensure this object continues to exist for the 103 // lifetime of the PersistedLogs object. 104 PrefService* local_state_; 105 106 // The name of the preference to serialize logs to/from. 107 const char* pref_name_; 108 109 // We will keep at least this |min_log_count_| logs or |min_log_bytes_| bytes 110 // of logs, whichever is greater, when writing to disk. These apply after 111 // skipping logs greater than |max_log_size_|. 112 const size_t min_log_count_; 113 const size_t min_log_bytes_; 114 115 // Logs greater than this size will not be written to disk. 116 const size_t max_log_size_; 117 118 struct LogHashPair { 119 // Initializes the members based on uncompressed |log_data|. 120 void Init(const std::string& log_data); 121 122 // Compressed log data - a serialized protobuf that's been gzipped. 123 std::string compressed_log_data; 124 125 // The SHA1 hash of log, stored to catch errors from memory corruption. 126 std::string hash; 127 }; 128 // A list of all of the stored logs, stored with SHA1 hashes to check for 129 // corruption while they are stored in memory. 130 std::vector<LogHashPair> list_; 131 132 // The index and type of the log staged for upload. If nothing has been 133 // staged, the index will be -1. 134 int staged_log_index_; 135 136 DISALLOW_COPY_AND_ASSIGN(PersistedLogs); 137 }; 138 139 } // namespace metrics 140 141 #endif // COMPONENTS_METRICS_PERSISTED_LOGS_H_ 142