1ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// Copyright (c) 2011 The Chromium Authors. All rights reserved.
206741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch// Use of this source code is governed by a BSD-style license that can be
306741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch// found in the LICENSE file.
406741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch
506741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch// This file defines a set of user experience metrics data recorded by
606741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch// the MetricsService.  This is the unit of data that is sent to the server.
706741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch
806741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch#ifndef CHROME_COMMON_METRICS_HELPERS_H_
906741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch#define CHROME_COMMON_METRICS_HELPERS_H_
103345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#pragma once
1106741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch
1206741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch#include <map>
1306741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch#include <string>
1406741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch
1506741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch#include "base/basictypes.h"
16ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "base/memory/scoped_ptr.h"
17731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick#include "base/metrics/histogram.h"
1806741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch#include "base/time.h"
19ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "content/common/page_transition_types.h"
2006741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch
2106741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdochclass GURL;
2206741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdochclass MetricsLog;
2306741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch
2406741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch// This class provides base functionality for logging metrics data.
2506741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdochclass MetricsLogBase {
2606741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch public:
2706741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  // Creates a new metrics log
2806741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  // client_id is the identifier for this profile on this installation
2906741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  // session_id is an integer that's incremented on each application launch
3006741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  MetricsLogBase(const std::string& client_id, int session_id,
3106741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch                 const std::string& version_string);
3206741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  virtual ~MetricsLogBase();
3306741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch
3406741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  // Records a user-initiated action.
3506741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  void RecordUserAction(const char* key);
3606741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch
3706741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  enum WindowEventType {
3806741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch    WINDOW_CREATE = 0,
3906741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch    WINDOW_OPEN,
4006741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch    WINDOW_CLOSE,
4106741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch    WINDOW_DESTROY
4206741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  };
4306741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch
4406741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  void RecordWindowEvent(WindowEventType type, int window_id, int parent_id);
4506741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch
4606741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  // Records a page load.
4706741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  // window_id - the index of the tab in which the load took place
4806741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  // url - which URL was loaded
4906741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  // origin - what kind of action initiated the load
5006741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  // load_time - how long it took to load the page
5106741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  void RecordLoadEvent(int window_id,
5206741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch                       const GURL& url,
5306741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch                       PageTransition::Type origin,
5406741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch                       int session_index,
5506741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch                       base::TimeDelta load_time);
5606741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch
5706741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  // Record any changes in a given histogram for transmission.
58731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  void RecordHistogramDelta(const base::Histogram& histogram,
59731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                            const base::Histogram::SampleSet& snapshot);
6006741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch
6106741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  // Stop writing to this record and generate the encoded representation.
6206741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  // None of the Record* methods can be called after this is called.
6306741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  void CloseLog();
6406741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch
6506741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  // These methods allow retrieval of the encoded representation of the
6606741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  // record.  They can only be called after CloseLog() has been called.
6706741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  // GetEncodedLog returns false if buffer_size is less than
6806741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  // GetEncodedLogSize();
6906741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  int GetEncodedLogSize();
7006741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  bool GetEncodedLog(char* buffer, int buffer_size);
7106741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  // Returns an empty string on failure.
7206741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  std::string GetEncodedLogString();
7306741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch
7406741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  // Returns the amount of time in seconds that this log has been in use.
7506741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  int GetElapsedSeconds();
7606741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch
7706741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  int num_events() { return num_events_; }
7806741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch
7906741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  void set_hardware_class(const std::string& hardware_class) {
8006741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch    hardware_class_ = hardware_class;
8106741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  }
8206741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch
8306741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  // Creates an MD5 hash of the given value, and returns hash as a byte
8406741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  // buffer encoded as a std::string.
8506741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  static std::string CreateHash(const std::string& value);
8606741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch
8706741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  // Return a base64-encoded MD5 hash of the given string.
8806741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  static std::string CreateBase64Hash(const std::string& string);
8906741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch
9006741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  // Get the GMT buildtime for the current binary, expressed in seconds since
9106741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  // Januray 1, 1970 GMT.
9206741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  // The value is used to identify when a new build is run, so that previous
9306741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  // reliability stats, from other builds, can be abandoned.
9406741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  static int64 GetBuildTime();
9506741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch
9606741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  // Use |extension| in all uploaded appversions in addition to the standard
9706741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  // version string.
9806741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  static void set_version_extension(const std::string& extension) {
9906741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch    version_extension_ = extension;
10006741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  }
10106741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch
10221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  virtual MetricsLog* AsMetricsLog();
10306741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch
10406741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch protected:
10506741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  class XmlWrapper;
10606741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch
10706741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  // Returns a string containing the current time.
10806741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  // Virtual so that it can be overridden for testing.
10906741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  virtual std::string GetCurrentTimeString();
11006741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  // Helper class that invokes StartElement from constructor, and EndElement
11106741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  // from destructor.
11206741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  //
11306741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  // Use the macro OPEN_ELEMENT_FOR_SCOPE to help avoid usage problems.
11406741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  class ScopedElement {
11506741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch   public:
11606741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch    ScopedElement(MetricsLogBase* log, const std::string& name) : log_(log) {
11706741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch      DCHECK(log);
11806741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch      log->StartElement(name.c_str());
11906741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch    }
12006741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch
12106741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch    ScopedElement(MetricsLogBase* log, const char* name) : log_(log) {
12206741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch      DCHECK(log);
12306741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch      log->StartElement(name);
12406741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch    }
12506741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch
12606741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch    ~ScopedElement() {
12706741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch      log_->EndElement();
12806741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch    }
12906741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch
13006741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch   private:
13106741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch     MetricsLogBase* log_;
13206741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  };
13306741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  friend class ScopedElement;
13406741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch
13506741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  static const char* WindowEventTypeToString(WindowEventType type);
13606741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch
13706741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  // Frees the resources allocated by the XML document writer: the
13806741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  // main writer object as well as the XML tree structure, if
13906741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  // applicable.
14006741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  void FreeDocWriter();
14106741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch
14206741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  // Convenience versions of xmlWriter functions
14306741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  void StartElement(const char* name);
14406741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  void EndElement();
14506741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  void WriteAttribute(const std::string& name, const std::string& value);
14606741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  void WriteIntAttribute(const std::string& name, int value);
14706741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  void WriteInt64Attribute(const std::string& name, int64 value);
14806741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch
14906741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  // Write the attributes that are common to every metrics event type.
15006741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  void WriteCommonEventAttributes();
15106741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch
15206741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  // An extension that is appended to the appversion in each log.
15306741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  static std::string version_extension_;
15406741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch
15506741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  base::Time start_time_;
15606741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  base::Time end_time_;
15706741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch
15806741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  std::string client_id_;
15906741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  std::string session_id_;
16006741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  std::string hardware_class_;
16106741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch
16206741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  // locked_ is true when record has been packed up for sending, and should
16306741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  // no longer be written to.  It is only used for sanity checking and is
16406741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  // not a real lock.
16506741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  bool locked_;
16606741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch
16706741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  // Isolated to limit the dependency on the XML library for our consumers.
16806741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  XmlWrapper* xml_wrapper_;
16906741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch
17006741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  int num_events_;  // the number of events recorded in this log
17106741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch
17206741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  DISALLOW_COPY_AND_ASSIGN(MetricsLogBase);
17306741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch};
17406741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch
1754a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch// HistogramSender handles the logistics of gathering up available histograms
1764a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch// for transmission (such as from renderer to browser, or from browser to UMA
1774a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch// upload).  It has several pure virtual functions that are replaced in
1784a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch// derived classes to allow the exact lower level transmission mechanism,
1794a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch// or error report mechanism, to be replaced.  Since histograms can sit in
1804a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch// memory for an extended period of time, and are vulnerable to memory
1814a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch// corruption, this class also validates as much rendundancy as it can before
1824a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch// calling for the marginal change (a.k.a., delta) in a histogram to be sent
1834a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch// onward.
1844a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdochclass HistogramSender {
1854a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch protected:
18621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  HistogramSender();
18721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  virtual ~HistogramSender();
1884a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch
1894a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  // Snapshot all histograms, and transmit the delta.
1904a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  // The arguments allow a derived class to select only a subset for
1914a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  // transmission, or to set a flag in each transmitted histogram.
1924a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  void TransmitAllHistograms(base::Histogram::Flags flags_to_set,
1934a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch                             bool send_only_uma);
1944a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch
1954a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  // Send the histograms onward, as defined in a derived class.
1964a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  // This is only called with a delta, listing samples that have not previously
1974a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  // been transmitted.
1984a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  virtual void TransmitHistogramDelta(
1994a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch      const base::Histogram& histogram,
2004a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch      const base::Histogram::SampleSet& snapshot) = 0;
2014a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch
2024a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  // Record various errors found during attempts to send histograms.
2034a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  virtual void InconsistencyDetected(int problem) = 0;
2044a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  virtual void UniqueInconsistencyDetected(int problem) = 0;
2054a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  virtual void SnapshotProblemResolved(int amount) = 0;
2064a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch
2074a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch private:
2084a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  // Maintain a map of histogram names to the sample stats we've sent.
2094a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  typedef std::map<std::string, base::Histogram::SampleSet> LoggedSampleMap;
2104a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  // List of histograms names, and their encontered corruptions.
2114a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  typedef std::map<std::string, int> ProblemMap;
2124a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch
2134a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  // Snapshot this histogram, and transmit the delta.
2144a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  void TransmitHistogram(const base::Histogram& histogram);
2154a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch
2164a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  // For histograms, record what we've already transmitted (as a sample for each
2174a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  // histogram) so that we can send only the delta with the next log.
2184a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  LoggedSampleMap logged_samples_;
2194a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch
2204a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  // List of histograms found corrupt to be corrupt, and their problems.
2214a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  scoped_ptr<ProblemMap> inconsistencies_;
2224a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch
2234a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  DISALLOW_COPY_AND_ASSIGN(HistogramSender);
2244a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch};
2254a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch
22606741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch// This class provides base functionality for logging metrics data.
22706741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch// TODO(ananta)
22806741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch// Factor out more common code from chrome and chrome frame metrics service
22906741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch// into this class.
2304a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdochclass MetricsServiceBase : public HistogramSender {
23106741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch protected:
23206741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  MetricsServiceBase();
23306741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  virtual ~MetricsServiceBase();
23406741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch
23506741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  // Check to see if there is a log that needs to be, or is being, transmitted.
23606741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  bool pending_log() const {
23706741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch    return pending_log_ || !compressed_log_.empty();
23806741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  }
23906741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch
24006741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  // Compress the report log in |input| using bzip2, store the result in
24106741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  // |output|.
24206741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  bool Bzip2Compress(const std::string& input, std::string* output);
24306741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch
24406741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  // Discard |pending_log_|, and clear |compressed_log_|. Called after
24506741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  // processing of this log is complete.
24606741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  void DiscardPendingLog();
24706741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch
24806741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  // Record complete list of histograms into the current log.
24906741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  // Called when we close a log.
25006741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  void RecordCurrentHistograms();
25106741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch
25206741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  // A log that we are currently transmiting, or about to try to transmit.
25306741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  MetricsLogBase* pending_log_;
25406741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch
25506741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  // An alternate form of |pending_log_|.  We persistently save this version
25606741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  // into prefs if we can't transmit it.  As a result, sometimes all we have is
25706741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  // the compressed text version.
25806741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  std::string compressed_log_;
25906741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch
26006741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  // The log that we are still appending to.
26106741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  MetricsLogBase* current_log_;
26206741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch
2634a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch private:
2644a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  // HistogramSender interface (override) methods.
2654a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  virtual void TransmitHistogramDelta(
2664a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch      const base::Histogram& histogram,
2674a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch      const base::Histogram::SampleSet& snapshot);
2684a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  virtual void InconsistencyDetected(int problem);
2694a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  virtual void UniqueInconsistencyDetected(int problem);
2704a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  virtual void SnapshotProblemResolved(int amount);
2713345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
2723345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  DISALLOW_COPY_AND_ASSIGN(MetricsServiceBase);
27306741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch};
27406741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch
27506741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch#endif  // CHROME_COMMON_METRICS_HELPERS_H_
276