Home | History | Annotate | Download | only in metrics
      1 // Copyright 2013 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 #include "base/metrics/histogram_delta_serialization.h"
      6 
      7 #include "base/logging.h"
      8 #include "base/metrics/histogram_base.h"
      9 #include "base/metrics/histogram_snapshot_manager.h"
     10 #include "base/metrics/statistics_recorder.h"
     11 #include "base/numerics/safe_conversions.h"
     12 #include "base/pickle.h"
     13 #include "base/values.h"
     14 
     15 namespace base {
     16 
     17 namespace {
     18 
     19 // Create or find existing histogram and add the samples from pickle.
     20 // Silently returns when seeing any data problem in the pickle.
     21 void DeserializeHistogramAndAddSamples(PickleIterator* iter) {
     22   HistogramBase* histogram = DeserializeHistogramInfo(iter);
     23   if (!histogram)
     24     return;
     25 
     26   if (histogram->flags() & HistogramBase::kIPCSerializationSourceFlag) {
     27     DVLOG(1) << "Single process mode, histogram observed and not copied: "
     28              << histogram->histogram_name();
     29     return;
     30   }
     31   histogram->AddSamplesFromPickle(iter);
     32 }
     33 
     34 }  // namespace
     35 
     36 HistogramDeltaSerialization::HistogramDeltaSerialization(
     37     const std::string& caller_name)
     38     : histogram_snapshot_manager_(this),
     39       serialized_deltas_(NULL) {
     40   inconsistencies_histogram_ =
     41       LinearHistogram::FactoryGet(
     42           "Histogram.Inconsistencies" + caller_name, 1,
     43           HistogramBase::NEVER_EXCEEDED_VALUE,
     44           HistogramBase::NEVER_EXCEEDED_VALUE + 1,
     45           HistogramBase::kUmaTargetedHistogramFlag);
     46 
     47   inconsistencies_unique_histogram_ =
     48       LinearHistogram::FactoryGet(
     49           "Histogram.Inconsistencies" + caller_name + "Unique", 1,
     50           HistogramBase::NEVER_EXCEEDED_VALUE,
     51           HistogramBase::NEVER_EXCEEDED_VALUE + 1,
     52           HistogramBase::kUmaTargetedHistogramFlag);
     53 
     54   inconsistent_snapshot_histogram_ =
     55       Histogram::FactoryGet(
     56           "Histogram.InconsistentSnapshot" + caller_name, 1, 1000000, 50,
     57           HistogramBase::kUmaTargetedHistogramFlag);
     58 }
     59 
     60 HistogramDeltaSerialization::~HistogramDeltaSerialization() {
     61 }
     62 
     63 void HistogramDeltaSerialization::PrepareAndSerializeDeltas(
     64     std::vector<std::string>* serialized_deltas,
     65     bool include_persistent) {
     66   DCHECK(thread_checker_.CalledOnValidThread());
     67 
     68   serialized_deltas_ = serialized_deltas;
     69   // Note: Before serializing, we set the kIPCSerializationSourceFlag for all
     70   // the histograms, so that the receiving process can distinguish them from the
     71   // local histograms.
     72   histogram_snapshot_manager_.PrepareDeltas(
     73       StatisticsRecorder::begin(include_persistent), StatisticsRecorder::end(),
     74       Histogram::kIPCSerializationSourceFlag, Histogram::kNoFlags);
     75   serialized_deltas_ = NULL;
     76 }
     77 
     78 // static
     79 void HistogramDeltaSerialization::DeserializeAndAddSamples(
     80     const std::vector<std::string>& serialized_deltas) {
     81   for (std::vector<std::string>::const_iterator it = serialized_deltas.begin();
     82        it != serialized_deltas.end(); ++it) {
     83     Pickle pickle(it->data(), checked_cast<int>(it->size()));
     84     PickleIterator iter(pickle);
     85     DeserializeHistogramAndAddSamples(&iter);
     86   }
     87 }
     88 
     89 void HistogramDeltaSerialization::RecordDelta(
     90     const HistogramBase& histogram,
     91     const HistogramSamples& snapshot) {
     92   DCHECK(thread_checker_.CalledOnValidThread());
     93   DCHECK_NE(0, snapshot.TotalCount());
     94 
     95   Pickle pickle;
     96   histogram.SerializeInfo(&pickle);
     97   snapshot.Serialize(&pickle);
     98   serialized_deltas_->push_back(
     99       std::string(static_cast<const char*>(pickle.data()), pickle.size()));
    100 }
    101 
    102 void HistogramDeltaSerialization::InconsistencyDetected(
    103     HistogramBase::Inconsistency problem) {
    104   DCHECK(thread_checker_.CalledOnValidThread());
    105 
    106   inconsistencies_histogram_->Add(problem);
    107 }
    108 
    109 void HistogramDeltaSerialization::UniqueInconsistencyDetected(
    110     HistogramBase::Inconsistency problem) {
    111   DCHECK(thread_checker_.CalledOnValidThread());
    112 
    113   inconsistencies_unique_histogram_->Add(problem);
    114 }
    115 
    116 void HistogramDeltaSerialization::InconsistencyDetectedInLoggedCount(
    117     int amount) {
    118   DCHECK(thread_checker_.CalledOnValidThread());
    119 
    120   inconsistent_snapshot_histogram_->Add(std::abs(amount));
    121 }
    122 
    123 }  // namespace base
    124