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 15namespace base { 16 17namespace { 18 19// Create or find existing histogram and add the samples from pickle. 20// Silently returns when seeing any data problem in the pickle. 21void 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 36HistogramDeltaSerialization::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 60HistogramDeltaSerialization::~HistogramDeltaSerialization() { 61} 62 63void 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 79void 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 89void 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 102void HistogramDeltaSerialization::InconsistencyDetected( 103 HistogramBase::Inconsistency problem) { 104 DCHECK(thread_checker_.CalledOnValidThread()); 105 106 inconsistencies_histogram_->Add(problem); 107} 108 109void HistogramDeltaSerialization::UniqueInconsistencyDetected( 110 HistogramBase::Inconsistency problem) { 111 DCHECK(thread_checker_.CalledOnValidThread()); 112 113 inconsistencies_unique_histogram_->Add(problem); 114} 115 116void 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