Use bounded ranges (string_view) for histogram names.
This CL changes the histogram creation APIs to take a durable string view (i.e., a pointer+size pair referring to memory that the programmer has annotated that it will not be freed) instead of just an implicit pointer. The HistogramBase class internally represents the name's length and the histogram's flags using 16 bits in order to not grow the in-memory size of Histogram objects. The name of the histogram is subsequently exposed by HistogramBase as a string_view. This CL updates consumers of the histogram name's to use a string_view of the name. This removes many string length calculations and string copy operations. For histograms allocated in shared memory, it also avoids potential out-of- bounds reads if the underlying string data is modified or corrupted such that it no longer has a trailing NUL char at the end of the string. Lastly, this CL updates a number of call-sites where the histogram names were being copied into short-lived string objects for use as search keys into various containers to perform the functionality without making any unnecessary copies. Low-Coverage-Reason: TRIVIAL_CHANGE Use of string_view instead of string/char* in some error/logging paths have low coverage. AX-Relnotes: n/a Bug: 393394360, 40818143 Change-Id: Iee9ee5ae62335b9e7815f4ae11bde4ff80cfd4a2 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6231451 Reviewed-by: Avi Drissman <avi@chromium.org> Reviewed-by: Antonio Rivera <antoniori@google.com> Commit-Queue: Roger McFarlane <rogerm@chromium.org> Reviewed-by: Etienne Pierre-Doray <etiennep@chromium.org> Reviewed-by: Nico Weber <thakis@chromium.org> Cr-Commit-Position: refs/heads/main@{#1422750}
This commit is contained in:

committed by
Chromium LUCI CQ

