// Copyright 2013 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #include "base/metrics/histogram_delta_serialization.h" #include "base/logging.h" #include "base/metrics/histogram_base.h" #include "base/metrics/histogram_snapshot_manager.h" #include "base/numerics/safe_conversions.h" #include "base/pickle.h" #include "base/values.h" namespace base { namespace { // Create or find existing histogram and add the samples from pickle. // Silently returns when seeing any data problem in the pickle. void DeserializeHistogramAndAddSamples(PickleIterator* iter) { HistogramBase* histogram = DeserializeHistogramInfo(iter); if (!histogram) return; if (histogram->flags() & HistogramBase::kIPCSerializationSourceFlag) { DVLOG(1) << "Single process mode, histogram observed and not copied: " << histogram->histogram_name(); return; } histogram->AddSamplesFromPickle(iter); } } // namespace HistogramDeltaSerialization::HistogramDeltaSerialization( const std::string& caller_name) : histogram_snapshot_manager_(this), serialized_deltas_(NULL) { inconsistencies_histogram_ = LinearHistogram::FactoryGet( "Histogram.Inconsistencies" + caller_name, 1, HistogramBase::NEVER_EXCEEDED_VALUE, HistogramBase::NEVER_EXCEEDED_VALUE + 1, HistogramBase::kUmaTargetedHistogramFlag); inconsistencies_unique_histogram_ = LinearHistogram::FactoryGet( "Histogram.Inconsistencies" + caller_name + "Unique", 1, HistogramBase::NEVER_EXCEEDED_VALUE, HistogramBase::NEVER_EXCEEDED_VALUE + 1, HistogramBase::kUmaTargetedHistogramFlag); inconsistent_snapshot_histogram_ = Histogram::FactoryGet( "Histogram.InconsistentSnapshot" + caller_name, 1, 1000000, 50, HistogramBase::kUmaTargetedHistogramFlag); } HistogramDeltaSerialization::~HistogramDeltaSerialization() { } void HistogramDeltaSerialization::PrepareAndSerializeDeltas( std::vector* serialized_deltas) { DCHECK(thread_checker_.CalledOnValidThread()); serialized_deltas_ = serialized_deltas; // Note: Before serializing, we set the kIPCSerializationSourceFlag for all // the histograms, so that the receiving process can distinguish them from the // local histograms. histogram_snapshot_manager_.PrepareDeltas( Histogram::kIPCSerializationSourceFlag, Histogram::kNoFlags); serialized_deltas_ = NULL; } // static void HistogramDeltaSerialization::DeserializeAndAddSamples( const std::vector& serialized_deltas) { for (std::vector::const_iterator it = serialized_deltas.begin(); it != serialized_deltas.end(); ++it) { Pickle pickle(it->data(), checked_cast(it->size())); PickleIterator iter(pickle); DeserializeHistogramAndAddSamples(&iter); } } void HistogramDeltaSerialization::RecordDelta( const HistogramBase& histogram, const HistogramSamples& snapshot) { DCHECK(thread_checker_.CalledOnValidThread()); DCHECK_NE(0, snapshot.TotalCount()); Pickle pickle; histogram.SerializeInfo(&pickle); snapshot.Serialize(&pickle); serialized_deltas_->push_back( std::string(static_cast(pickle.data()), pickle.size())); } void HistogramDeltaSerialization::InconsistencyDetected( HistogramBase::Inconsistency problem) { DCHECK(thread_checker_.CalledOnValidThread()); inconsistencies_histogram_->Add(problem); } void HistogramDeltaSerialization::UniqueInconsistencyDetected( HistogramBase::Inconsistency problem) { DCHECK(thread_checker_.CalledOnValidThread()); inconsistencies_unique_histogram_->Add(problem); } void HistogramDeltaSerialization::InconsistencyDetectedInLoggedCount( int amount) { DCHECK(thread_checker_.CalledOnValidThread()); inconsistent_snapshot_histogram_->Add(std::abs(amount)); } } // namespace base