• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.
has_staged_log()74   bool has_staged_log() const { return staged_log_index_ != -1; }
75 
76   // Returns the element in the front of the list.
staged_log()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.
staged_log_hash()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.
size()89   size_t size() const { return list_.size(); }
90 
91   // True if there are no stored logs.
empty()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