parent
a2d6b9176f
commit
8952859c39
base
BUILD.gn
android
metrics
dummy_histogram.hhistogram.cchistogram.hhistogram_base.cchistogram_base.hhistogram_base_unittest.cchistogram_snapshot_manager_unittest.cchistogram_threadsafe_unittest.ccpersistent_histogram_allocator.ccpersistent_histogram_allocator.hpersistent_histogram_allocator_unittest.ccsparse_histogram.ccsparse_histogram.hsparse_histogram_unittest.ccstatistics_recorder.ccstatistics_recorder.hstatistics_recorder_unittest.cc
strings
test
metrics
chrome/browser
ash
autofill
metrics
notifications
os_crypt
password_manager
privacy_sandbox
segmentation_platform
site_protection
ui
chromecast/base/metrics
chromeos/ash/services/ime/public/mojom
components
fuchsia_legacymetrics
metrics
content
file_metrics_provider_unittest.cchistogram_encoder.cchistogram_encoder.hmetrics_log.ccmetrics_log.hnet
segmentation_platform
internal
value_store
content/browser
devtools
metrics
shared_storage
tracing
ios/chrome
services/tracing/public/cpp
background_tracing
perfetto
third_party/webrtc_overrides
@ -589,6 +589,7 @@ component("base") {
|
|||||||
"strings/abseil_string_number_conversions.cc",
|
"strings/abseil_string_number_conversions.cc",
|
||||||
"strings/abseil_string_number_conversions.h",
|
"strings/abseil_string_number_conversions.h",
|
||||||
"strings/cstring_view.h",
|
"strings/cstring_view.h",
|
||||||
|
"strings/durable_string_view.h",
|
||||||
"strings/escape.cc",
|
"strings/escape.cc",
|
||||||
"strings/escape.h",
|
"strings/escape.h",
|
||||||
"strings/latin1_string_conversions.cc",
|
"strings/latin1_string_conversions.cc",
|
||||||
|
@ -2,10 +2,13 @@
|
|||||||
// Use of this source code is governed by a BSD-style license that can be
|
// Use of this source code is governed by a BSD-style license that can be
|
||||||
// found in the LICENSE file.
|
// found in the LICENSE file.
|
||||||
|
|
||||||
|
#include <map>
|
||||||
|
|
||||||
#include "base/android/callback_android.h"
|
#include "base/android/callback_android.h"
|
||||||
#include "base/android/jni_android.h"
|
#include "base/android/jni_android.h"
|
||||||
#include "base/android/jni_array.h"
|
#include "base/android/jni_array.h"
|
||||||
#include "base/android/jni_string.h"
|
#include "base/android/jni_string.h"
|
||||||
|
#include "base/containers/map_util.h"
|
||||||
#include "base/format_macros.h"
|
#include "base/format_macros.h"
|
||||||
#include "base/metrics/histogram.h"
|
#include "base/metrics/histogram.h"
|
||||||
#include "base/metrics/histogram_base.h"
|
#include "base/metrics/histogram_base.h"
|
||||||
@ -24,25 +27,25 @@ namespace android {
|
|||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
using HistogramsSnapshot =
|
using HistogramsSnapshot =
|
||||||
std::map<std::string, std::unique_ptr<HistogramSamples>>;
|
std::map<std::string, std::unique_ptr<HistogramSamples>, std::less<>>;
|
||||||
|
|
||||||
std::string HistogramConstructionParamsToString(HistogramBase* histogram) {
|
std::string HistogramConstructionParamsToString(HistogramBase* histogram) {
|
||||||
std::string params_str = histogram->histogram_name();
|
std::string_view name = histogram->histogram_name();
|
||||||
switch (histogram->GetHistogramType()) {
|
switch (histogram->GetHistogramType()) {
|
||||||
case HISTOGRAM:
|
case HISTOGRAM:
|
||||||
case LINEAR_HISTOGRAM:
|
case LINEAR_HISTOGRAM:
|
||||||
case BOOLEAN_HISTOGRAM:
|
case BOOLEAN_HISTOGRAM:
|
||||||
case CUSTOM_HISTOGRAM: {
|
case CUSTOM_HISTOGRAM: {
|
||||||
Histogram* hist = static_cast<Histogram*>(histogram);
|
Histogram* hist = static_cast<Histogram*>(histogram);
|
||||||
params_str += StringPrintf("/%d/%d/%" PRIuS, hist->declared_min(),
|
return StringPrintf("%.*s/%d/%d/%" PRIuS, name.length(), name.data(),
|
||||||
hist->declared_max(), hist->bucket_count());
|
hist->declared_min(), hist->declared_max(),
|
||||||
break;
|
hist->bucket_count());
|
||||||
}
|
}
|
||||||
case SPARSE_HISTOGRAM:
|
case SPARSE_HISTOGRAM:
|
||||||
case DUMMY_HISTOGRAM:
|
case DUMMY_HISTOGRAM:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return params_str;
|
return std::string(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Convert a jlong |histogram_hint| from Java to a HistogramBase* via a cast.
|
// Convert a jlong |histogram_hint| from Java to a HistogramBase* via a cast.
|
||||||
@ -289,7 +292,8 @@ JNI_NativeUmaRecorder_GetHistogramSamplesForTesting(JNIEnv* env,
|
|||||||
jlong JNI_NativeUmaRecorder_CreateHistogramSnapshotForTesting(JNIEnv* env) {
|
jlong JNI_NativeUmaRecorder_CreateHistogramSnapshotForTesting(JNIEnv* env) {
|
||||||
HistogramsSnapshot* snapshot = new HistogramsSnapshot();
|
HistogramsSnapshot* snapshot = new HistogramsSnapshot();
|
||||||
for (const auto* const histogram : StatisticsRecorder::GetHistograms()) {
|
for (const auto* const histogram : StatisticsRecorder::GetHistograms()) {
|
||||||
(*snapshot)[histogram->histogram_name()] = histogram->SnapshotSamples();
|
InsertOrAssign(*snapshot, histogram->histogram_name(),
|
||||||
|
histogram->SnapshotSamples());
|
||||||
}
|
}
|
||||||
return reinterpret_cast<intptr_t>(snapshot);
|
return reinterpret_cast<intptr_t>(snapshot);
|
||||||
}
|
}
|
||||||
|
@ -54,7 +54,7 @@ class BASE_EXPORT DummyHistogram : public HistogramBase {
|
|||||||
private:
|
private:
|
||||||
friend class NoDestructor<DummyHistogram>;
|
friend class NoDestructor<DummyHistogram>;
|
||||||
|
|
||||||
DummyHistogram() : HistogramBase("dummy_histogram") {}
|
DummyHistogram() : HistogramBase(DurableStringView("dummy_histogram")) {}
|
||||||
~DummyHistogram() override = default;
|
~DummyHistogram() override = default;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -317,14 +317,14 @@ HistogramBase* Histogram::FactoryMicrosecondsTimeGet(const char* name,
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<HistogramBase> Histogram::PersistentCreate(
|
std::unique_ptr<HistogramBase> Histogram::PersistentCreate(
|
||||||
const char* name,
|
DurableStringView durable_name,
|
||||||
const BucketRanges* ranges,
|
const BucketRanges* ranges,
|
||||||
const DelayedPersistentAllocation& counts,
|
const DelayedPersistentAllocation& counts,
|
||||||
const DelayedPersistentAllocation& logged_counts,
|
const DelayedPersistentAllocation& logged_counts,
|
||||||
HistogramSamples::Metadata* meta,
|
HistogramSamples::Metadata* meta,
|
||||||
HistogramSamples::Metadata* logged_meta) {
|
HistogramSamples::Metadata* logged_meta) {
|
||||||
return WrapUnique(
|
return WrapUnique(new Histogram(durable_name, ranges, counts, logged_counts,
|
||||||
new Histogram(name, ranges, counts, logged_counts, meta, logged_meta));
|
meta, logged_meta));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Calculate what range of values are held in each bucket.
|
// Calculate what range of values are held in each bucket.
|
||||||
@ -623,25 +623,25 @@ void Histogram::SerializeInfoImpl(Pickle* pickle) const {
|
|||||||
pickle->WriteUInt32(bucket_ranges()->checksum());
|
pickle->WriteUInt32(bucket_ranges()->checksum());
|
||||||
}
|
}
|
||||||
|
|
||||||
Histogram::Histogram(const char* name, const BucketRanges* ranges)
|
Histogram::Histogram(DurableStringView durable_name, const BucketRanges* ranges)
|
||||||
: HistogramBase(name) {
|
: HistogramBase(durable_name) {
|
||||||
DCHECK(ranges) << name;
|
DCHECK(ranges) << histogram_name();
|
||||||
unlogged_samples_ =
|
unlogged_samples_ =
|
||||||
std::make_unique<SampleVector>(HashMetricName(name), ranges);
|
std::make_unique<SampleVector>(HashMetricName(histogram_name()), ranges);
|
||||||
logged_samples_ =
|
logged_samples_ =
|
||||||
std::make_unique<SampleVector>(unlogged_samples_->id(), ranges);
|
std::make_unique<SampleVector>(unlogged_samples_->id(), ranges);
|
||||||
}
|
}
|
||||||
|
|
||||||
Histogram::Histogram(const char* name,
|
Histogram::Histogram(DurableStringView durable_name,
|
||||||
const BucketRanges* ranges,
|
const BucketRanges* ranges,
|
||||||
const DelayedPersistentAllocation& counts,
|
const DelayedPersistentAllocation& counts,
|
||||||
const DelayedPersistentAllocation& logged_counts,
|
const DelayedPersistentAllocation& logged_counts,
|
||||||
HistogramSamples::Metadata* meta,
|
HistogramSamples::Metadata* meta,
|
||||||
HistogramSamples::Metadata* logged_meta)
|
HistogramSamples::Metadata* logged_meta)
|
||||||
: HistogramBase(name) {
|
: HistogramBase(durable_name) {
|
||||||
DCHECK(ranges) << name;
|
DCHECK(ranges) << histogram_name();
|
||||||
unlogged_samples_ = std::make_unique<PersistentSampleVector>(
|
unlogged_samples_ = std::make_unique<PersistentSampleVector>(
|
||||||
HashMetricName(name), ranges, meta, counts);
|
HashMetricName(histogram_name()), ranges, meta, counts);
|
||||||
logged_samples_ = std::make_unique<PersistentSampleVector>(
|
logged_samples_ = std::make_unique<PersistentSampleVector>(
|
||||||
unlogged_samples_->id(), ranges, logged_meta, logged_counts);
|
unlogged_samples_->id(), ranges, logged_meta, logged_counts);
|
||||||
}
|
}
|
||||||
@ -860,14 +860,14 @@ HistogramBase* LinearHistogram::FactoryTimeGet(const char* name,
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<HistogramBase> LinearHistogram::PersistentCreate(
|
std::unique_ptr<HistogramBase> LinearHistogram::PersistentCreate(
|
||||||
const char* name,
|
DurableStringView durable_name,
|
||||||
const BucketRanges* ranges,
|
const BucketRanges* ranges,
|
||||||
const DelayedPersistentAllocation& counts,
|
const DelayedPersistentAllocation& counts,
|
||||||
const DelayedPersistentAllocation& logged_counts,
|
const DelayedPersistentAllocation& logged_counts,
|
||||||
HistogramSamples::Metadata* meta,
|
HistogramSamples::Metadata* meta,
|
||||||
HistogramSamples::Metadata* logged_meta) {
|
HistogramSamples::Metadata* logged_meta) {
|
||||||
return WrapUnique(new LinearHistogram(name, ranges, counts, logged_counts,
|
return WrapUnique(new LinearHistogram(durable_name, ranges, counts,
|
||||||
meta, logged_meta));
|
logged_counts, meta, logged_meta));
|
||||||
}
|
}
|
||||||
|
|
||||||
HistogramBase* LinearHistogram::FactoryGetWithRangeDescription(
|
HistogramBase* LinearHistogram::FactoryGetWithRangeDescription(
|
||||||
@ -905,17 +905,23 @@ HistogramType LinearHistogram::GetHistogramType() const {
|
|||||||
return LINEAR_HISTOGRAM;
|
return LINEAR_HISTOGRAM;
|
||||||
}
|
}
|
||||||
|
|
||||||
LinearHistogram::LinearHistogram(const char* name, const BucketRanges* ranges)
|
LinearHistogram::LinearHistogram(DurableStringView durable_name,
|
||||||
: Histogram(name, ranges) {}
|
const BucketRanges* ranges)
|
||||||
|
: Histogram(durable_name, ranges) {}
|
||||||
|
|
||||||
LinearHistogram::LinearHistogram(
|
LinearHistogram::LinearHistogram(
|
||||||
const char* name,
|
DurableStringView durable_name,
|
||||||
const BucketRanges* ranges,
|
const BucketRanges* ranges,
|
||||||
const DelayedPersistentAllocation& counts,
|
const DelayedPersistentAllocation& counts,
|
||||||
const DelayedPersistentAllocation& logged_counts,
|
const DelayedPersistentAllocation& logged_counts,
|
||||||
HistogramSamples::Metadata* meta,
|
HistogramSamples::Metadata* meta,
|
||||||
HistogramSamples::Metadata* logged_meta)
|
HistogramSamples::Metadata* logged_meta)
|
||||||
: Histogram(name, ranges, counts, logged_counts, meta, logged_meta) {}
|
: Histogram(durable_name,
|
||||||
|
ranges,
|
||||||
|
counts,
|
||||||
|
logged_counts,
|
||||||
|
meta,
|
||||||
|
logged_meta) {}
|
||||||
|
|
||||||
std::string LinearHistogram::GetAsciiBucketRange(size_t i) const {
|
std::string LinearHistogram::GetAsciiBucketRange(size_t i) const {
|
||||||
int range = ranges(i);
|
int range = ranges(i);
|
||||||
@ -1141,14 +1147,14 @@ HistogramBase* BooleanHistogram::FactoryGet(const char* name, int32_t flags) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<HistogramBase> BooleanHistogram::PersistentCreate(
|
std::unique_ptr<HistogramBase> BooleanHistogram::PersistentCreate(
|
||||||
const char* name,
|
DurableStringView durable_name,
|
||||||
const BucketRanges* ranges,
|
const BucketRanges* ranges,
|
||||||
const DelayedPersistentAllocation& counts,
|
const DelayedPersistentAllocation& counts,
|
||||||
const DelayedPersistentAllocation& logged_counts,
|
const DelayedPersistentAllocation& logged_counts,
|
||||||
HistogramSamples::Metadata* meta,
|
HistogramSamples::Metadata* meta,
|
||||||
HistogramSamples::Metadata* logged_meta) {
|
HistogramSamples::Metadata* logged_meta) {
|
||||||
return WrapUnique(new BooleanHistogram(name, ranges, counts, logged_counts,
|
return WrapUnique(new BooleanHistogram(durable_name, ranges, counts,
|
||||||
meta, logged_meta));
|
logged_counts, meta, logged_meta));
|
||||||
}
|
}
|
||||||
|
|
||||||
HistogramType BooleanHistogram::GetHistogramType() const {
|
HistogramType BooleanHistogram::GetHistogramType() const {
|
||||||
@ -1161,17 +1167,23 @@ HistogramBase* BooleanHistogram::FactoryGetInternal(std::string_view name,
|
|||||||
return Factory(name, flags).Build();
|
return Factory(name, flags).Build();
|
||||||
}
|
}
|
||||||
|
|
||||||
BooleanHistogram::BooleanHistogram(const char* name, const BucketRanges* ranges)
|
BooleanHistogram::BooleanHistogram(DurableStringView durable_name,
|
||||||
: LinearHistogram(name, ranges) {}
|
const BucketRanges* ranges)
|
||||||
|
: LinearHistogram(durable_name, ranges) {}
|
||||||
|
|
||||||
BooleanHistogram::BooleanHistogram(
|
BooleanHistogram::BooleanHistogram(
|
||||||
const char* name,
|
DurableStringView durable_name,
|
||||||
const BucketRanges* ranges,
|
const BucketRanges* ranges,
|
||||||
const DelayedPersistentAllocation& counts,
|
const DelayedPersistentAllocation& counts,
|
||||||
const DelayedPersistentAllocation& logged_counts,
|
const DelayedPersistentAllocation& logged_counts,
|
||||||
HistogramSamples::Metadata* meta,
|
HistogramSamples::Metadata* meta,
|
||||||
HistogramSamples::Metadata* logged_meta)
|
HistogramSamples::Metadata* logged_meta)
|
||||||
: LinearHistogram(name, ranges, counts, logged_counts, meta, logged_meta) {}
|
: LinearHistogram(durable_name,
|
||||||
|
ranges,
|
||||||
|
counts,
|
||||||
|
logged_counts,
|
||||||
|
meta,
|
||||||
|
logged_meta) {}
|
||||||
|
|
||||||
HistogramBase* BooleanHistogram::DeserializeInfoImpl(PickleIterator* iter) {
|
HistogramBase* BooleanHistogram::DeserializeInfoImpl(PickleIterator* iter) {
|
||||||
std::string histogram_name;
|
std::string histogram_name;
|
||||||
@ -1264,14 +1276,14 @@ HistogramBase* CustomHistogram::FactoryGet(
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<HistogramBase> CustomHistogram::PersistentCreate(
|
std::unique_ptr<HistogramBase> CustomHistogram::PersistentCreate(
|
||||||
const char* name,
|
DurableStringView durable_name,
|
||||||
const BucketRanges* ranges,
|
const BucketRanges* ranges,
|
||||||
const DelayedPersistentAllocation& counts,
|
const DelayedPersistentAllocation& counts,
|
||||||
const DelayedPersistentAllocation& logged_counts,
|
const DelayedPersistentAllocation& logged_counts,
|
||||||
HistogramSamples::Metadata* meta,
|
HistogramSamples::Metadata* meta,
|
||||||
HistogramSamples::Metadata* logged_meta) {
|
HistogramSamples::Metadata* logged_meta) {
|
||||||
return WrapUnique(new CustomHistogram(name, ranges, counts, logged_counts,
|
return WrapUnique(new CustomHistogram(durable_name, ranges, counts,
|
||||||
meta, logged_meta));
|
logged_counts, meta, logged_meta));
|
||||||
}
|
}
|
||||||
|
|
||||||
HistogramType CustomHistogram::GetHistogramType() const {
|
HistogramType CustomHistogram::GetHistogramType() const {
|
||||||
@ -1292,17 +1304,23 @@ std::vector<Sample32> CustomHistogram::ArrayToCustomEnumRanges(
|
|||||||
return all_values;
|
return all_values;
|
||||||
}
|
}
|
||||||
|
|
||||||
CustomHistogram::CustomHistogram(const char* name, const BucketRanges* ranges)
|
CustomHistogram::CustomHistogram(DurableStringView durable_name,
|
||||||
: Histogram(name, ranges) {}
|
const BucketRanges* ranges)
|
||||||
|
: Histogram(durable_name, ranges) {}
|
||||||
|
|
||||||
CustomHistogram::CustomHistogram(
|
CustomHistogram::CustomHistogram(
|
||||||
const char* name,
|
DurableStringView durable_name,
|
||||||
const BucketRanges* ranges,
|
const BucketRanges* ranges,
|
||||||
const DelayedPersistentAllocation& counts,
|
const DelayedPersistentAllocation& counts,
|
||||||
const DelayedPersistentAllocation& logged_counts,
|
const DelayedPersistentAllocation& logged_counts,
|
||||||
HistogramSamples::Metadata* meta,
|
HistogramSamples::Metadata* meta,
|
||||||
HistogramSamples::Metadata* logged_meta)
|
HistogramSamples::Metadata* logged_meta)
|
||||||
: Histogram(name, ranges, counts, logged_counts, meta, logged_meta) {}
|
: Histogram(durable_name,
|
||||||
|
ranges,
|
||||||
|
counts,
|
||||||
|
logged_counts,
|
||||||
|
meta,
|
||||||
|
logged_meta) {}
|
||||||
|
|
||||||
void CustomHistogram::SerializeInfoImpl(Pickle* pickle) const {
|
void CustomHistogram::SerializeInfoImpl(Pickle* pickle) const {
|
||||||
Histogram::SerializeInfoImpl(pickle);
|
Histogram::SerializeInfoImpl(pickle);
|
||||||
|
@ -176,7 +176,7 @@ class BASE_EXPORT Histogram : public HistogramBase {
|
|||||||
|
|
||||||
// Create a histogram using data in persistent storage.
|
// Create a histogram using data in persistent storage.
|
||||||
static std::unique_ptr<HistogramBase> PersistentCreate(
|
static std::unique_ptr<HistogramBase> PersistentCreate(
|
||||||
const char* name,
|
DurableStringView durable_name,
|
||||||
const BucketRanges* ranges,
|
const BucketRanges* ranges,
|
||||||
const DelayedPersistentAllocation& counts,
|
const DelayedPersistentAllocation& counts,
|
||||||
const DelayedPersistentAllocation& logged_counts,
|
const DelayedPersistentAllocation& logged_counts,
|
||||||
@ -250,7 +250,7 @@ class BASE_EXPORT Histogram : public HistogramBase {
|
|||||||
|
|
||||||
// |ranges| should contain the underflow and overflow buckets. See top
|
// |ranges| should contain the underflow and overflow buckets. See top
|
||||||
// comments for example.
|
// comments for example.
|
||||||
Histogram(const char* name, const BucketRanges* ranges);
|
Histogram(DurableStringView durable_name, const BucketRanges* ranges);
|
||||||
|
|
||||||
// Traditionally, histograms allocate their own memory for the bucket
|
// Traditionally, histograms allocate their own memory for the bucket
|
||||||
// vector but "shared" histograms use memory regions allocated from a
|
// vector but "shared" histograms use memory regions allocated from a
|
||||||
@ -258,7 +258,7 @@ class BASE_EXPORT Histogram : public HistogramBase {
|
|||||||
// the life of this memory is managed externally and exceeds the lifetime
|
// the life of this memory is managed externally and exceeds the lifetime
|
||||||
// of this object. Practically, this memory is never released until the
|
// of this object. Practically, this memory is never released until the
|
||||||
// process exits and the OS cleans it up.
|
// process exits and the OS cleans it up.
|
||||||
Histogram(const char* name,
|
Histogram(DurableStringView durable_name,
|
||||||
const BucketRanges* ranges,
|
const BucketRanges* ranges,
|
||||||
const DelayedPersistentAllocation& counts,
|
const DelayedPersistentAllocation& counts,
|
||||||
const DelayedPersistentAllocation& logged_counts,
|
const DelayedPersistentAllocation& logged_counts,
|
||||||
@ -383,7 +383,7 @@ class BASE_EXPORT LinearHistogram : public Histogram {
|
|||||||
|
|
||||||
// Create a histogram using data in persistent storage.
|
// Create a histogram using data in persistent storage.
|
||||||
static std::unique_ptr<HistogramBase> PersistentCreate(
|
static std::unique_ptr<HistogramBase> PersistentCreate(
|
||||||
const char* name,
|
DurableStringView durable_name,
|
||||||
const BucketRanges* ranges,
|
const BucketRanges* ranges,
|
||||||
const DelayedPersistentAllocation& counts,
|
const DelayedPersistentAllocation& counts,
|
||||||
const DelayedPersistentAllocation& logged_counts,
|
const DelayedPersistentAllocation& logged_counts,
|
||||||
@ -418,9 +418,9 @@ class BASE_EXPORT LinearHistogram : public Histogram {
|
|||||||
protected:
|
protected:
|
||||||
class Factory;
|
class Factory;
|
||||||
|
|
||||||
LinearHistogram(const char* name, const BucketRanges* ranges);
|
LinearHistogram(DurableStringView durable_name, const BucketRanges* ranges);
|
||||||
|
|
||||||
LinearHistogram(const char* name,
|
LinearHistogram(DurableStringView durable_name,
|
||||||
const BucketRanges* ranges,
|
const BucketRanges* ranges,
|
||||||
const DelayedPersistentAllocation& counts,
|
const DelayedPersistentAllocation& counts,
|
||||||
const DelayedPersistentAllocation& logged_counts,
|
const DelayedPersistentAllocation& logged_counts,
|
||||||
@ -540,7 +540,7 @@ class BASE_EXPORT BooleanHistogram : public LinearHistogram {
|
|||||||
|
|
||||||
// Create a histogram using data in persistent storage.
|
// Create a histogram using data in persistent storage.
|
||||||
static std::unique_ptr<HistogramBase> PersistentCreate(
|
static std::unique_ptr<HistogramBase> PersistentCreate(
|
||||||
const char* name,
|
DurableStringView durable_name,
|
||||||
const BucketRanges* ranges,
|
const BucketRanges* ranges,
|
||||||
const DelayedPersistentAllocation& counts,
|
const DelayedPersistentAllocation& counts,
|
||||||
const DelayedPersistentAllocation& logged_counts,
|
const DelayedPersistentAllocation& logged_counts,
|
||||||
@ -556,8 +556,8 @@ class BASE_EXPORT BooleanHistogram : public LinearHistogram {
|
|||||||
static HistogramBase* FactoryGetInternal(std::string_view name,
|
static HistogramBase* FactoryGetInternal(std::string_view name,
|
||||||
int32_t flags);
|
int32_t flags);
|
||||||
|
|
||||||
BooleanHistogram(const char* name, const BucketRanges* ranges);
|
BooleanHistogram(DurableStringView durable_name, const BucketRanges* ranges);
|
||||||
BooleanHistogram(const char* name,
|
BooleanHistogram(DurableStringView durable_name,
|
||||||
const BucketRanges* ranges,
|
const BucketRanges* ranges,
|
||||||
const DelayedPersistentAllocation& counts,
|
const DelayedPersistentAllocation& counts,
|
||||||
const DelayedPersistentAllocation& logged_counts,
|
const DelayedPersistentAllocation& logged_counts,
|
||||||
@ -597,7 +597,7 @@ class BASE_EXPORT CustomHistogram : public Histogram {
|
|||||||
|
|
||||||
// Create a histogram using data in persistent storage.
|
// Create a histogram using data in persistent storage.
|
||||||
static std::unique_ptr<HistogramBase> PersistentCreate(
|
static std::unique_ptr<HistogramBase> PersistentCreate(
|
||||||
const char* name,
|
DurableStringView durable_name,
|
||||||
const BucketRanges* ranges,
|
const BucketRanges* ranges,
|
||||||
const DelayedPersistentAllocation& counts,
|
const DelayedPersistentAllocation& counts,
|
||||||
const DelayedPersistentAllocation& logged_counts,
|
const DelayedPersistentAllocation& logged_counts,
|
||||||
@ -618,9 +618,9 @@ class BASE_EXPORT CustomHistogram : public Histogram {
|
|||||||
protected:
|
protected:
|
||||||
class Factory;
|
class Factory;
|
||||||
|
|
||||||
CustomHistogram(const char* name, const BucketRanges* ranges);
|
CustomHistogram(DurableStringView durable_name, const BucketRanges* ranges);
|
||||||
|
|
||||||
CustomHistogram(const char* name,
|
CustomHistogram(DurableStringView durable_name,
|
||||||
const BucketRanges* ranges,
|
const BucketRanges* ranges,
|
||||||
const DelayedPersistentAllocation& counts,
|
const DelayedPersistentAllocation& counts,
|
||||||
const DelayedPersistentAllocation& logged_counts,
|
const DelayedPersistentAllocation& logged_counts,
|
||||||
|
@ -85,8 +85,12 @@ HistogramBase::CountAndBucketData& HistogramBase::CountAndBucketData::operator=(
|
|||||||
|
|
||||||
const HistogramBase::Sample32 HistogramBase::kSampleType_MAX = INT_MAX;
|
const HistogramBase::Sample32 HistogramBase::kSampleType_MAX = INT_MAX;
|
||||||
|
|
||||||
HistogramBase::HistogramBase(const char* name)
|
HistogramBase::HistogramBase(DurableStringView name)
|
||||||
: histogram_name_(name), flags_(kNoFlags) {}
|
: histogram_name_(name->data()),
|
||||||
|
histogram_name_length_(base::saturated_cast<uint16_t>(name->length())),
|
||||||
|
flags_(kNoFlags) {
|
||||||
|
DCHECK_LT(name->length(), static_cast<size_t>(UINT16_MAX));
|
||||||
|
}
|
||||||
|
|
||||||
HistogramBase::~HistogramBase() = default;
|
HistogramBase::~HistogramBase() = default;
|
||||||
|
|
||||||
@ -97,14 +101,21 @@ void HistogramBase::CheckName(std::string_view name) const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void HistogramBase::SetFlags(int32_t flags) {
|
void HistogramBase::SetFlags(int32_t flags) {
|
||||||
flags_.fetch_or(flags, std::memory_order_relaxed);
|
DCHECK_GE(flags, 0);
|
||||||
|
DCHECK_LE(flags, static_cast<int32_t>(UINT16_MAX));
|
||||||
|
CHECK_EQ(flags & ~0xFFFF, 0);
|
||||||
|
flags_.fetch_or(static_cast<uint16_t>(flags), std::memory_order_relaxed);
|
||||||
}
|
}
|
||||||
|
|
||||||
void HistogramBase::ClearFlags(int32_t flags) {
|
void HistogramBase::ClearFlags(int32_t flags) {
|
||||||
flags_.fetch_and(~flags, std::memory_order_relaxed);
|
DCHECK_GE(flags, 0);
|
||||||
|
DCHECK_LE(flags, static_cast<int32_t>(UINT16_MAX));
|
||||||
|
flags_.fetch_and(~static_cast<uint16_t>(flags), std::memory_order_relaxed);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool HistogramBase::HasFlags(int32_t flags) const {
|
bool HistogramBase::HasFlags(int32_t flags) const {
|
||||||
|
DCHECK_GE(flags, 0);
|
||||||
|
DCHECK_LE(flags, static_cast<int32_t>(UINT16_MAX));
|
||||||
// Check this->flags() is a superset of |flags|, i.e. every flag in |flags| is
|
// Check this->flags() is a superset of |flags|, i.e. every flag in |flags| is
|
||||||
// included.
|
// included.
|
||||||
return (this->flags() & flags) == flags;
|
return (this->flags() & flags) == flags;
|
||||||
@ -258,10 +269,12 @@ void HistogramBase::WriteAscii(std::string* output) const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// static
|
// static
|
||||||
char const* HistogramBase::GetPermanentName(std::string_view name) {
|
DurableStringView HistogramBase::GetPermanentName(std::string_view name) {
|
||||||
// A set of histogram names that provides the "permanent" lifetime required
|
// A set of histogram names that provides the "permanent" lifetime required by
|
||||||
// by histogram objects for those strings that are not already code constants
|
// histogram objects for those strings that are not already code constants or
|
||||||
// or held in persistent memory.
|
// held in persistent memory. The container used for `permanent_names` MUST
|
||||||
|
// support pointer-stability for its keys, due to small-string-optimization
|
||||||
|
// in std::string.
|
||||||
static base::NoDestructor<std::set<std::string, std::less<>>> permanent_names;
|
static base::NoDestructor<std::set<std::string, std::less<>>> permanent_names;
|
||||||
static base::NoDestructor<Lock> permanent_names_lock;
|
static base::NoDestructor<Lock> permanent_names_lock;
|
||||||
|
|
||||||
@ -270,7 +283,7 @@ char const* HistogramBase::GetPermanentName(std::string_view name) {
|
|||||||
if (it == permanent_names->end() || *it != name) {
|
if (it == permanent_names->end() || *it != name) {
|
||||||
it = permanent_names->emplace_hint(it, name);
|
it = permanent_names->emplace_hint(it, name);
|
||||||
}
|
}
|
||||||
return it->c_str();
|
return DurableStringView(*it);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace base
|
} // namespace base
|
||||||
|
@ -16,6 +16,7 @@
|
|||||||
|
|
||||||
#include "base/atomicops.h"
|
#include "base/atomicops.h"
|
||||||
#include "base/base_export.h"
|
#include "base/base_export.h"
|
||||||
|
#include "base/strings/durable_string_view.h"
|
||||||
#include "base/time/time.h"
|
#include "base/time/time.h"
|
||||||
#include "base/values.h"
|
#include "base/values.h"
|
||||||
|
|
||||||
@ -100,7 +101,7 @@ class BASE_EXPORT HistogramBase {
|
|||||||
|
|
||||||
static const Sample32 kSampleType_MAX; // INT_MAX
|
static const Sample32 kSampleType_MAX; // INT_MAX
|
||||||
|
|
||||||
enum Flags {
|
enum Flags : uint16_t {
|
||||||
kNoFlags = 0x0,
|
kNoFlags = 0x0,
|
||||||
|
|
||||||
// Histogram should be UMA uploaded.
|
// Histogram should be UMA uploaded.
|
||||||
@ -145,14 +146,16 @@ class BASE_EXPORT HistogramBase {
|
|||||||
|
|
||||||
// Construct the base histogram. The name is not copied; it's up to the
|
// Construct the base histogram. The name is not copied; it's up to the
|
||||||
// caller to ensure that it lives at least as long as this object.
|
// caller to ensure that it lives at least as long as this object.
|
||||||
explicit HistogramBase(const char* name);
|
explicit HistogramBase(DurableStringView name);
|
||||||
|
|
||||||
HistogramBase(const HistogramBase&) = delete;
|
HistogramBase(const HistogramBase&) = delete;
|
||||||
HistogramBase& operator=(const HistogramBase&) = delete;
|
HistogramBase& operator=(const HistogramBase&) = delete;
|
||||||
|
|
||||||
virtual ~HistogramBase();
|
virtual ~HistogramBase();
|
||||||
|
|
||||||
const char* histogram_name() const { return histogram_name_; }
|
std::string_view histogram_name() const {
|
||||||
|
return {histogram_name_, histogram_name_length_};
|
||||||
|
}
|
||||||
|
|
||||||
// Compares |name| to the histogram name and triggers a DCHECK if they do not
|
// Compares |name| to the histogram name and triggers a DCHECK if they do not
|
||||||
// match. This is a helper function used by histogram macros, which results in
|
// match. This is a helper function used by histogram macros, which results in
|
||||||
@ -339,25 +342,28 @@ class BASE_EXPORT HistogramBase {
|
|||||||
// them passing |sample| as the parameter.
|
// them passing |sample| as the parameter.
|
||||||
void FindAndRunCallbacks(Sample32 sample) const;
|
void FindAndRunCallbacks(Sample32 sample) const;
|
||||||
|
|
||||||
// Gets a permanent string that can be used for histogram objects when the
|
// Gets a view to a permanent string that can be used for histogram objects
|
||||||
// original is not a code constant or held in persistent memory.
|
// when the original string is not a code constant or held in persistent
|
||||||
static const char* GetPermanentName(std::string_view name);
|
// memory.
|
||||||
|
static DurableStringView GetPermanentName(std::string_view name);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
friend class HistogramBaseTest;
|
friend class HistogramBaseTest;
|
||||||
|
friend class HistogramThreadsafeTest;
|
||||||
|
|
||||||
// A pointer to permanent storage where the histogram name is held. This can
|
// A pointer to permanent storage where the histogram name is held. This can
|
||||||
// be code space or the output of GetPermanentName() or any other storage
|
// be code space or the output of GetPermanentName() or any other storage
|
||||||
// that is known to never change. This is not std::string_view because (a)
|
// that is expected to never be deallocated or modified.
|
||||||
// char* is 1/2 the size and (b) std::string_view transparently casts from
|
|
||||||
// std::string which can easily lead to a pointer to non-permanent space. For
|
|
||||||
// persistent histograms, this will simply point into the persistent memory
|
|
||||||
// segment, thus avoiding duplication. For heap histograms, the
|
|
||||||
// GetPermanentName method will create the necessary copy.
|
|
||||||
const char* const histogram_name_;
|
const char* const histogram_name_;
|
||||||
|
|
||||||
|
// The length of the string pointed to by `histogram_name_`. This is stored
|
||||||
|
// to avoid having to recalculate the length every time `histogram_name_` is
|
||||||
|
// used and to avoid reading beyond the strings alloc in the event of memory
|
||||||
|
// tampering or corruption.
|
||||||
|
const uint16_t histogram_name_length_;
|
||||||
|
|
||||||
// Additional information about the histogram.
|
// Additional information about the histogram.
|
||||||
std::atomic<int32_t> flags_{0};
|
std::atomic<uint16_t> flags_{0};
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace base
|
} // namespace base
|
||||||
|
@ -60,7 +60,7 @@ TEST_F(HistogramBaseTest, DeserializeHistogram) {
|
|||||||
deserialized = DeserializeHistogramInfo(&iter2);
|
deserialized = DeserializeHistogramInfo(&iter2);
|
||||||
EXPECT_TRUE(deserialized);
|
EXPECT_TRUE(deserialized);
|
||||||
EXPECT_NE(histogram, deserialized);
|
EXPECT_NE(histogram, deserialized);
|
||||||
EXPECT_STREQ("TestHistogram", deserialized->histogram_name());
|
EXPECT_EQ("TestHistogram", deserialized->histogram_name());
|
||||||
EXPECT_TRUE(deserialized->HasConstructionArguments(1, 1000, 10));
|
EXPECT_TRUE(deserialized->HasConstructionArguments(1, 1000, 10));
|
||||||
|
|
||||||
// kIPCSerializationSourceFlag will be cleared.
|
// kIPCSerializationSourceFlag will be cleared.
|
||||||
@ -84,7 +84,7 @@ TEST_F(HistogramBaseTest, DeserializeLinearHistogram) {
|
|||||||
deserialized = DeserializeHistogramInfo(&iter2);
|
deserialized = DeserializeHistogramInfo(&iter2);
|
||||||
EXPECT_TRUE(deserialized);
|
EXPECT_TRUE(deserialized);
|
||||||
EXPECT_NE(histogram, deserialized);
|
EXPECT_NE(histogram, deserialized);
|
||||||
EXPECT_STREQ("TestHistogram", deserialized->histogram_name());
|
EXPECT_EQ("TestHistogram", deserialized->histogram_name());
|
||||||
EXPECT_TRUE(deserialized->HasConstructionArguments(1, 1000, 10));
|
EXPECT_TRUE(deserialized->HasConstructionArguments(1, 1000, 10));
|
||||||
EXPECT_EQ(0, deserialized->flags());
|
EXPECT_EQ(0, deserialized->flags());
|
||||||
}
|
}
|
||||||
@ -106,7 +106,7 @@ TEST_F(HistogramBaseTest, DeserializeBooleanHistogram) {
|
|||||||
deserialized = DeserializeHistogramInfo(&iter2);
|
deserialized = DeserializeHistogramInfo(&iter2);
|
||||||
EXPECT_TRUE(deserialized);
|
EXPECT_TRUE(deserialized);
|
||||||
EXPECT_NE(histogram, deserialized);
|
EXPECT_NE(histogram, deserialized);
|
||||||
EXPECT_STREQ("TestHistogram", deserialized->histogram_name());
|
EXPECT_EQ("TestHistogram", deserialized->histogram_name());
|
||||||
EXPECT_TRUE(deserialized->HasConstructionArguments(1, 2, 3));
|
EXPECT_TRUE(deserialized->HasConstructionArguments(1, 2, 3));
|
||||||
EXPECT_EQ(0, deserialized->flags());
|
EXPECT_EQ(0, deserialized->flags());
|
||||||
}
|
}
|
||||||
@ -133,7 +133,7 @@ TEST_F(HistogramBaseTest, DeserializeCustomHistogram) {
|
|||||||
deserialized = DeserializeHistogramInfo(&iter2);
|
deserialized = DeserializeHistogramInfo(&iter2);
|
||||||
EXPECT_TRUE(deserialized);
|
EXPECT_TRUE(deserialized);
|
||||||
EXPECT_NE(histogram, deserialized);
|
EXPECT_NE(histogram, deserialized);
|
||||||
EXPECT_STREQ("TestHistogram", deserialized->histogram_name());
|
EXPECT_EQ("TestHistogram", deserialized->histogram_name());
|
||||||
EXPECT_TRUE(deserialized->HasConstructionArguments(5, 13, 4));
|
EXPECT_TRUE(deserialized->HasConstructionArguments(5, 13, 4));
|
||||||
EXPECT_EQ(0, deserialized->flags());
|
EXPECT_EQ(0, deserialized->flags());
|
||||||
}
|
}
|
||||||
@ -155,7 +155,7 @@ TEST_F(HistogramBaseTest, DeserializeSparseHistogram) {
|
|||||||
deserialized = DeserializeHistogramInfo(&iter2);
|
deserialized = DeserializeHistogramInfo(&iter2);
|
||||||
EXPECT_TRUE(deserialized);
|
EXPECT_TRUE(deserialized);
|
||||||
EXPECT_NE(histogram, deserialized);
|
EXPECT_NE(histogram, deserialized);
|
||||||
EXPECT_STREQ("TestHistogram", deserialized->histogram_name());
|
EXPECT_EQ("TestHistogram", deserialized->histogram_name());
|
||||||
EXPECT_EQ(0, deserialized->flags());
|
EXPECT_EQ(0, deserialized->flags());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -9,6 +9,7 @@
|
|||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "base/containers/contains.h"
|
#include "base/containers/contains.h"
|
||||||
|
#include "base/containers/map_util.h"
|
||||||
#include "base/memory/raw_ptr.h"
|
#include "base/memory/raw_ptr.h"
|
||||||
#include "base/metrics/histogram_delta_serialization.h"
|
#include "base/metrics/histogram_delta_serialization.h"
|
||||||
#include "base/metrics/histogram_functions.h"
|
#include "base/metrics/histogram_functions.h"
|
||||||
@ -48,7 +49,8 @@ class HistogramFlattenerDeltaRecorder : public HistogramFlattener {
|
|||||||
CHECK(!Contains(recorded_delta_histogram_sum_, histogram.histogram_name()));
|
CHECK(!Contains(recorded_delta_histogram_sum_, histogram.histogram_name()));
|
||||||
// Keep pointer to snapshot for testing. This really isn't ideal but the
|
// Keep pointer to snapshot for testing. This really isn't ideal but the
|
||||||
// snapshot-manager keeps the snapshot alive until it's "forgotten".
|
// snapshot-manager keeps the snapshot alive until it's "forgotten".
|
||||||
recorded_delta_histogram_sum_[histogram.histogram_name()] = snapshot.sum();
|
InsertOrAssign(recorded_delta_histogram_sum_, histogram.histogram_name(),
|
||||||
|
snapshot.sum());
|
||||||
}
|
}
|
||||||
|
|
||||||
void Reset() {
|
void Reset() {
|
||||||
@ -69,7 +71,7 @@ class HistogramFlattenerDeltaRecorder : public HistogramFlattener {
|
|||||||
private:
|
private:
|
||||||
std::vector<raw_ptr<const HistogramBase, VectorExperimental>>
|
std::vector<raw_ptr<const HistogramBase, VectorExperimental>>
|
||||||
recorded_delta_histograms_;
|
recorded_delta_histograms_;
|
||||||
std::map<std::string, int64_t> recorded_delta_histogram_sum_;
|
std::map<std::string, int64_t, std::less<>> recorded_delta_histogram_sum_;
|
||||||
};
|
};
|
||||||
|
|
||||||
class HistogramSnapshotManagerTest : public testing::Test {
|
class HistogramSnapshotManagerTest : public testing::Test {
|
||||||
|
@ -9,11 +9,11 @@
|
|||||||
|
|
||||||
#include <array>
|
#include <array>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <set>
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "base/atomicops.h"
|
#include "base/atomicops.h"
|
||||||
|
#include "base/containers/contains.h"
|
||||||
#include "base/containers/span.h"
|
#include "base/containers/span.h"
|
||||||
#include "base/memory/raw_span.h"
|
#include "base/memory/raw_span.h"
|
||||||
#include "base/metrics/bucket_ranges.h"
|
#include "base/metrics/bucket_ranges.h"
|
||||||
@ -31,16 +31,6 @@ namespace base {
|
|||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
char const* GetPermanentName(const std::string& name) {
|
|
||||||
// A set of histogram names that provides the "permanent" lifetime required
|
|
||||||
// by histogram objects for those strings that are not already code constants
|
|
||||||
// or held in persistent memory.
|
|
||||||
static base::NoDestructor<std::set<std::string>> permanent_names;
|
|
||||||
|
|
||||||
auto result = permanent_names->insert(name);
|
|
||||||
return result.first->c_str();
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t GetBucketIndex(HistogramBase::Sample32 value, const BucketRanges* ranges) {
|
size_t GetBucketIndex(HistogramBase::Sample32 value, const BucketRanges* ranges) {
|
||||||
size_t bucket_count = ranges->bucket_count();
|
size_t bucket_count = ranges->bucket_count();
|
||||||
EXPECT_GE(bucket_count, 1U);
|
EXPECT_GE(bucket_count, 1U);
|
||||||
@ -235,15 +225,15 @@ class HistogramThreadsafeTest : public testing::Test {
|
|||||||
// during the test.
|
// during the test.
|
||||||
std::string local_heap_histogram_name =
|
std::string local_heap_histogram_name =
|
||||||
StringPrintf("LocalHeapNumericHistogram%zu", suffix);
|
StringPrintf("LocalHeapNumericHistogram%zu", suffix);
|
||||||
auto& local_heap_histogram = histograms_.emplace_back(
|
auto& local_heap_histogram = histograms_.emplace_back(new Histogram(
|
||||||
new Histogram(GetPermanentName(local_heap_histogram_name),
|
HistogramBase::GetPermanentName(local_heap_histogram_name),
|
||||||
numeric_histogram->bucket_ranges()));
|
numeric_histogram->bucket_ranges()));
|
||||||
histograms.push_back(local_heap_histogram.get());
|
histograms.push_back(local_heap_histogram.get());
|
||||||
std::string local_heap_sparse_histogram_name =
|
std::string local_heap_sparse_histogram_name =
|
||||||
StringPrintf("LocalHeapSparseHistogram%zu", suffix);
|
StringPrintf("LocalHeapSparseHistogram%zu", suffix);
|
||||||
auto& local_heap_sparse_histogram =
|
auto& local_heap_sparse_histogram =
|
||||||
histograms_.emplace_back(new SparseHistogram(
|
histograms_.emplace_back(new SparseHistogram(
|
||||||
GetPermanentName(local_heap_sparse_histogram_name)));
|
HistogramBase::GetPermanentName(local_heap_sparse_histogram_name)));
|
||||||
histograms.push_back(local_heap_sparse_histogram.get());
|
histograms.push_back(local_heap_sparse_histogram.get());
|
||||||
|
|
||||||
// Furthermore, create two additional *different* histogram objects that
|
// Furthermore, create two additional *different* histogram objects that
|
||||||
@ -446,7 +436,7 @@ TEST_F(HistogramThreadsafeTest, SnapshotDeltaThreadsafe) {
|
|||||||
// a normal histogram, once as a simulation of a subprocess histogram, and
|
// a normal histogram, once as a simulation of a subprocess histogram, and
|
||||||
// once as a duplicate histogram created from the same allocator.
|
// once as a duplicate histogram created from the same allocator.
|
||||||
size_t expected_logged_samples_count = kNumThreads * kNumEmissions;
|
size_t expected_logged_samples_count = kNumThreads * kNumEmissions;
|
||||||
if (!strstr(histogram->histogram_name(), "LocalHeap")) {
|
if (!Contains(histogram->histogram_name(), "LocalHeap")) {
|
||||||
expected_logged_samples_count *= 3;
|
expected_logged_samples_count *= 3;
|
||||||
}
|
}
|
||||||
ASSERT_EQ(static_cast<size_t>(logged_samples->TotalCount()),
|
ASSERT_EQ(static_cast<size_t>(logged_samples->TotalCount()),
|
||||||
|
@ -324,14 +324,17 @@ std::unique_ptr<HistogramBase> PersistentHistogramAllocator::GetHistogram(
|
|||||||
PersistentHistogramData* data =
|
PersistentHistogramData* data =
|
||||||
memory_allocator_->GetAsObject<PersistentHistogramData>(ref, &alloc_size);
|
memory_allocator_->GetAsObject<PersistentHistogramData>(ref, &alloc_size);
|
||||||
|
|
||||||
|
// Get a bounded view of the metric name. Note that this is a durable but
|
||||||
|
// volatile view. I.e., the data lives in the persistent shared memory region
|
||||||
|
// and will not be freed, but the contents of the view may change at any time.
|
||||||
// Checks data for nullptr; `metric_name` not empty means data is not nullptr.
|
// Checks data for nullptr; `metric_name` not empty means data is not nullptr.
|
||||||
std::string_view metric_name = PersistentMemoryAllocator::StringViewAt(
|
DurableStringView durable_metric_name(PersistentMemoryAllocator::StringViewAt(
|
||||||
data, offsetof(PersistentHistogramData, name), alloc_size);
|
data, offsetof(PersistentHistogramData, name), alloc_size));
|
||||||
|
|
||||||
// Check that metadata is reasonable: metric_name is non-empty,
|
// Check that metadata is reasonable: metric_name is non-empty,
|
||||||
// ID fields have been loaded with a hash of the name (0 is considered
|
// ID fields have been loaded with a hash of the name (0 is considered
|
||||||
// unset/invalid).
|
// unset/invalid).
|
||||||
if (metric_name.empty() ||
|
if (durable_metric_name->empty() ||
|
||||||
UNSAFE_TODO(reinterpret_cast<const char*>(data)[alloc_size - 1]) !=
|
UNSAFE_TODO(reinterpret_cast<const char*>(data)[alloc_size - 1]) !=
|
||||||
'\0' ||
|
'\0' ||
|
||||||
data->samples_metadata.id == 0 || data->logged_metadata.id == 0 ||
|
data->samples_metadata.id == 0 || data->logged_metadata.id == 0 ||
|
||||||
@ -342,10 +345,10 @@ std::unique_ptr<HistogramBase> PersistentHistogramAllocator::GetHistogram(
|
|||||||
// could just verify the name length based on the overall alloc length,
|
// could just verify the name length based on the overall alloc length,
|
||||||
// but that doesn't work because the allocated block may have been
|
// but that doesn't work because the allocated block may have been
|
||||||
// aligned to the next boundary value.
|
// aligned to the next boundary value.
|
||||||
HashMetricName(metric_name) != data->samples_metadata.id) {
|
HashMetricName(*durable_metric_name) != data->samples_metadata.id) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
return CreateHistogram(data);
|
return CreateHistogram(data, durable_metric_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<HistogramBase> PersistentHistogramAllocator::AllocateHistogram(
|
std::unique_ptr<HistogramBase> PersistentHistogramAllocator::AllocateHistogram(
|
||||||
@ -456,7 +459,10 @@ std::unique_ptr<HistogramBase> PersistentHistogramAllocator::AllocateHistogram(
|
|||||||
// using what is already known above but avoids duplicating the switch
|
// using what is already known above but avoids duplicating the switch
|
||||||
// statement here and serves as a double-check that everything is
|
// statement here and serves as a double-check that everything is
|
||||||
// correct before commiting the new histogram to persistent space.
|
// correct before commiting the new histogram to persistent space.
|
||||||
std::unique_ptr<HistogramBase> histogram = CreateHistogram(histogram_data);
|
DurableStringView durable_name(
|
||||||
|
std::string_view(histogram_data->name, name.size()));
|
||||||
|
std::unique_ptr<HistogramBase> histogram =
|
||||||
|
CreateHistogram(histogram_data, durable_name);
|
||||||
DCHECK(histogram);
|
DCHECK(histogram);
|
||||||
DCHECK_NE(0U, histogram_data->samples_metadata.id);
|
DCHECK_NE(0U, histogram_data->samples_metadata.id);
|
||||||
DCHECK_NE(0U, histogram_data->logged_metadata.id);
|
DCHECK_NE(0U, histogram_data->logged_metadata.id);
|
||||||
@ -566,15 +572,20 @@ void PersistentHistogramAllocator::ClearLastCreatedReferenceForTesting() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<HistogramBase> PersistentHistogramAllocator::CreateHistogram(
|
std::unique_ptr<HistogramBase> PersistentHistogramAllocator::CreateHistogram(
|
||||||
PersistentHistogramData* histogram_data_ptr) {
|
PersistentHistogramData* histogram_data_ptr,
|
||||||
|
DurableStringView durable_name) {
|
||||||
if (!histogram_data_ptr) {
|
if (!histogram_data_ptr) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// The durable name is expected to be hanging off the end of the histogram
|
||||||
|
// data (which we expect was allocated by the persistent memory allocator).
|
||||||
|
DCHECK_EQ(durable_name->data(), histogram_data_ptr->name);
|
||||||
|
|
||||||
// Sparse histograms are quite different so handle them as a special case.
|
// Sparse histograms are quite different so handle them as a special case.
|
||||||
if (histogram_data_ptr->histogram_type == SPARSE_HISTOGRAM) {
|
if (histogram_data_ptr->histogram_type == SPARSE_HISTOGRAM) {
|
||||||
std::unique_ptr<HistogramBase> histogram =
|
std::unique_ptr<HistogramBase> histogram =
|
||||||
SparseHistogram::PersistentCreate(this, histogram_data_ptr->name,
|
SparseHistogram::PersistentCreate(this, durable_name,
|
||||||
&histogram_data_ptr->samples_metadata,
|
&histogram_data_ptr->samples_metadata,
|
||||||
&histogram_data_ptr->logged_metadata);
|
&histogram_data_ptr->logged_metadata);
|
||||||
DCHECK(histogram);
|
DCHECK(histogram);
|
||||||
@ -662,33 +673,32 @@ std::unique_ptr<HistogramBase> PersistentHistogramAllocator::CreateHistogram(
|
|||||||
kTypeIdCountsArray, counts_bytes, counts_bytes / 2);
|
kTypeIdCountsArray, counts_bytes, counts_bytes / 2);
|
||||||
|
|
||||||
// Create the right type of histogram.
|
// Create the right type of histogram.
|
||||||
const char* name = histogram_data_ptr->name;
|
|
||||||
std::unique_ptr<HistogramBase> histogram;
|
std::unique_ptr<HistogramBase> histogram;
|
||||||
switch (histogram_type) {
|
switch (histogram_type) {
|
||||||
case HISTOGRAM:
|
case HISTOGRAM:
|
||||||
histogram =
|
histogram = Histogram::PersistentCreate(
|
||||||
Histogram::PersistentCreate(name, ranges, counts_data, logged_data,
|
durable_name, ranges, counts_data, logged_data,
|
||||||
&histogram_data_ptr->samples_metadata,
|
&histogram_data_ptr->samples_metadata,
|
||||||
&histogram_data_ptr->logged_metadata);
|
&histogram_data_ptr->logged_metadata);
|
||||||
DCHECK(histogram);
|
DCHECK(histogram);
|
||||||
break;
|
break;
|
||||||
case LINEAR_HISTOGRAM:
|
case LINEAR_HISTOGRAM:
|
||||||
histogram = LinearHistogram::PersistentCreate(
|
histogram = LinearHistogram::PersistentCreate(
|
||||||
name, ranges, counts_data, logged_data,
|
durable_name, ranges, counts_data, logged_data,
|
||||||
&histogram_data_ptr->samples_metadata,
|
&histogram_data_ptr->samples_metadata,
|
||||||
&histogram_data_ptr->logged_metadata);
|
&histogram_data_ptr->logged_metadata);
|
||||||
DCHECK(histogram);
|
DCHECK(histogram);
|
||||||
break;
|
break;
|
||||||
case BOOLEAN_HISTOGRAM:
|
case BOOLEAN_HISTOGRAM:
|
||||||
histogram = BooleanHistogram::PersistentCreate(
|
histogram = BooleanHistogram::PersistentCreate(
|
||||||
name, ranges, counts_data, logged_data,
|
durable_name, ranges, counts_data, logged_data,
|
||||||
&histogram_data_ptr->samples_metadata,
|
&histogram_data_ptr->samples_metadata,
|
||||||
&histogram_data_ptr->logged_metadata);
|
&histogram_data_ptr->logged_metadata);
|
||||||
DCHECK(histogram);
|
DCHECK(histogram);
|
||||||
break;
|
break;
|
||||||
case CUSTOM_HISTOGRAM:
|
case CUSTOM_HISTOGRAM:
|
||||||
histogram = CustomHistogram::PersistentCreate(
|
histogram = CustomHistogram::PersistentCreate(
|
||||||
name, ranges, counts_data, logged_data,
|
durable_name, ranges, counts_data, logged_data,
|
||||||
&histogram_data_ptr->samples_metadata,
|
&histogram_data_ptr->samples_metadata,
|
||||||
&histogram_data_ptr->logged_metadata);
|
&histogram_data_ptr->logged_metadata);
|
||||||
DCHECK(histogram);
|
DCHECK(histogram);
|
||||||
|
@ -334,8 +334,13 @@ class BASE_EXPORT PersistentHistogramAllocator {
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
// Create a histogram based on saved (persistent) information about it.
|
// Create a histogram based on saved (persistent) information about it.
|
||||||
|
// `histogram_data_ptr` refers to a variable length structure, ending
|
||||||
|
// with the histogram name. `durable_name` must be a durable string view
|
||||||
|
// starting at `histogram_data_ptr->name` and with some length bounded by the
|
||||||
|
// `alloc_size` returned from the `memory_allocator`.
|
||||||
std::unique_ptr<HistogramBase> CreateHistogram(
|
std::unique_ptr<HistogramBase> CreateHistogram(
|
||||||
PersistentHistogramData* histogram_data_ptr);
|
PersistentHistogramData* histogram_data_ptr,
|
||||||
|
DurableStringView durable_name);
|
||||||
|
|
||||||
// Gets or creates an object in the global StatisticsRecorder matching
|
// Gets or creates an object in the global StatisticsRecorder matching
|
||||||
// the `histogram` passed. Null is returned if one was not found and
|
// the `histogram` passed. Null is returned if one was not found and
|
||||||
|
@ -686,7 +686,7 @@ TEST_F(PersistentHistogramAllocatorTest, MovePersistentFile) {
|
|||||||
std::unique_ptr<HistogramBase> histogram;
|
std::unique_ptr<HistogramBase> histogram;
|
||||||
bool found_histogram = false;
|
bool found_histogram = false;
|
||||||
while ((histogram = it.GetNext()) != nullptr) {
|
while ((histogram = it.GetNext()) != nullptr) {
|
||||||
if (strcmp(kHistogramName, histogram->histogram_name()) == 0) {
|
if (histogram->histogram_name() == kHistogramName) {
|
||||||
found_histogram = true;
|
found_histogram = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -89,10 +89,11 @@ HistogramBase* SparseHistogram::FactoryGet(std::string_view name,
|
|||||||
// static
|
// static
|
||||||
std::unique_ptr<HistogramBase> SparseHistogram::PersistentCreate(
|
std::unique_ptr<HistogramBase> SparseHistogram::PersistentCreate(
|
||||||
PersistentHistogramAllocator* allocator,
|
PersistentHistogramAllocator* allocator,
|
||||||
const char* name,
|
DurableStringView durable_name,
|
||||||
HistogramSamples::Metadata* meta,
|
HistogramSamples::Metadata* meta,
|
||||||
HistogramSamples::Metadata* logged_meta) {
|
HistogramSamples::Metadata* logged_meta) {
|
||||||
return WrapUnique(new SparseHistogram(allocator, name, meta, logged_meta));
|
return WrapUnique(
|
||||||
|
new SparseHistogram(allocator, durable_name, meta, logged_meta));
|
||||||
}
|
}
|
||||||
|
|
||||||
SparseHistogram::~SparseHistogram() = default;
|
SparseHistogram::~SparseHistogram() = default;
|
||||||
@ -200,16 +201,16 @@ void SparseHistogram::SerializeInfoImpl(Pickle* pickle) const {
|
|||||||
pickle->WriteInt(flags());
|
pickle->WriteInt(flags());
|
||||||
}
|
}
|
||||||
|
|
||||||
SparseHistogram::SparseHistogram(const char* name)
|
SparseHistogram::SparseHistogram(DurableStringView durable_name)
|
||||||
: HistogramBase(name),
|
: HistogramBase(durable_name),
|
||||||
unlogged_samples_(new SampleMap(HashMetricName(name))),
|
unlogged_samples_(new SampleMap(HashMetricName(*durable_name))),
|
||||||
logged_samples_(new SampleMap(unlogged_samples_->id())) {}
|
logged_samples_(new SampleMap(unlogged_samples_->id())) {}
|
||||||
|
|
||||||
SparseHistogram::SparseHistogram(PersistentHistogramAllocator* allocator,
|
SparseHistogram::SparseHistogram(PersistentHistogramAllocator* allocator,
|
||||||
const char* name,
|
DurableStringView durable_name,
|
||||||
HistogramSamples::Metadata* meta,
|
HistogramSamples::Metadata* meta,
|
||||||
HistogramSamples::Metadata* logged_meta)
|
HistogramSamples::Metadata* logged_meta)
|
||||||
: HistogramBase(name),
|
: HistogramBase(durable_name),
|
||||||
// While other histogram types maintain a static vector of values with
|
// While other histogram types maintain a static vector of values with
|
||||||
// sufficient space for both "active" and "logged" samples, with each
|
// sufficient space for both "active" and "logged" samples, with each
|
||||||
// SampleVector being given the appropriate half, sparse histograms
|
// SampleVector being given the appropriate half, sparse histograms
|
||||||
@ -220,8 +221,9 @@ SparseHistogram::SparseHistogram(PersistentHistogramAllocator* allocator,
|
|||||||
// "active" samples use, for convenience purposes, an ID matching
|
// "active" samples use, for convenience purposes, an ID matching
|
||||||
// that of the histogram while the "logged" samples use that number
|
// that of the histogram while the "logged" samples use that number
|
||||||
// plus 1.
|
// plus 1.
|
||||||
unlogged_samples_(
|
unlogged_samples_(new PersistentSampleMap(HashMetricName(*durable_name),
|
||||||
new PersistentSampleMap(HashMetricName(name), allocator, meta)),
|
allocator,
|
||||||
|
meta)),
|
||||||
logged_samples_(new PersistentSampleMap(unlogged_samples_->id() + 1,
|
logged_samples_(new PersistentSampleMap(unlogged_samples_->id() + 1,
|
||||||
allocator,
|
allocator,
|
||||||
logged_meta)) {}
|
logged_meta)) {}
|
||||||
|
@ -35,7 +35,7 @@ class BASE_EXPORT SparseHistogram : public HistogramBase {
|
|||||||
// live longer than the created sparse histogram.
|
// live longer than the created sparse histogram.
|
||||||
static std::unique_ptr<HistogramBase> PersistentCreate(
|
static std::unique_ptr<HistogramBase> PersistentCreate(
|
||||||
PersistentHistogramAllocator* allocator,
|
PersistentHistogramAllocator* allocator,
|
||||||
const char* name,
|
DurableStringView name,
|
||||||
HistogramSamples::Metadata* meta,
|
HistogramSamples::Metadata* meta,
|
||||||
HistogramSamples::Metadata* logged_meta);
|
HistogramSamples::Metadata* logged_meta);
|
||||||
|
|
||||||
@ -67,10 +67,10 @@ class BASE_EXPORT SparseHistogram : public HistogramBase {
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
// Clients should always use FactoryGet to create SparseHistogram.
|
// Clients should always use FactoryGet to create SparseHistogram.
|
||||||
explicit SparseHistogram(const char* name);
|
explicit SparseHistogram(DurableStringView name);
|
||||||
|
|
||||||
SparseHistogram(PersistentHistogramAllocator* allocator,
|
SparseHistogram(PersistentHistogramAllocator* allocator,
|
||||||
const char* name,
|
DurableStringView name,
|
||||||
HistogramSamples::Metadata* meta,
|
HistogramSamples::Metadata* meta,
|
||||||
HistogramSamples::Metadata* logged_meta);
|
HistogramSamples::Metadata* logged_meta);
|
||||||
|
|
||||||
|
@ -78,10 +78,12 @@ class SparseHistogramTest : public testing::TestWithParam<bool> {
|
|||||||
GlobalHistogramAllocator::ReleaseForTesting();
|
GlobalHistogramAllocator::ReleaseForTesting();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<SparseHistogram> NewSparseHistogram(const char* name) {
|
template <size_t N>
|
||||||
|
std::unique_ptr<SparseHistogram> NewSparseHistogram(const char (&name)[N]) {
|
||||||
// std::make_unique can't access protected ctor so do it manually. This
|
// std::make_unique can't access protected ctor so do it manually. This
|
||||||
// test class is a friend so can access it.
|
// test class is a friend so can access it.
|
||||||
return std::unique_ptr<SparseHistogram>(new SparseHistogram(name));
|
return std::unique_ptr<SparseHistogram>(
|
||||||
|
new SparseHistogram(DurableStringView(std::string_view(name, N - 1))));
|
||||||
}
|
}
|
||||||
|
|
||||||
CountAndBucketData GetCountAndBucketData(SparseHistogram* histogram) {
|
CountAndBucketData GetCountAndBucketData(SparseHistogram* histogram) {
|
||||||
@ -268,7 +270,7 @@ TEST_P(SparseHistogramTest, MacroBasicTest) {
|
|||||||
const HistogramBase* const sparse_histogram = histograms[0];
|
const HistogramBase* const sparse_histogram = histograms[0];
|
||||||
|
|
||||||
EXPECT_EQ(SPARSE_HISTOGRAM, sparse_histogram->GetHistogramType());
|
EXPECT_EQ(SPARSE_HISTOGRAM, sparse_histogram->GetHistogramType());
|
||||||
EXPECT_STREQ("Sparse", sparse_histogram->histogram_name());
|
EXPECT_EQ("Sparse", sparse_histogram->histogram_name());
|
||||||
EXPECT_EQ(
|
EXPECT_EQ(
|
||||||
HistogramBase::kUmaTargetedHistogramFlag |
|
HistogramBase::kUmaTargetedHistogramFlag |
|
||||||
(use_persistent_histogram_allocator_ ? HistogramBase::kIsPersistent
|
(use_persistent_histogram_allocator_ ? HistogramBase::kIsPersistent
|
||||||
@ -292,8 +294,8 @@ TEST_P(SparseHistogramTest, MacroInLoopTest) {
|
|||||||
const StatisticsRecorder::Histograms histograms =
|
const StatisticsRecorder::Histograms histograms =
|
||||||
StatisticsRecorder::Sort(StatisticsRecorder::GetHistograms());
|
StatisticsRecorder::Sort(StatisticsRecorder::GetHistograms());
|
||||||
ASSERT_THAT(histograms, testing::SizeIs(2));
|
ASSERT_THAT(histograms, testing::SizeIs(2));
|
||||||
EXPECT_STREQ(histograms[0]->histogram_name(), "Sparse0");
|
EXPECT_EQ(histograms[0]->histogram_name(), "Sparse0");
|
||||||
EXPECT_STREQ(histograms[1]->histogram_name(), "Sparse1");
|
EXPECT_EQ(histograms[1]->histogram_name(), "Sparse1");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_P(SparseHistogramTest, Serialize) {
|
TEST_P(SparseHistogramTest, Serialize) {
|
||||||
|
@ -34,7 +34,7 @@ namespace {
|
|||||||
|
|
||||||
bool HistogramNameLesser(const base::HistogramBase* a,
|
bool HistogramNameLesser(const base::HistogramBase* a,
|
||||||
const base::HistogramBase* b) {
|
const base::HistogramBase* b) {
|
||||||
return strcmp(a->histogram_name(), b->histogram_name()) < 0;
|
return a->histogram_name() < b->histogram_name();
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
@ -56,7 +56,7 @@ std::atomic<StatisticsRecorder::GlobalSampleCallback>
|
|||||||
StatisticsRecorder::global_sample_callback_{nullptr};
|
StatisticsRecorder::global_sample_callback_{nullptr};
|
||||||
|
|
||||||
StatisticsRecorder::ScopedHistogramSampleObserver::
|
StatisticsRecorder::ScopedHistogramSampleObserver::
|
||||||
ScopedHistogramSampleObserver(const std::string& name,
|
ScopedHistogramSampleObserver(std::string_view name,
|
||||||
OnSampleCallback callback)
|
OnSampleCallback callback)
|
||||||
: histogram_name_(name), callback_(callback) {
|
: histogram_name_(name), callback_(callback) {
|
||||||
StatisticsRecorder::AddHistogramSampleObserver(histogram_name_, this);
|
StatisticsRecorder::AddHistogramSampleObserver(histogram_name_, this);
|
||||||
@ -68,7 +68,7 @@ StatisticsRecorder::ScopedHistogramSampleObserver::
|
|||||||
}
|
}
|
||||||
|
|
||||||
void StatisticsRecorder::ScopedHistogramSampleObserver::RunCallback(
|
void StatisticsRecorder::ScopedHistogramSampleObserver::RunCallback(
|
||||||
const char* histogram_name,
|
std::string_view histogram_name,
|
||||||
uint64_t name_hash,
|
uint64_t name_hash,
|
||||||
HistogramBase::Sample32 sample) {
|
HistogramBase::Sample32 sample) {
|
||||||
callback_.Run(histogram_name, name_hash, sample);
|
callback_.Run(histogram_name, name_hash, sample);
|
||||||
@ -144,8 +144,7 @@ HistogramBase* StatisticsRecorder::RegisterOrDeleteDuplicate(
|
|||||||
// you are unluckily a victim of a hash collision. For now, the best solution
|
// you are unluckily a victim of a hash collision. For now, the best solution
|
||||||
// is to rename the histogram. Reach out to chrome-metrics-team@google.com if
|
// is to rename the histogram. Reach out to chrome-metrics-team@google.com if
|
||||||
// you are unsure!
|
// you are unsure!
|
||||||
DCHECK_EQ(strcmp(histogram->histogram_name(), registered->histogram_name()),
|
DCHECK_EQ(histogram->histogram_name(), registered->histogram_name())
|
||||||
0)
|
|
||||||
<< "Histogram name hash collision between " << histogram->histogram_name()
|
<< "Histogram name hash collision between " << histogram->histogram_name()
|
||||||
<< " and " << registered->histogram_name() << " (hash = " << hash << ")";
|
<< " and " << registered->histogram_name() << " (hash = " << hash << ")";
|
||||||
|
|
||||||
@ -385,7 +384,7 @@ void StatisticsRecorder::RemoveHistogramSampleObserver(
|
|||||||
// static
|
// static
|
||||||
void StatisticsRecorder::FindAndRunHistogramCallbacks(
|
void StatisticsRecorder::FindAndRunHistogramCallbacks(
|
||||||
base::PassKey<HistogramBase>,
|
base::PassKey<HistogramBase>,
|
||||||
const char* histogram_name,
|
std::string_view histogram_name,
|
||||||
uint64_t name_hash,
|
uint64_t name_hash,
|
||||||
HistogramBase::Sample32 sample) {
|
HistogramBase::Sample32 sample) {
|
||||||
DCHECK_EQ(name_hash, HashMetricName(histogram_name));
|
DCHECK_EQ(name_hash, HashMetricName(histogram_name));
|
||||||
@ -530,26 +529,26 @@ StatisticsRecorder::Histograms StatisticsRecorder::Sort(Histograms histograms) {
|
|||||||
// static
|
// static
|
||||||
StatisticsRecorder::Histograms StatisticsRecorder::WithName(
|
StatisticsRecorder::Histograms StatisticsRecorder::WithName(
|
||||||
Histograms histograms,
|
Histograms histograms,
|
||||||
const std::string& query,
|
std::string_view query,
|
||||||
bool case_sensitive) {
|
bool case_sensitive) {
|
||||||
// Need a C-string query for comparisons against C-string histogram name.
|
// Char equality comparator which respects the `case_sensitive` setting.
|
||||||
std::string lowercase_query;
|
auto comparator = [case_sensitive](char a, char b) {
|
||||||
const char* query_string;
|
return case_sensitive ? a == b : std::toupper(a) == std::toupper(b);
|
||||||
if (case_sensitive) {
|
};
|
||||||
query_string = query.c_str();
|
// Filter function that returns true if `h->histogram_name()` does not contain
|
||||||
} else {
|
// `query`. Uses `comparator` to compare chars.
|
||||||
lowercase_query = base::ToLowerASCII(query);
|
auto histogram_name_does_not_contain_query =
|
||||||
query_string = lowercase_query.c_str();
|
[comparator, query](const HistogramBase* const h) {
|
||||||
}
|
const auto& name = h->histogram_name();
|
||||||
|
return std::search(name.begin(), name.end(), query.begin(), query.end(),
|
||||||
auto removed = std::ranges::remove_if(
|
comparator) == name.end();
|
||||||
histograms, [query_string, case_sensitive](const HistogramBase* const h) {
|
};
|
||||||
return !strstr(case_sensitive
|
// Erase the non-matching histograms. Note that `histograms` was passed by
|
||||||
? h->histogram_name()
|
// value so we can efficiently remove the unwanted elements and return the
|
||||||
: base::ToLowerASCII(h->histogram_name()).c_str(),
|
// local instance.
|
||||||
query_string);
|
histograms.erase(std::remove_if(histograms.begin(), histograms.end(),
|
||||||
});
|
histogram_name_does_not_contain_query),
|
||||||
histograms.erase(removed.begin(), removed.end());
|
histograms.end());
|
||||||
return histograms;
|
return histograms;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -74,7 +74,7 @@ class BASE_EXPORT StatisticsRecorder {
|
|||||||
// about a histogram sample. This is used in conjunction with
|
// about a histogram sample. This is used in conjunction with
|
||||||
// ScopedHistogramSampleObserver to get notified when a sample is collected.
|
// ScopedHistogramSampleObserver to get notified when a sample is collected.
|
||||||
using OnSampleCallback =
|
using OnSampleCallback =
|
||||||
base::RepeatingCallback<void(const char* /*=histogram_name*/,
|
base::RepeatingCallback<void(std::string_view /*=histogram_name*/,
|
||||||
uint64_t /*=name_hash*/,
|
uint64_t /*=name_hash*/,
|
||||||
HistogramBase::Sample32)>;
|
HistogramBase::Sample32)>;
|
||||||
|
|
||||||
@ -89,7 +89,7 @@ class BASE_EXPORT StatisticsRecorder {
|
|||||||
public:
|
public:
|
||||||
// Constructor. Called with the desired histogram name and the callback to
|
// Constructor. Called with the desired histogram name and the callback to
|
||||||
// be invoked when a sample is recorded.
|
// be invoked when a sample is recorded.
|
||||||
explicit ScopedHistogramSampleObserver(const std::string& histogram_name,
|
explicit ScopedHistogramSampleObserver(std::string_view histogram_name,
|
||||||
OnSampleCallback callback);
|
OnSampleCallback callback);
|
||||||
~ScopedHistogramSampleObserver();
|
~ScopedHistogramSampleObserver();
|
||||||
|
|
||||||
@ -97,7 +97,7 @@ class BASE_EXPORT StatisticsRecorder {
|
|||||||
friend class StatisticsRecorder;
|
friend class StatisticsRecorder;
|
||||||
|
|
||||||
// Runs the callback.
|
// Runs the callback.
|
||||||
void RunCallback(const char* histogram_name,
|
void RunCallback(std::string_view histogram_name,
|
||||||
uint64_t name_hash,
|
uint64_t name_hash,
|
||||||
HistogramBase::Sample32 sample);
|
HistogramBase::Sample32 sample);
|
||||||
|
|
||||||
@ -216,7 +216,7 @@ class BASE_EXPORT StatisticsRecorder {
|
|||||||
//
|
//
|
||||||
// This method is thread safe.
|
// This method is thread safe.
|
||||||
static void FindAndRunHistogramCallbacks(base::PassKey<HistogramBase>,
|
static void FindAndRunHistogramCallbacks(base::PassKey<HistogramBase>,
|
||||||
const char* histogram_name,
|
std::string_view histogram_name,
|
||||||
uint64_t name_hash,
|
uint64_t name_hash,
|
||||||
HistogramBase::Sample32 sample);
|
HistogramBase::Sample32 sample);
|
||||||
|
|
||||||
@ -275,10 +275,10 @@ class BASE_EXPORT StatisticsRecorder {
|
|||||||
// |case_sensitive| determines whether the matching should be done in a
|
// |case_sensitive| determines whether the matching should be done in a
|
||||||
// case sensitive way.
|
// case sensitive way.
|
||||||
static Histograms WithName(Histograms histograms,
|
static Histograms WithName(Histograms histograms,
|
||||||
const std::string& query,
|
std::string_view query,
|
||||||
bool case_sensitive = true);
|
bool case_sensitive = true);
|
||||||
|
|
||||||
using GlobalSampleCallback = void (*)(const char* /*=histogram_name*/,
|
using GlobalSampleCallback = void (*)(std::string_view /*=histogram_name*/,
|
||||||
uint64_t /*=name_hash*/,
|
uint64_t /*=name_hash*/,
|
||||||
HistogramBase::Sample32);
|
HistogramBase::Sample32);
|
||||||
// Installs a global callback which will be called for every added
|
// Installs a global callback which will be called for every added
|
||||||
|
@ -121,7 +121,7 @@ class StatisticsRecorderTest : public testing::TestWithParam<bool> {
|
|||||||
return StatisticsRecorder::top_ != nullptr;
|
return StatisticsRecorder::top_ != nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
Histogram* CreateHistogram(const char* name,
|
Histogram* CreateHistogram(DurableStringView durable_name,
|
||||||
HistogramBase::Sample32 min,
|
HistogramBase::Sample32 min,
|
||||||
HistogramBase::Sample32 max,
|
HistogramBase::Sample32 max,
|
||||||
size_t bucket_count) {
|
size_t bucket_count) {
|
||||||
@ -129,7 +129,16 @@ class StatisticsRecorderTest : public testing::TestWithParam<bool> {
|
|||||||
Histogram::InitializeBucketRanges(min, max, ranges);
|
Histogram::InitializeBucketRanges(min, max, ranges);
|
||||||
const BucketRanges* registered_ranges =
|
const BucketRanges* registered_ranges =
|
||||||
StatisticsRecorder::RegisterOrDeleteDuplicateRanges(ranges);
|
StatisticsRecorder::RegisterOrDeleteDuplicateRanges(ranges);
|
||||||
return new Histogram(name, registered_ranges);
|
return new Histogram(durable_name, registered_ranges);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <size_t N>
|
||||||
|
Histogram* CreateHistogram(const char (&literal)[N],
|
||||||
|
HistogramBase::Sample32 min,
|
||||||
|
HistogramBase::Sample32 max,
|
||||||
|
size_t bucket_count) {
|
||||||
|
return CreateHistogram(DurableStringView(std::string_view(literal, N - 1)),
|
||||||
|
min, max, bucket_count);
|
||||||
}
|
}
|
||||||
|
|
||||||
void InitLogOnShutdown() { StatisticsRecorder::InitLogOnShutdown(); }
|
void InitLogOnShutdown() { StatisticsRecorder::InitLogOnShutdown(); }
|
||||||
@ -459,17 +468,17 @@ namespace {
|
|||||||
struct CallbackCheckWrapper {
|
struct CallbackCheckWrapper {
|
||||||
CallbackCheckWrapper() : last_name_hash(HashMetricName("")) {}
|
CallbackCheckWrapper() : last_name_hash(HashMetricName("")) {}
|
||||||
|
|
||||||
void OnHistogramChanged(const char* histogram_name,
|
void OnHistogramChanged(std::string_view histogram_name,
|
||||||
uint64_t name_hash,
|
uint64_t name_hash,
|
||||||
HistogramBase::Sample32 histogram_value) {
|
HistogramBase::Sample32 histogram_value) {
|
||||||
called = true;
|
called = true;
|
||||||
last_histogram_name = histogram_name;
|
last_histogram_name = std::string(histogram_name);
|
||||||
last_name_hash = name_hash;
|
last_name_hash = name_hash;
|
||||||
last_histogram_value = histogram_value;
|
last_histogram_value = histogram_value;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool called = false;
|
bool called = false;
|
||||||
const char* last_histogram_name = "";
|
std::string last_histogram_name = "";
|
||||||
uint64_t last_name_hash;
|
uint64_t last_name_hash;
|
||||||
base::HistogramBase::Sample32 last_histogram_value = 0;
|
base::HistogramBase::Sample32 last_histogram_value = 0;
|
||||||
};
|
};
|
||||||
@ -479,7 +488,7 @@ struct CallbackCheckWrapper {
|
|||||||
TEST_P(StatisticsRecorderTest,
|
TEST_P(StatisticsRecorderTest,
|
||||||
AddHistogramCallbackBeforeHistogramRegistration) {
|
AddHistogramCallbackBeforeHistogramRegistration) {
|
||||||
test::TaskEnvironment task_environment;
|
test::TaskEnvironment task_environment;
|
||||||
const char* histogram_name = "TestHistogram";
|
constexpr char histogram_name[] = "TestHistogram";
|
||||||
CallbackCheckWrapper callback_wrapper;
|
CallbackCheckWrapper callback_wrapper;
|
||||||
|
|
||||||
auto callback =
|
auto callback =
|
||||||
@ -500,7 +509,7 @@ TEST_P(StatisticsRecorderTest,
|
|||||||
TEST_P(StatisticsRecorderTest,
|
TEST_P(StatisticsRecorderTest,
|
||||||
RemoveHistogramCallbackBeforeHistogramRegistrationWithMultipleClients) {
|
RemoveHistogramCallbackBeforeHistogramRegistrationWithMultipleClients) {
|
||||||
test::TaskEnvironment task_environment;
|
test::TaskEnvironment task_environment;
|
||||||
const char* histogram_name = "TestHistogram";
|
constexpr char histogram_name[] = "TestHistogram";
|
||||||
CallbackCheckWrapper callback_wrapper1;
|
CallbackCheckWrapper callback_wrapper1;
|
||||||
CallbackCheckWrapper callback_wrapper2;
|
CallbackCheckWrapper callback_wrapper2;
|
||||||
|
|
||||||
@ -623,7 +632,7 @@ TEST_P(StatisticsRecorderTest, CallbackUsedTest) {
|
|||||||
base::RunLoop().RunUntilIdle();
|
base::RunLoop().RunUntilIdle();
|
||||||
|
|
||||||
EXPECT_TRUE(callback_wrapper.called);
|
EXPECT_TRUE(callback_wrapper.called);
|
||||||
EXPECT_STREQ(callback_wrapper.last_histogram_name, "TestHistogram");
|
EXPECT_EQ(callback_wrapper.last_histogram_name, "TestHistogram");
|
||||||
EXPECT_EQ(callback_wrapper.last_name_hash, HashMetricName("TestHistogram"));
|
EXPECT_EQ(callback_wrapper.last_name_hash, HashMetricName("TestHistogram"));
|
||||||
EXPECT_EQ(callback_wrapper.last_histogram_value, 1);
|
EXPECT_EQ(callback_wrapper.last_histogram_value, 1);
|
||||||
}
|
}
|
||||||
@ -644,7 +653,7 @@ TEST_P(StatisticsRecorderTest, CallbackUsedTest) {
|
|||||||
base::RunLoop().RunUntilIdle();
|
base::RunLoop().RunUntilIdle();
|
||||||
|
|
||||||
EXPECT_TRUE(callback_wrapper.called);
|
EXPECT_TRUE(callback_wrapper.called);
|
||||||
EXPECT_STREQ(callback_wrapper.last_histogram_name, "TestLinearHistogram");
|
EXPECT_EQ(callback_wrapper.last_histogram_name, "TestLinearHistogram");
|
||||||
EXPECT_EQ(callback_wrapper.last_name_hash,
|
EXPECT_EQ(callback_wrapper.last_name_hash,
|
||||||
HashMetricName("TestLinearHistogram"));
|
HashMetricName("TestLinearHistogram"));
|
||||||
EXPECT_EQ(callback_wrapper.last_histogram_value, 1);
|
EXPECT_EQ(callback_wrapper.last_histogram_value, 1);
|
||||||
@ -669,7 +678,7 @@ TEST_P(StatisticsRecorderTest, CallbackUsedTest) {
|
|||||||
base::RunLoop().RunUntilIdle();
|
base::RunLoop().RunUntilIdle();
|
||||||
|
|
||||||
EXPECT_TRUE(callback_wrapper.called);
|
EXPECT_TRUE(callback_wrapper.called);
|
||||||
EXPECT_STREQ(callback_wrapper.last_histogram_name, "TestCustomHistogram");
|
EXPECT_EQ(callback_wrapper.last_histogram_name, "TestCustomHistogram");
|
||||||
EXPECT_EQ(callback_wrapper.last_name_hash,
|
EXPECT_EQ(callback_wrapper.last_name_hash,
|
||||||
HashMetricName("TestCustomHistogram"));
|
HashMetricName("TestCustomHistogram"));
|
||||||
EXPECT_EQ(callback_wrapper.last_histogram_value, 1);
|
EXPECT_EQ(callback_wrapper.last_histogram_value, 1);
|
||||||
@ -691,7 +700,7 @@ TEST_P(StatisticsRecorderTest, CallbackUsedTest) {
|
|||||||
base::RunLoop().RunUntilIdle();
|
base::RunLoop().RunUntilIdle();
|
||||||
|
|
||||||
EXPECT_TRUE(callback_wrapper.called);
|
EXPECT_TRUE(callback_wrapper.called);
|
||||||
EXPECT_STREQ(callback_wrapper.last_histogram_name, "TestSparseHistogram");
|
EXPECT_EQ(callback_wrapper.last_histogram_name, "TestSparseHistogram");
|
||||||
EXPECT_EQ(callback_wrapper.last_name_hash,
|
EXPECT_EQ(callback_wrapper.last_name_hash,
|
||||||
HashMetricName("TestSparseHistogram"));
|
HashMetricName("TestSparseHistogram"));
|
||||||
EXPECT_EQ(callback_wrapper.last_histogram_value, 1);
|
EXPECT_EQ(callback_wrapper.last_histogram_value, 1);
|
||||||
@ -716,7 +725,7 @@ TEST_P(StatisticsRecorderTest, CallbackUsedBeforeHistogramCreatedTest) {
|
|||||||
base::RunLoop().RunUntilIdle();
|
base::RunLoop().RunUntilIdle();
|
||||||
|
|
||||||
EXPECT_TRUE(callback_wrapper.called);
|
EXPECT_TRUE(callback_wrapper.called);
|
||||||
EXPECT_STREQ(callback_wrapper.last_histogram_name, "TestHistogram");
|
EXPECT_EQ(callback_wrapper.last_histogram_name, "TestHistogram");
|
||||||
EXPECT_EQ(callback_wrapper.last_name_hash, HashMetricName("TestHistogram"));
|
EXPECT_EQ(callback_wrapper.last_name_hash, HashMetricName("TestHistogram"));
|
||||||
EXPECT_EQ(callback_wrapper.last_histogram_value, 1);
|
EXPECT_EQ(callback_wrapper.last_histogram_value, 1);
|
||||||
}
|
}
|
||||||
@ -731,9 +740,9 @@ TEST_P(StatisticsRecorderTest, GlobalCallbackCalled) {
|
|||||||
// function pointer.
|
// function pointer.
|
||||||
static size_t callback_callcount;
|
static size_t callback_callcount;
|
||||||
callback_callcount = 0;
|
callback_callcount = 0;
|
||||||
auto callback = [](const char* histogram_name, uint64_t name_hash,
|
auto callback = [](std::string_view histogram_name, uint64_t name_hash,
|
||||||
HistogramBase::Sample32 sample) {
|
HistogramBase::Sample32 sample) {
|
||||||
EXPECT_STREQ(histogram_name, "TestHistogram");
|
EXPECT_EQ(histogram_name, "TestHistogram");
|
||||||
EXPECT_EQ(sample, 1);
|
EXPECT_EQ(sample, 1);
|
||||||
++callback_callcount;
|
++callback_callcount;
|
||||||
};
|
};
|
||||||
|
25
base/strings/durable_string_view.h
Normal file
25
base/strings/durable_string_view.h
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
// Copyright 2025 The Chromium Authors
|
||||||
|
// Use of this source code is governed by a BSD-style license that can be
|
||||||
|
// found in the LICENSE file.
|
||||||
|
#ifndef BASE_STRINGS_DURABLE_STRING_VIEW_H_
|
||||||
|
#define BASE_STRINGS_DURABLE_STRING_VIEW_H_
|
||||||
|
|
||||||
|
#include <string_view>
|
||||||
|
|
||||||
|
#include "base/types/strong_alias.h"
|
||||||
|
|
||||||
|
namespace base {
|
||||||
|
|
||||||
|
// A strong type alias which denotes a std::string_view having durable storage.
|
||||||
|
// This allows the programmer to declare that a particular string_view is over
|
||||||
|
// memory that will not be deallocated. I.e., the programmer's use of this alias
|
||||||
|
// is a promise that it is safe to read from within the memory bounds.
|
||||||
|
//
|
||||||
|
// While the underlying string view data can and should be considered const,
|
||||||
|
// note that DurableStringView is unable to *guarantee* that underlying data
|
||||||
|
// is truly const.
|
||||||
|
using DurableStringView = base::StrongAlias<class DurableTag, std::string_view>;
|
||||||
|
|
||||||
|
} // namespace base
|
||||||
|
|
||||||
|
#endif // BASE_STRINGS_DURABLE_STRING_VIEW_H_
|
@ -8,6 +8,7 @@
|
|||||||
|
|
||||||
#include <string_view>
|
#include <string_view>
|
||||||
|
|
||||||
|
#include "base/containers/map_util.h"
|
||||||
#include "base/metrics/histogram.h"
|
#include "base/metrics/histogram.h"
|
||||||
#include "base/metrics/histogram_samples.h"
|
#include "base/metrics/histogram_samples.h"
|
||||||
#include "base/metrics/metrics_hashes.h"
|
#include "base/metrics/metrics_hashes.h"
|
||||||
@ -24,8 +25,8 @@ HistogramTester::HistogramTester() {
|
|||||||
// Record any histogram data that exists when the object is created so it can
|
// Record any histogram data that exists when the object is created so it can
|
||||||
// be subtracted later.
|
// be subtracted later.
|
||||||
for (const auto* const histogram : StatisticsRecorder::GetHistograms()) {
|
for (const auto* const histogram : StatisticsRecorder::GetHistograms()) {
|
||||||
histograms_snapshot_[histogram->histogram_name()] =
|
InsertOrAssign(histograms_snapshot_, histogram->histogram_name(),
|
||||||
histogram->SnapshotSamples();
|
histogram->SnapshotSamples());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -205,7 +206,8 @@ HistogramTester::CountsMap HistogramTester::GetTotalCountsForPrefix(
|
|||||||
GetHistogramSamplesSinceCreation(histogram->histogram_name());
|
GetHistogramSamplesSinceCreation(histogram->histogram_name());
|
||||||
// Omit unchanged histograms from the result.
|
// Omit unchanged histograms from the result.
|
||||||
if (new_samples->TotalCount()) {
|
if (new_samples->TotalCount()) {
|
||||||
result[histogram->histogram_name()] = new_samples->TotalCount();
|
InsertOrAssign(result, histogram->histogram_name(),
|
||||||
|
new_samples->TotalCount());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
|
@ -77,7 +77,7 @@ size_t ExtensionConsoleErrorObserver::GetErrorsAndWarningsCount() const {
|
|||||||
return errors_.size();
|
return errors_.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
HistogramWaiter::HistogramWaiter(const char* metric_name) {
|
HistogramWaiter::HistogramWaiter(std::string_view metric_name) {
|
||||||
histogram_observer_ =
|
histogram_observer_ =
|
||||||
std::make_unique<base::StatisticsRecorder::ScopedHistogramSampleObserver>(
|
std::make_unique<base::StatisticsRecorder::ScopedHistogramSampleObserver>(
|
||||||
metric_name,
|
metric_name,
|
||||||
@ -93,9 +93,10 @@ void HistogramWaiter::Wait() {
|
|||||||
run_loop_.Run();
|
run_loop_.Run();
|
||||||
}
|
}
|
||||||
|
|
||||||
void HistogramWaiter::OnHistogramCallback(const char* metric_name,
|
void HistogramWaiter::OnHistogramCallback(
|
||||||
uint64_t name_hash,
|
std::string_view metric_name,
|
||||||
base::HistogramBase::Sample32 sample) {
|
uint64_t name_hash,
|
||||||
|
base::HistogramBase::Sample32 sample) {
|
||||||
run_loop_.Quit();
|
run_loop_.Quit();
|
||||||
histogram_observer_.reset();
|
histogram_observer_.reset();
|
||||||
}
|
}
|
||||||
|
@ -103,14 +103,14 @@ class ExtensionConsoleErrorObserver : public ErrorConsole::Observer {
|
|||||||
// times, create multiple instances of this class.
|
// times, create multiple instances of this class.
|
||||||
class HistogramWaiter {
|
class HistogramWaiter {
|
||||||
public:
|
public:
|
||||||
explicit HistogramWaiter(const char* metric_name);
|
explicit HistogramWaiter(std::string_view metric_name);
|
||||||
~HistogramWaiter();
|
~HistogramWaiter();
|
||||||
HistogramWaiter(const HistogramWaiter&) = delete;
|
HistogramWaiter(const HistogramWaiter&) = delete;
|
||||||
HistogramWaiter& operator=(const HistogramWaiter&) = delete;
|
HistogramWaiter& operator=(const HistogramWaiter&) = delete;
|
||||||
|
|
||||||
// Waits for the next update to the observed histogram.
|
// Waits for the next update to the observed histogram.
|
||||||
void Wait();
|
void Wait();
|
||||||
void OnHistogramCallback(const char* metric_name,
|
void OnHistogramCallback(std::string_view metric_name,
|
||||||
uint64_t name_hash,
|
uint64_t name_hash,
|
||||||
base::HistogramBase::Sample32 sample);
|
base::HistogramBase::Sample32 sample);
|
||||||
|
|
||||||
|
@ -195,9 +195,9 @@ class MetricsScraper {
|
|||||||
std::vector<std::string> histogram_names;
|
std::vector<std::string> histogram_names;
|
||||||
for (base::HistogramBase* histogram :
|
for (base::HistogramBase* histogram :
|
||||||
base::StatisticsRecorder::GetHistograms()) {
|
base::StatisticsRecorder::GetHistograms()) {
|
||||||
const std::string& name = histogram->histogram_name();
|
const auto& name = histogram->histogram_name();
|
||||||
if (MatchesRegex(base::UTF8ToUTF16(name), *histogram_regex_)) {
|
if (MatchesRegex(base::UTF8ToUTF16(name), *histogram_regex_)) {
|
||||||
histogram_names.push_back(name);
|
histogram_names.emplace_back(name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
std::ranges::sort(histogram_names);
|
std::ranges::sort(histogram_names);
|
||||||
|
@ -87,7 +87,7 @@ IN_PROC_BROWSER_TEST_F(StartupMetricsTest, MAYBE_ReportsValues) {
|
|||||||
base::StatisticsRecorder::ScopedHistogramSampleObserver>(
|
base::StatisticsRecorder::ScopedHistogramSampleObserver>(
|
||||||
histogram,
|
histogram,
|
||||||
base::BindLambdaForTesting(
|
base::BindLambdaForTesting(
|
||||||
[&](const char* histogram_name, uint64_t name_hash,
|
[&](std::string_view histogram_name, uint64_t name_hash,
|
||||||
base::HistogramBase::Sample32 sample) { run_loop.Quit(); }));
|
base::HistogramBase::Sample32 sample) { run_loop.Quit(); }));
|
||||||
run_loop.Run();
|
run_loop.Run();
|
||||||
}
|
}
|
||||||
|
@ -167,7 +167,7 @@ class NotificationPlatformBridgeWinUITest : public InProcessBrowserTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void OnHistogramRecorded(const base::RepeatingClosure& quit_closure,
|
void OnHistogramRecorded(const base::RepeatingClosure& quit_closure,
|
||||||
const char* histogram_name,
|
std::string_view histogram_name,
|
||||||
uint64_t name_hash,
|
uint64_t name_hash,
|
||||||
base::HistogramBase::Sample32 sample) {
|
base::HistogramBase::Sample32 sample) {
|
||||||
quit_closure.Run();
|
quit_closure.Run();
|
||||||
|
@ -67,7 +67,7 @@ void WaitForHistogram(const std::string& histogram_name) {
|
|||||||
std::make_unique<base::StatisticsRecorder::ScopedHistogramSampleObserver>(
|
std::make_unique<base::StatisticsRecorder::ScopedHistogramSampleObserver>(
|
||||||
histogram_name,
|
histogram_name,
|
||||||
base::BindLambdaForTesting(
|
base::BindLambdaForTesting(
|
||||||
[&](const char* histogram_name, uint64_t name_hash,
|
[&](std::string_view histogram_name, uint64_t name_hash,
|
||||||
base::HistogramBase::Sample32 sample) { run_loop.Quit(); }));
|
base::HistogramBase::Sample32 sample) { run_loop.Quit(); }));
|
||||||
run_loop.Run();
|
run_loop.Run();
|
||||||
}
|
}
|
||||||
|
@ -83,7 +83,7 @@ class PasswordManagerAndroidBrowserTest
|
|||||||
base::StatisticsRecorder::ScopedHistogramSampleObserver>(
|
base::StatisticsRecorder::ScopedHistogramSampleObserver>(
|
||||||
histogram_name,
|
histogram_name,
|
||||||
base::BindLambdaForTesting(
|
base::BindLambdaForTesting(
|
||||||
[&](const char* histogram_name, uint64_t name_hash,
|
[&](std::string_view histogram_name, uint64_t name_hash,
|
||||||
base::HistogramBase::Sample32 sample) { run_loop.Quit(); }));
|
base::HistogramBase::Sample32 sample) { run_loop.Quit(); }));
|
||||||
run_loop.Run();
|
run_loop.Run();
|
||||||
}
|
}
|
||||||
|
@ -926,7 +926,7 @@ class
|
|||||||
/*disabled_features=*/{});
|
/*disabled_features=*/{});
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t GetTotalSampleCount(const std::string& histogram_name) {
|
size_t GetTotalSampleCount(std::string_view histogram_name) {
|
||||||
auto buckets = histogram_tester_.GetAllSamples(histogram_name);
|
auto buckets = histogram_tester_.GetAllSamples(histogram_name);
|
||||||
size_t count = 0;
|
size_t count = 0;
|
||||||
for (const auto& bucket : buckets) {
|
for (const auto& bucket : buckets) {
|
||||||
@ -949,7 +949,7 @@ class
|
|||||||
auto histogram_observer = std::make_unique<
|
auto histogram_observer = std::make_unique<
|
||||||
base::StatisticsRecorder::ScopedHistogramSampleObserver>(
|
base::StatisticsRecorder::ScopedHistogramSampleObserver>(
|
||||||
histogram_name,
|
histogram_name,
|
||||||
base::BindLambdaForTesting([&](const char* histogram_name,
|
base::BindLambdaForTesting([&](std::string_view histogram_name,
|
||||||
uint64_t name_hash,
|
uint64_t name_hash,
|
||||||
base::HistogramBase::Sample32 sample) {
|
base::HistogramBase::Sample32 sample) {
|
||||||
if (GetTotalSampleCount(histogram_name) >= expected_sample_count) {
|
if (GetTotalSampleCount(histogram_name) >= expected_sample_count) {
|
||||||
|
@ -275,7 +275,7 @@ class SegmentationPlatformTest : public PlatformBrowserTest {
|
|||||||
return search_user_metadata;
|
return search_user_metadata;
|
||||||
}
|
}
|
||||||
|
|
||||||
void WaitForHistogram(const std::string& histogram_name,
|
void WaitForHistogram(std::string_view histogram_name,
|
||||||
const base::HistogramTester& histogram_tester) {
|
const base::HistogramTester& histogram_tester) {
|
||||||
// Continue if histogram was already recorded.
|
// Continue if histogram was already recorded.
|
||||||
if (histogram_tester.GetAllSamples(histogram_name).size() > 0) {
|
if (histogram_tester.GetAllSamples(histogram_name).size() > 0) {
|
||||||
@ -288,7 +288,7 @@ class SegmentationPlatformTest : public PlatformBrowserTest {
|
|||||||
base::StatisticsRecorder::ScopedHistogramSampleObserver>(
|
base::StatisticsRecorder::ScopedHistogramSampleObserver>(
|
||||||
histogram_name,
|
histogram_name,
|
||||||
base::BindLambdaForTesting(
|
base::BindLambdaForTesting(
|
||||||
[&](const char* histogram_name, uint64_t name_hash,
|
[&](std::string_view histogram_name, uint64_t name_hash,
|
||||||
base::HistogramBase::Sample32 sample) { run_loop.Quit(); }));
|
base::HistogramBase::Sample32 sample) { run_loop.Quit(); }));
|
||||||
run_loop.Run();
|
run_loop.Run();
|
||||||
}
|
}
|
||||||
|
@ -153,7 +153,7 @@ class SiteProtectionMetricsObserverTest
|
|||||||
base::StatisticsRecorder::ScopedHistogramSampleObserver observer(
|
base::StatisticsRecorder::ScopedHistogramSampleObserver observer(
|
||||||
histogram_name,
|
histogram_name,
|
||||||
base::BindLambdaForTesting(
|
base::BindLambdaForTesting(
|
||||||
[&](const char* histogram_name, uint64_t name_hash,
|
[&](std::string_view histogram_name, uint64_t name_hash,
|
||||||
base::HistogramBase::Sample32 sample) { run_loop.Quit(); }));
|
base::HistogramBase::Sample32 sample) { run_loop.Quit(); }));
|
||||||
NavigateAndCommit(url);
|
NavigateAndCommit(url);
|
||||||
run_loop.Run();
|
run_loop.Run();
|
||||||
@ -336,7 +336,7 @@ TEST_F(SiteProtectionMetricsObserverTest, IgnoreCurrentNavigationEngagement) {
|
|||||||
base::StatisticsRecorder::ScopedHistogramSampleObserver observer(
|
base::StatisticsRecorder::ScopedHistogramSampleObserver observer(
|
||||||
"SafeBrowsing.SiteProtection.FamiliarityHeuristic",
|
"SafeBrowsing.SiteProtection.FamiliarityHeuristic",
|
||||||
base::BindLambdaForTesting(
|
base::BindLambdaForTesting(
|
||||||
[&](const char* histogram_name, uint64_t name_hash,
|
[&](std::string_view histogram_name, uint64_t name_hash,
|
||||||
base::HistogramBase::Sample32 sample) { run_loop.Quit(); }));
|
base::HistogramBase::Sample32 sample) { run_loop.Quit(); }));
|
||||||
|
|
||||||
NavigateAndCommit(kUrl, ui::PAGE_TRANSITION_TYPED);
|
NavigateAndCommit(kUrl, ui::PAGE_TRANSITION_TYPED);
|
||||||
|
@ -229,7 +229,7 @@ class LensOverlayLiveTest : public signin::test::LiveTest {
|
|||||||
base::StatisticsRecorder::ScopedHistogramSampleObserver>(
|
base::StatisticsRecorder::ScopedHistogramSampleObserver>(
|
||||||
histogram_name,
|
histogram_name,
|
||||||
base::BindLambdaForTesting(
|
base::BindLambdaForTesting(
|
||||||
[&](const char* histogram_name, uint64_t name_hash,
|
[&](std::string_view histogram_name, uint64_t name_hash,
|
||||||
base::HistogramBase::Sample32 sample) { run_loop.Quit(); }));
|
base::HistogramBase::Sample32 sample) { run_loop.Quit(); }));
|
||||||
run_loop.Run();
|
run_loop.Run();
|
||||||
}
|
}
|
||||||
|
@ -57,7 +57,7 @@ void WaitForHistogram(const std::string& histogram_name) {
|
|||||||
std::make_unique<base::StatisticsRecorder::ScopedHistogramSampleObserver>(
|
std::make_unique<base::StatisticsRecorder::ScopedHistogramSampleObserver>(
|
||||||
histogram_name,
|
histogram_name,
|
||||||
base::BindLambdaForTesting(
|
base::BindLambdaForTesting(
|
||||||
[&](const char* histogram_name, uint64_t name_hash,
|
[&](std::string_view histogram_name, uint64_t name_hash,
|
||||||
base::HistogramBase::Sample32 sample) { run_loop.Quit(); }));
|
base::HistogramBase::Sample32 sample) { run_loop.Quit(); }));
|
||||||
run_loop.Run();
|
run_loop.Run();
|
||||||
}
|
}
|
||||||
|
@ -47,10 +47,17 @@ std::string GetAppName() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
struct HistogramArgs {
|
struct HistogramArgs {
|
||||||
const char* name;
|
base::DurableStringView durable_name;
|
||||||
int minimum;
|
int minimum;
|
||||||
int maximum;
|
int maximum;
|
||||||
size_t bucket_count;
|
size_t bucket_count;
|
||||||
|
|
||||||
|
template <size_t N>
|
||||||
|
HistogramArgs(const char (&literal)[N], int min, int max, size_t count)
|
||||||
|
: durable_name(std::string_view(literal, N - 1)),
|
||||||
|
minimum(min),
|
||||||
|
maximum(max),
|
||||||
|
bucket_count(count) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
// List of metrics to collect using a GroupedHistogram.
|
// List of metrics to collect using a GroupedHistogram.
|
||||||
@ -97,7 +104,7 @@ class GroupedHistogram : public base::Histogram {
|
|||||||
public:
|
public:
|
||||||
// TODO(crbug.com/40824087): min/max parameters are redundant with "ranges"
|
// TODO(crbug.com/40824087): min/max parameters are redundant with "ranges"
|
||||||
// and can probably be removed.
|
// and can probably be removed.
|
||||||
GroupedHistogram(const char* metric_to_override,
|
GroupedHistogram(base::DurableStringView metric_to_override,
|
||||||
Sample32 minimum,
|
Sample32 minimum,
|
||||||
Sample32 maximum,
|
Sample32 maximum,
|
||||||
const base::BucketRanges* ranges)
|
const base::BucketRanges* ranges)
|
||||||
@ -119,8 +126,7 @@ class GroupedHistogram : public base::Histogram {
|
|||||||
// Note: This is very inefficient. Fetching the app name (which has a lock)
|
// Note: This is very inefficient. Fetching the app name (which has a lock)
|
||||||
// plus doing a search by name with FactoryGet (which also has a lock) makes
|
// plus doing a search by name with FactoryGet (which also has a lock) makes
|
||||||
// incrementing a metric relatively slow.
|
// incrementing a metric relatively slow.
|
||||||
std::string name(
|
std::string name = base::StrCat({histogram_name(), ".", GetAppName()});
|
||||||
base::StringPrintf("%s.%s", histogram_name(), GetAppName().c_str()));
|
|
||||||
HistogramBase* grouped_histogram =
|
HistogramBase* grouped_histogram =
|
||||||
base::Histogram::FactoryGet(name,
|
base::Histogram::FactoryGet(name,
|
||||||
minimum_,
|
minimum_,
|
||||||
@ -143,17 +149,16 @@ class GroupedHistogram : public base::Histogram {
|
|||||||
// before any Histogram of the same name has been used.
|
// before any Histogram of the same name has been used.
|
||||||
// It acts similarly to Histogram::FactoryGet but checks that
|
// It acts similarly to Histogram::FactoryGet but checks that
|
||||||
// the histogram is being newly created and does not already exist.
|
// the histogram is being newly created and does not already exist.
|
||||||
void PreregisterHistogram(const char* name,
|
void PreregisterHistogram(base::DurableStringView durable_name,
|
||||||
GroupedHistogram::Sample32 minimum,
|
GroupedHistogram::Sample32 minimum,
|
||||||
GroupedHistogram::Sample32 maximum,
|
GroupedHistogram::Sample32 maximum,
|
||||||
size_t bucket_count,
|
size_t bucket_count,
|
||||||
int32_t flags) {
|
int32_t flags) {
|
||||||
std::string_view name_piece(name);
|
|
||||||
|
|
||||||
DCHECK(base::Histogram::InspectConstructionArguments(
|
DCHECK(base::Histogram::InspectConstructionArguments(
|
||||||
name_piece, &minimum, &maximum, &bucket_count));
|
*durable_name, &minimum, &maximum, &bucket_count));
|
||||||
DCHECK(!base::StatisticsRecorder::FindHistogram(name_piece))
|
DCHECK(!base::StatisticsRecorder::FindHistogram(*durable_name))
|
||||||
<< "Failed to preregister " << name << ", Histogram already exists.";
|
<< "Failed to preregister " << *durable_name
|
||||||
|
<< ", Histogram already exists.";
|
||||||
|
|
||||||
// To avoid racy destruction at shutdown, the following will be leaked.
|
// To avoid racy destruction at shutdown, the following will be leaked.
|
||||||
base::BucketRanges* ranges = new base::BucketRanges(bucket_count + 1);
|
base::BucketRanges* ranges = new base::BucketRanges(bucket_count + 1);
|
||||||
@ -162,7 +167,7 @@ void PreregisterHistogram(const char* name,
|
|||||||
base::StatisticsRecorder::RegisterOrDeleteDuplicateRanges(ranges);
|
base::StatisticsRecorder::RegisterOrDeleteDuplicateRanges(ranges);
|
||||||
|
|
||||||
GroupedHistogram* tentative_histogram =
|
GroupedHistogram* tentative_histogram =
|
||||||
new GroupedHistogram(name, minimum, maximum, registered_ranges);
|
new GroupedHistogram(durable_name, minimum, maximum, registered_ranges);
|
||||||
|
|
||||||
tentative_histogram->SetFlags(flags);
|
tentative_histogram->SetFlags(flags);
|
||||||
base::HistogramBase* histogram =
|
base::HistogramBase* histogram =
|
||||||
@ -178,10 +183,8 @@ void PreregisterHistogram(const char* name,
|
|||||||
void PreregisterAllGroupedHistograms() {
|
void PreregisterAllGroupedHistograms() {
|
||||||
for (size_t i = 0; i < std::size(kHistogramsToGroup); ++i) {
|
for (size_t i = 0; i < std::size(kHistogramsToGroup); ++i) {
|
||||||
PreregisterHistogram(
|
PreregisterHistogram(
|
||||||
kHistogramsToGroup[i].name,
|
kHistogramsToGroup[i].durable_name, kHistogramsToGroup[i].minimum,
|
||||||
kHistogramsToGroup[i].minimum,
|
kHistogramsToGroup[i].maximum, kHistogramsToGroup[i].bucket_count,
|
||||||
kHistogramsToGroup[i].maximum,
|
|
||||||
kHistogramsToGroup[i].bucket_count,
|
|
||||||
base::HistogramBase::kUmaTargetedHistogramFlag);
|
base::HistogramBase::kUmaTargetedHistogramFlag);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -38,7 +38,7 @@ TEST_P(BucketedHistogramTraitsTest, ValidHistogram) {
|
|||||||
EXPECT_TRUE(mojo::test::SerializeAndDeserialize<mojom::BucketedHistogram>(
|
EXPECT_TRUE(mojo::test::SerializeAndDeserialize<mojom::BucketedHistogram>(
|
||||||
histogram, output));
|
histogram, output));
|
||||||
|
|
||||||
EXPECT_STREQ(output->histogram_name(), "Untrusted.Metric");
|
EXPECT_EQ(output->histogram_name(), "Untrusted.Metric");
|
||||||
EXPECT_EQ(output->declared_min(), 1);
|
EXPECT_EQ(output->declared_min(), 1);
|
||||||
EXPECT_EQ(output->declared_max(), 10);
|
EXPECT_EQ(output->declared_max(), 10);
|
||||||
EXPECT_EQ(output->bucket_count(), 3u);
|
EXPECT_EQ(output->bucket_count(), 3u);
|
||||||
|
@ -57,7 +57,7 @@ class LegacyMetricsHistogramFlattener : public base::HistogramFlattener {
|
|||||||
DVLOG(3) << "RecordDelta " << histogram.histogram_name();
|
DVLOG(3) << "RecordDelta " << histogram.histogram_name();
|
||||||
|
|
||||||
fuchsia::legacymetrics::Histogram converted;
|
fuchsia::legacymetrics::Histogram converted;
|
||||||
converted.set_name(histogram.histogram_name());
|
converted.set_name(std::string(histogram.histogram_name()));
|
||||||
converted.set_sum(snapshot.sum());
|
converted.set_sum(snapshot.sum());
|
||||||
|
|
||||||
for (std::unique_ptr<base::SampleCountIterator> it = snapshot.Iterator();
|
for (std::unique_ptr<base::SampleCountIterator> it = snapshot.Iterator();
|
||||||
|
@ -33,6 +33,11 @@ struct HistogramData {
|
|||||||
const base::HistogramBase::Count32 total_count;
|
const base::HistogramBase::Count32 total_count;
|
||||||
const int64_t sum;
|
const int64_t sum;
|
||||||
|
|
||||||
|
HistogramData(std::string_view name,
|
||||||
|
base::HistogramBase::Count32 count,
|
||||||
|
int64_t sum)
|
||||||
|
: histogram_name(name), total_count(count), sum(sum) {}
|
||||||
|
|
||||||
bool operator==(const HistogramData& other) const {
|
bool operator==(const HistogramData& other) const {
|
||||||
return histogram_name == other.histogram_name &&
|
return histogram_name == other.histogram_name &&
|
||||||
total_count == other.total_count && sum == other.sum;
|
total_count == other.total_count && sum == other.sum;
|
||||||
|
@ -79,8 +79,9 @@ class HistogramFlattenerDeltaRecorder : public base::HistogramFlattener {
|
|||||||
void RecordDelta(const base::HistogramBase& histogram,
|
void RecordDelta(const base::HistogramBase& histogram,
|
||||||
const base::HistogramSamples& snapshot) override {
|
const base::HistogramSamples& snapshot) override {
|
||||||
// Only remember locally created histograms; they have exactly 2 chars.
|
// Only remember locally created histograms; they have exactly 2 chars.
|
||||||
if (strlen(histogram.histogram_name()) == 2)
|
if (histogram.histogram_name().length() == 2) {
|
||||||
recorded_delta_histogram_names_.push_back(histogram.histogram_name());
|
recorded_delta_histogram_names_.emplace_back(histogram.histogram_name());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<std::string> GetRecordedDeltaHistogramNames() {
|
std::vector<std::string> GetRecordedDeltaHistogramNames() {
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
#include "components/metrics/histogram_encoder.h"
|
#include "components/metrics/histogram_encoder.h"
|
||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <string>
|
#include <string_view>
|
||||||
|
|
||||||
#include "base/metrics/histogram.h"
|
#include "base/metrics/histogram.h"
|
||||||
#include "base/metrics/histogram_samples.h"
|
#include "base/metrics/histogram_samples.h"
|
||||||
@ -15,7 +15,7 @@ using base::SampleCountIterator;
|
|||||||
|
|
||||||
namespace metrics {
|
namespace metrics {
|
||||||
|
|
||||||
void EncodeHistogramDelta(const std::string& histogram_name,
|
void EncodeHistogramDelta(std::string_view histogram_name,
|
||||||
const base::HistogramSamples& snapshot,
|
const base::HistogramSamples& snapshot,
|
||||||
ChromeUserMetricsExtension* uma_proto) {
|
ChromeUserMetricsExtension* uma_proto) {
|
||||||
DCHECK_NE(0, snapshot.TotalCount());
|
DCHECK_NE(0, snapshot.TotalCount());
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
#ifndef COMPONENTS_METRICS_HISTOGRAM_ENCODER_H_
|
#ifndef COMPONENTS_METRICS_HISTOGRAM_ENCODER_H_
|
||||||
#define COMPONENTS_METRICS_HISTOGRAM_ENCODER_H_
|
#define COMPONENTS_METRICS_HISTOGRAM_ENCODER_H_
|
||||||
|
|
||||||
#include <string>
|
#include <string_view>
|
||||||
|
|
||||||
#include "third_party/metrics_proto/chrome_user_metrics_extension.pb.h"
|
#include "third_party/metrics_proto/chrome_user_metrics_extension.pb.h"
|
||||||
|
|
||||||
@ -20,7 +20,7 @@ namespace metrics {
|
|||||||
|
|
||||||
// Record any changes (histogram deltas of counts from |snapshot|) into
|
// Record any changes (histogram deltas of counts from |snapshot|) into
|
||||||
// |uma_proto| for the given histogram (|histogram_name|).
|
// |uma_proto| for the given histogram (|histogram_name|).
|
||||||
void EncodeHistogramDelta(const std::string& histogram_name,
|
void EncodeHistogramDelta(std::string_view histogram_name,
|
||||||
const base::HistogramSamples& snapshot,
|
const base::HistogramSamples& snapshot,
|
||||||
ChromeUserMetricsExtension* uma_proto);
|
ChromeUserMetricsExtension* uma_proto);
|
||||||
|
|
||||||
|
@ -466,7 +466,7 @@ void MetricsLog::RecordCoreSystemProfile(
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void MetricsLog::RecordHistogramDelta(const std::string& histogram_name,
|
void MetricsLog::RecordHistogramDelta(std::string_view histogram_name,
|
||||||
const base::HistogramSamples& snapshot) {
|
const base::HistogramSamples& snapshot) {
|
||||||
DCHECK(!closed_);
|
DCHECK(!closed_);
|
||||||
log_metadata_.AddSampleCount(snapshot.TotalCount());
|
log_metadata_.AddSampleCount(snapshot.TotalCount());
|
||||||
|
@ -165,7 +165,7 @@ class MetricsLog {
|
|||||||
void RecordUserAction(const std::string& key, base::TimeTicks action_time);
|
void RecordUserAction(const std::string& key, base::TimeTicks action_time);
|
||||||
|
|
||||||
// Record any changes in a given histogram for transmission.
|
// Record any changes in a given histogram for transmission.
|
||||||
void RecordHistogramDelta(const std::string& histogram_name,
|
void RecordHistogramDelta(std::string_view histogram_name,
|
||||||
const base::HistogramSamples& snapshot);
|
const base::HistogramSamples& snapshot);
|
||||||
|
|
||||||
// TODO(rkaplow): I think this can be a little refactored as it currently
|
// TODO(rkaplow): I think this can be a little refactored as it currently
|
||||||
|
@ -405,7 +405,7 @@ void LogUploadingHistograms(const std::string& compressed_log_data) {
|
|||||||
auto get_histogram_name = [&](uint64_t name_hash) -> std::string {
|
auto get_histogram_name = [&](uint64_t name_hash) -> std::string {
|
||||||
for (base::HistogramBase* histogram : histograms) {
|
for (base::HistogramBase* histogram : histograms) {
|
||||||
if (histogram->name_hash() == name_hash) {
|
if (histogram->name_hash() == name_hash) {
|
||||||
return histogram->histogram_name();
|
return std::string(histogram->histogram_name());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return base::StrCat({"unnamed ", base::NumberToString(name_hash)});
|
return base::StrCat({"unnamed ", base::NumberToString(name_hash)});
|
||||||
|
@ -241,7 +241,7 @@ void TrainingDataCollectorImpl::OnGetSegmentsInfoList(
|
|||||||
}
|
}
|
||||||
|
|
||||||
void TrainingDataCollectorImpl::OnHistogramSignalUpdated(
|
void TrainingDataCollectorImpl::OnHistogramSignalUpdated(
|
||||||
const std::string& histogram_name,
|
std::string_view histogram_name,
|
||||||
base::HistogramBase::Sample32 sample) {
|
base::HistogramBase::Sample32 sample) {
|
||||||
// Report training data for all models which output collection is triggered by
|
// Report training data for all models which output collection is triggered by
|
||||||
// |histogram_name|.
|
// |histogram_name|.
|
||||||
|
@ -69,7 +69,7 @@ class TrainingDataCollectorImpl : public TrainingDataCollector,
|
|||||||
SuccessCallback callback) override;
|
SuccessCallback callback) override;
|
||||||
|
|
||||||
// HistogramSignalHandler::Observer implementation.
|
// HistogramSignalHandler::Observer implementation.
|
||||||
void OnHistogramSignalUpdated(const std::string& histogram_name,
|
void OnHistogramSignalUpdated(std::string_view histogram_name,
|
||||||
base::HistogramBase::Sample32 sample) override;
|
base::HistogramBase::Sample32 sample) override;
|
||||||
|
|
||||||
// UserActionSignalHandler::Observer implementation.
|
// UserActionSignalHandler::Observer implementation.
|
||||||
|
@ -63,7 +63,7 @@ void HistogramSignalHandler::EnableMetrics(bool enable_metrics) {
|
|||||||
|
|
||||||
void HistogramSignalHandler::OnHistogramSample(
|
void HistogramSignalHandler::OnHistogramSample(
|
||||||
proto::SignalType signal_type,
|
proto::SignalType signal_type,
|
||||||
const char* histogram_name,
|
std::string_view histogram_name,
|
||||||
uint64_t name_hash,
|
uint64_t name_hash,
|
||||||
base::HistogramBase::Sample32 sample) {
|
base::HistogramBase::Sample32 sample) {
|
||||||
if (!metrics_enabled_) {
|
if (!metrics_enabled_) {
|
||||||
@ -91,7 +91,7 @@ void HistogramSignalHandler::RemoveObserver(Observer* observer) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void HistogramSignalHandler::OnSampleWritten(
|
void HistogramSignalHandler::OnSampleWritten(
|
||||||
const std::string& histogram_name,
|
std::string_view histogram_name,
|
||||||
base::HistogramBase::Sample32 sample,
|
base::HistogramBase::Sample32 sample,
|
||||||
bool success) {
|
bool success) {
|
||||||
if (!success) {
|
if (!success) {
|
||||||
|
@ -35,7 +35,7 @@ class HistogramSignalHandler {
|
|||||||
public:
|
public:
|
||||||
// Called when a histogram signal tracked by segmentation platform is
|
// Called when a histogram signal tracked by segmentation platform is
|
||||||
// updated and written to database.
|
// updated and written to database.
|
||||||
virtual void OnHistogramSignalUpdated(const std::string& histogram_name,
|
virtual void OnHistogramSignalUpdated(std::string_view histogram_name,
|
||||||
base::HistogramBase::Sample32) = 0;
|
base::HistogramBase::Sample32) = 0;
|
||||||
~Observer() override = default;
|
~Observer() override = default;
|
||||||
|
|
||||||
@ -65,11 +65,11 @@ class HistogramSignalHandler {
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
void OnHistogramSample(proto::SignalType signal_type,
|
void OnHistogramSample(proto::SignalType signal_type,
|
||||||
const char* histogram_name,
|
std::string_view histogram_name,
|
||||||
uint64_t name_hash,
|
uint64_t name_hash,
|
||||||
base::HistogramBase::Sample32 sample);
|
base::HistogramBase::Sample32 sample);
|
||||||
|
|
||||||
void OnSampleWritten(const std::string& histogram_name,
|
void OnSampleWritten(std::string_view histogram_name,
|
||||||
base::HistogramBase::Sample32 sample,
|
base::HistogramBase::Sample32 sample,
|
||||||
bool success);
|
bool success);
|
||||||
|
|
||||||
|
@ -41,7 +41,7 @@ class MockObserver : public HistogramSignalHandler::Observer {
|
|||||||
~MockObserver() override = default;
|
~MockObserver() override = default;
|
||||||
MOCK_METHOD(void,
|
MOCK_METHOD(void,
|
||||||
OnHistogramSignalUpdated,
|
OnHistogramSignalUpdated,
|
||||||
(const std::string&, base::HistogramBase::Sample32),
|
(std::string_view, base::HistogramBase::Sample32),
|
||||||
(override));
|
(override));
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -69,7 +69,7 @@ class LazyLevelDb {
|
|||||||
// to delete the database. Will only attempt a single recovery.
|
// to delete the database. Will only attempt a single recovery.
|
||||||
ValueStore::Status EnsureDbIsOpen();
|
ValueStore::Status EnsureDbIsOpen();
|
||||||
|
|
||||||
const char* open_histogram_name() const {
|
std::string_view open_histogram_name() const {
|
||||||
return open_histogram_->histogram_name();
|
return open_histogram_->histogram_name();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -10,6 +10,7 @@
|
|||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
#include "base/command_line.h"
|
#include "base/command_line.h"
|
||||||
|
#include "base/containers/map_util.h"
|
||||||
#include "base/immediate_crash.h"
|
#include "base/immediate_crash.h"
|
||||||
#include "base/metrics/histogram_base.h"
|
#include "base/metrics/histogram_base.h"
|
||||||
#include "base/metrics/histogram_samples.h"
|
#include "base/metrics/histogram_samples.h"
|
||||||
@ -677,7 +678,7 @@ std::unique_ptr<Browser::Histogram> BrowserHandler::GetHistogramData(
|
|||||||
}
|
}
|
||||||
|
|
||||||
auto result = Browser::Histogram::Create()
|
auto result = Browser::Histogram::Create()
|
||||||
.SetName(histogram.histogram_name())
|
.SetName(std::string(histogram.histogram_name()))
|
||||||
.SetSum(data->sum())
|
.SetSum(data->sum())
|
||||||
.SetCount(data->TotalCount())
|
.SetCount(data->TotalCount())
|
||||||
.SetBuckets(std::move(out_buckets))
|
.SetBuckets(std::move(out_buckets))
|
||||||
@ -689,7 +690,8 @@ std::unique_ptr<Browser::Histogram> BrowserHandler::GetHistogramData(
|
|||||||
// If we had subtracted previous data, re-add it to get the full snapshot.
|
// If we had subtracted previous data, re-add it to get the full snapshot.
|
||||||
data->Add(*previous_data);
|
data->Add(*previous_data);
|
||||||
}
|
}
|
||||||
histograms_snapshots_[histogram.histogram_name()] = std::move(data);
|
base::InsertOrAssign(histograms_snapshots_, histogram.histogram_name(),
|
||||||
|
std::move(data));
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
|
@ -117,7 +117,7 @@ class BrowserHandler : public DevToolsDomainHandler,
|
|||||||
base::flat_set<raw_ptr<download::DownloadItem, CtnExperimental>>
|
base::flat_set<raw_ptr<download::DownloadItem, CtnExperimental>>
|
||||||
pending_downloads_;
|
pending_downloads_;
|
||||||
// Stores past histogram snapshots for producing histogram deltas.
|
// Stores past histogram snapshots for producing histogram deltas.
|
||||||
std::map<std::string, std::unique_ptr<base::HistogramSamples>>
|
std::map<std::string, std::unique_ptr<base::HistogramSamples>, std::less<>>
|
||||||
histograms_snapshots_;
|
histograms_snapshots_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
|
|
||||||
#include "content/browser/metrics/histograms_monitor.h"
|
#include "content/browser/metrics/histograms_monitor.h"
|
||||||
|
|
||||||
|
#include "base/containers/map_util.h"
|
||||||
#include "base/metrics/histogram_samples.h"
|
#include "base/metrics/histogram_samples.h"
|
||||||
#include "base/metrics/statistics_recorder.h"
|
#include "base/metrics/statistics_recorder.h"
|
||||||
|
|
||||||
@ -17,8 +18,8 @@ void HistogramsMonitor::StartMonitoring() {
|
|||||||
histograms_snapshot_.clear();
|
histograms_snapshot_.clear();
|
||||||
// Save a snapshot of all current histograms that will be used as a baseline.
|
// Save a snapshot of all current histograms that will be used as a baseline.
|
||||||
for (const auto* histogram : base::StatisticsRecorder::GetHistograms()) {
|
for (const auto* histogram : base::StatisticsRecorder::GetHistograms()) {
|
||||||
histograms_snapshot_[histogram->histogram_name()] =
|
base::InsertOrAssign(histograms_snapshot_, histogram->histogram_name(),
|
||||||
histogram->SnapshotSamples();
|
histogram->SnapshotSamples());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -45,7 +45,7 @@ class CONTENT_EXPORT HistogramsMonitor {
|
|||||||
base::Value::List GetDiffInternal(
|
base::Value::List GetDiffInternal(
|
||||||
const base::StatisticsRecorder::Histograms& histograms);
|
const base::StatisticsRecorder::Histograms& histograms);
|
||||||
|
|
||||||
std::map<std::string, std::unique_ptr<base::HistogramSamples>>
|
std::map<std::string, std::unique_ptr<base::HistogramSamples>, std::less<>>
|
||||||
histograms_snapshot_;
|
histograms_snapshot_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -473,7 +473,7 @@ void SharedStorageBrowserTestBase::WaitForHistogram(
|
|||||||
std::make_unique<base::StatisticsRecorder::ScopedHistogramSampleObserver>(
|
std::make_unique<base::StatisticsRecorder::ScopedHistogramSampleObserver>(
|
||||||
histogram_name,
|
histogram_name,
|
||||||
base::BindLambdaForTesting(
|
base::BindLambdaForTesting(
|
||||||
[&](const char* histogram_name, uint64_t name_hash,
|
[&](std::string_view histogram_name, uint64_t name_hash,
|
||||||
base::HistogramBase::Sample32 sample) { run_loop.Quit(); }));
|
base::HistogramBase::Sample32 sample) { run_loop.Quit(); }));
|
||||||
run_loop.Run();
|
run_loop.Run();
|
||||||
}
|
}
|
||||||
|
@ -268,7 +268,7 @@ class HistogramRule : public BackgroundTracingRule,
|
|||||||
void OnHistogramChangedCallback(
|
void OnHistogramChangedCallback(
|
||||||
base::Histogram::Sample32 reference_lower_value,
|
base::Histogram::Sample32 reference_lower_value,
|
||||||
base::Histogram::Sample32 reference_upper_value,
|
base::Histogram::Sample32 reference_upper_value,
|
||||||
const char* histogram_name,
|
std::string_view histogram_name,
|
||||||
uint64_t name_hash,
|
uint64_t name_hash,
|
||||||
base::Histogram::Sample32 actual_value) {
|
base::Histogram::Sample32 actual_value) {
|
||||||
DCHECK_EQ(histogram_name, histogram_name_);
|
DCHECK_EQ(histogram_name, histogram_name_);
|
||||||
|
@ -138,8 +138,7 @@ void AboutUIHTMLSource::StartDataRequest(
|
|||||||
// chrome://histograms, this code could likely be moved to //ios/web.
|
// chrome://histograms, this code could likely be moved to //ios/web.
|
||||||
for (base::HistogramBase* histogram : base::StatisticsRecorder::Sort(
|
for (base::HistogramBase* histogram : base::StatisticsRecorder::Sort(
|
||||||
base::StatisticsRecorder::GetHistograms())) {
|
base::StatisticsRecorder::GetHistograms())) {
|
||||||
std::string histogram_name = histogram->histogram_name();
|
if (!base::Contains(histogram->histogram_name(), path)) {
|
||||||
if (!base::Contains(histogram_name, path)) {
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
base::Value::Dict histogram_dict = histogram->ToGraphDict();
|
base::Value::Dict histogram_dict = histogram->ToGraphDict();
|
||||||
|
@ -104,7 +104,7 @@ class HistogramTester {
|
|||||||
// Used to determine the histogram changes made during this instance's
|
// Used to determine the histogram changes made during this instance's
|
||||||
// lifecycle. This instance takes ownership of the samples, which are deleted
|
// lifecycle. This instance takes ownership of the samples, which are deleted
|
||||||
// when the instance is destroyed.
|
// when the instance is destroyed.
|
||||||
std::map<std::string, std::unique_ptr<base::HistogramSamples>>
|
std::map<std::string, std::unique_ptr<base::HistogramSamples>, std::less<>>
|
||||||
histograms_snapshot_;
|
histograms_snapshot_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -6,6 +6,7 @@
|
|||||||
|
|
||||||
#import <Foundation/Foundation.h>
|
#import <Foundation/Foundation.h>
|
||||||
|
|
||||||
|
#import "base/containers/map_util.h"
|
||||||
#import "base/memory/ptr_util.h"
|
#import "base/memory/ptr_util.h"
|
||||||
#import "base/metrics/histogram_macros.h"
|
#import "base/metrics/histogram_macros.h"
|
||||||
#import "base/metrics/histogram_samples.h"
|
#import "base/metrics/histogram_samples.h"
|
||||||
@ -32,7 +33,8 @@ HistogramTester::HistogramTester() {
|
|||||||
// Record any histogram data that exists when the object is created so it can
|
// Record any histogram data that exists when the object is created so it can
|
||||||
// be subtracted later.
|
// be subtracted later.
|
||||||
for (const auto* const h : base::StatisticsRecorder::GetHistograms()) {
|
for (const auto* const h : base::StatisticsRecorder::GetHistograms()) {
|
||||||
histograms_snapshot_[h->histogram_name()] = h->SnapshotSamples();
|
base::InsertOrAssign(histograms_snapshot_, h->histogram_name(),
|
||||||
|
h->SnapshotSamples());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -80,7 +80,7 @@ void BackgroundTracingAgentImpl::OnHistogramChanged(
|
|||||||
const std::string& rule_id,
|
const std::string& rule_id,
|
||||||
base::Histogram::Sample32 histogram_lower_value,
|
base::Histogram::Sample32 histogram_lower_value,
|
||||||
base::Histogram::Sample32 histogram_upper_value,
|
base::Histogram::Sample32 histogram_upper_value,
|
||||||
const char* histogram_name,
|
std::string_view histogram_name,
|
||||||
uint64_t name_hash,
|
uint64_t name_hash,
|
||||||
base::Histogram::Sample32 actual_value) {
|
base::Histogram::Sample32 actual_value) {
|
||||||
if (actual_value < histogram_lower_value ||
|
if (actual_value < histogram_lower_value ||
|
||||||
|
@ -49,7 +49,7 @@ class COMPONENT_EXPORT(BACKGROUND_TRACING_CPP) BackgroundTracingAgentImpl
|
|||||||
void OnHistogramChanged(const std::string& rule_id,
|
void OnHistogramChanged(const std::string& rule_id,
|
||||||
base::Histogram::Sample32 reference_lower_value,
|
base::Histogram::Sample32 reference_lower_value,
|
||||||
base::Histogram::Sample32 reference_upper_value,
|
base::Histogram::Sample32 reference_upper_value,
|
||||||
const char* histogram_name,
|
std::string_view histogram_name,
|
||||||
uint64_t name_hash,
|
uint64_t name_hash,
|
||||||
base::Histogram::Sample32 actual_value);
|
base::Histogram::Sample32 actual_value);
|
||||||
|
|
||||||
@ -61,7 +61,7 @@ class COMPONENT_EXPORT(BACKGROUND_TRACING_CPP) BackgroundTracingAgentImpl
|
|||||||
base::Time histogram_last_changed_;
|
base::Time histogram_last_changed_;
|
||||||
// Tracks histogram names and corresponding registered callbacks.
|
// Tracks histogram names and corresponding registered callbacks.
|
||||||
std::map<
|
std::map<
|
||||||
std::string,
|
std::string /*=rule_id*/,
|
||||||
std::unique_ptr<base::StatisticsRecorder::ScopedHistogramSampleObserver>>
|
std::unique_ptr<base::StatisticsRecorder::ScopedHistogramSampleObserver>>
|
||||||
histogram_callback_map_;
|
histogram_callback_map_;
|
||||||
|
|
||||||
|
@ -177,8 +177,8 @@ void CustomEventRecorder::LogHistogram(base::HistogramBase* histogram) {
|
|||||||
}
|
}
|
||||||
base::Pickle pickle;
|
base::Pickle pickle;
|
||||||
samples->Serialize(&pickle);
|
samples->Serialize(&pickle);
|
||||||
std::string buckets =
|
std::string buckets = base::Base64Encode(
|
||||||
base::Base64Encode(std::string(pickle.data_as_char(), pickle.size()));
|
std::string_view(pickle.data_as_char(), pickle.size()));
|
||||||
TRACE_EVENT_INSTANT2("benchmark,uma", "UMAHistogramSamples",
|
TRACE_EVENT_INSTANT2("benchmark,uma", "UMAHistogramSamples",
|
||||||
TRACE_EVENT_SCOPE_PROCESS, "name",
|
TRACE_EVENT_SCOPE_PROCESS, "name",
|
||||||
histogram->histogram_name(), "buckets", buckets);
|
histogram->histogram_name(), "buckets", buckets);
|
||||||
|
@ -67,7 +67,7 @@ class COMPONENT_EXPORT(TRACING_CPP) CustomEventRecorder
|
|||||||
// For each of the Histogram that we are tracking, cache the snapshot of their
|
// For each of the Histogram that we are tracking, cache the snapshot of their
|
||||||
// HistogramSamples from before tracing began. So that we can calculate the
|
// HistogramSamples from before tracing began. So that we can calculate the
|
||||||
// delta when we go to LogHistograms.
|
// delta when we go to LogHistograms.
|
||||||
std::map<std::string, std::unique_ptr<base::HistogramSamples>>
|
std::map<std::string, std::unique_ptr<base::HistogramSamples>, std::less<>>
|
||||||
startup_histogram_samples_;
|
startup_histogram_samples_;
|
||||||
std::vector<std::string> histograms_;
|
std::vector<std::string> histograms_;
|
||||||
base::ActionCallback user_action_callback_ =
|
base::ActionCallback user_action_callback_ =
|
||||||
|
@ -37,13 +37,13 @@ std::optional<base::HistogramBase::Sample32> MaybeReferenceValue(
|
|||||||
|
|
||||||
struct HistogramSamplesIncrementalState {
|
struct HistogramSamplesIncrementalState {
|
||||||
using InternedHistogramName =
|
using InternedHistogramName =
|
||||||
perfetto::SmallInternedDataTraits::Index<const char*>;
|
perfetto::SmallInternedDataTraits::Index<std::string_view>;
|
||||||
|
|
||||||
bool was_cleared = true;
|
bool was_cleared = true;
|
||||||
InternedHistogramName histogram_names_;
|
InternedHistogramName histogram_names_;
|
||||||
|
|
||||||
size_t GetInternedHistogramName(
|
size_t GetInternedHistogramName(
|
||||||
const char* value,
|
std::string_view value,
|
||||||
HistogramSamplesDataSource::TraceContext::TracePacketHandle& packet) {
|
HistogramSamplesDataSource::TraceContext::TracePacketHandle& packet) {
|
||||||
size_t iid;
|
size_t iid;
|
||||||
if (histogram_names_.LookUpOrInsert(&iid, value)) {
|
if (histogram_names_.LookUpOrInsert(&iid, value)) {
|
||||||
@ -52,7 +52,7 @@ struct HistogramSamplesIncrementalState {
|
|||||||
auto* interned_data = packet->set_interned_data();
|
auto* interned_data = packet->set_interned_data();
|
||||||
auto* msg = interned_data->add_histogram_names();
|
auto* msg = interned_data->add_histogram_names();
|
||||||
msg->set_iid(iid);
|
msg->set_iid(iid);
|
||||||
msg->set_name(value);
|
msg->set_name(value.data(), value.size());
|
||||||
return iid;
|
return iid;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -136,7 +136,7 @@ void HistogramSamplesDataSource::OnStop(const StopArgs&) {
|
|||||||
void HistogramSamplesDataSource::OnMetricSample(
|
void HistogramSamplesDataSource::OnMetricSample(
|
||||||
std::optional<base::HistogramBase::Sample32> reference_lower_value,
|
std::optional<base::HistogramBase::Sample32> reference_lower_value,
|
||||||
std::optional<base::HistogramBase::Sample32> reference_upper_value,
|
std::optional<base::HistogramBase::Sample32> reference_upper_value,
|
||||||
const char* histogram_name,
|
std::string_view histogram_name,
|
||||||
uint64_t name_hash,
|
uint64_t name_hash,
|
||||||
base::HistogramBase::Sample32 sample) {
|
base::HistogramBase::Sample32 sample) {
|
||||||
if ((reference_lower_value && sample < reference_lower_value) ||
|
if ((reference_lower_value && sample < reference_lower_value) ||
|
||||||
@ -148,14 +148,14 @@ void HistogramSamplesDataSource::OnMetricSample(
|
|||||||
}
|
}
|
||||||
|
|
||||||
void HistogramSamplesDataSource::OnAnyMetricSample(
|
void HistogramSamplesDataSource::OnAnyMetricSample(
|
||||||
const char* histogram_name,
|
std::string_view histogram_name,
|
||||||
uint64_t name_hash,
|
uint64_t name_hash,
|
||||||
base::HistogramBase::Sample32 sample) {
|
base::HistogramBase::Sample32 sample) {
|
||||||
OnMetricSampleImpl(histogram_name, name_hash, sample, std::nullopt);
|
OnMetricSampleImpl(histogram_name, name_hash, sample, std::nullopt);
|
||||||
}
|
}
|
||||||
|
|
||||||
void HistogramSamplesDataSource::OnMetricSampleImpl(
|
void HistogramSamplesDataSource::OnMetricSampleImpl(
|
||||||
const char* histogram_name,
|
std::string_view histogram_name,
|
||||||
uint64_t name_hash,
|
uint64_t name_hash,
|
||||||
base::HistogramBase::Sample32 sample,
|
base::HistogramBase::Sample32 sample,
|
||||||
std::optional<uintptr_t> instance) {
|
std::optional<uintptr_t> instance) {
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
#ifndef SERVICES_TRACING_PUBLIC_CPP_PERFETTO_HISTOGRAM_SAMPLES_DATA_SOURCE_H_
|
#ifndef SERVICES_TRACING_PUBLIC_CPP_PERFETTO_HISTOGRAM_SAMPLES_DATA_SOURCE_H_
|
||||||
#define SERVICES_TRACING_PUBLIC_CPP_PERFETTO_HISTOGRAM_SAMPLES_DATA_SOURCE_H_
|
#define SERVICES_TRACING_PUBLIC_CPP_PERFETTO_HISTOGRAM_SAMPLES_DATA_SOURCE_H_
|
||||||
|
|
||||||
|
#include <string_view>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "base/component_export.h"
|
#include "base/component_export.h"
|
||||||
@ -45,15 +46,15 @@ class COMPONENT_EXPORT(TRACING_CPP) HistogramSamplesDataSource
|
|||||||
void OnMetricSample(
|
void OnMetricSample(
|
||||||
std::optional<base::HistogramBase::Sample32> reference_lower_value,
|
std::optional<base::HistogramBase::Sample32> reference_lower_value,
|
||||||
std::optional<base::HistogramBase::Sample32> reference_upper_value,
|
std::optional<base::HistogramBase::Sample32> reference_upper_value,
|
||||||
const char* histogram_name,
|
std::string_view histogram_name,
|
||||||
uint64_t name_hash,
|
uint64_t name_hash,
|
||||||
base::HistogramBase::Sample32 actual_value);
|
base::HistogramBase::Sample32 actual_value);
|
||||||
static void OnAnyMetricSample(const char* histogram_name,
|
static void OnAnyMetricSample(std::string_view histogram_name,
|
||||||
uint64_t name_hash,
|
uint64_t name_hash,
|
||||||
base::HistogramBase::Sample32 sample);
|
base::HistogramBase::Sample32 sample);
|
||||||
// `instance` identifies the instance that registered a callback, or nullopt
|
// `instance` identifies the instance that registered a callback, or nullopt
|
||||||
// if this is a global callback.
|
// if this is a global callback.
|
||||||
static void OnMetricSampleImpl(const char* histogram_name,
|
static void OnMetricSampleImpl(std::string_view histogram_name,
|
||||||
uint64_t name_hash,
|
uint64_t name_hash,
|
||||||
base::HistogramBase::Sample32 sample,
|
base::HistogramBase::Sample32 sample,
|
||||||
std::optional<uintptr_t> instance);
|
std::optional<uintptr_t> instance);
|
||||||
|
2
third_party/webrtc_overrides/metrics.cc
vendored
2
third_party/webrtc_overrides/metrics.cc
vendored
@ -47,7 +47,7 @@ Histogram* SparseHistogramFactoryGetEnumeration(std::string_view name,
|
|||||||
std::string(name), base::HistogramBase::kUmaTargetedHistogramFlag));
|
std::string(name), base::HistogramBase::kUmaTargetedHistogramFlag));
|
||||||
}
|
}
|
||||||
|
|
||||||
const char* GetHistogramName(Histogram* histogram_pointer) {
|
std::string_view GetHistogramName(Histogram* histogram_pointer) {
|
||||||
base::HistogramBase* ptr =
|
base::HistogramBase* ptr =
|
||||||
reinterpret_cast<base::HistogramBase*>(histogram_pointer);
|
reinterpret_cast<base::HistogramBase*>(histogram_pointer);
|
||||||
return ptr->histogram_name();
|
return ptr->histogram_name();
|
||||||
|
Reference in New Issue
Block a user