Home | History | Annotate | Download | only in metrics
      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