[metrics] Templatized Metrics API (#36449)

This adds compile-time checking that the type of the value and the size of the labels and optional labels passed when recording a metric must match with the type and the size specified when the metric is registered.

The RegistrationBuilder API idea is credited to @ctiller.

<!--

If you know who should review your pull request, please assign it to that
person, otherwise the pull request would get assigned randomly.

If your pull request is for a specific language, please add the appropriate
lang label.

-->

Closes #36449

COPYBARA_INTEGRATE_REVIEW=https://github.com/grpc/grpc/pull/36449 from yijiem:registration-builder-api a727810136
PiperOrigin-RevId: 632271022
pull/36570/head^2
Yijie Ma 10 months ago committed by Copybara-Service
parent c0208416b6
commit bc4766381a
  1. 193
      src/core/lib/channel/metrics.cc
  2. 308
      src/core/lib/channel/metrics.h
  3. 12
      src/core/load_balancing/pick_first/pick_first.cc
  4. 49
      src/core/load_balancing/rls/rls.cc
  5. 31
      src/core/load_balancing/weighted_round_robin/weighted_round_robin.cc
  6. 34
      src/core/xds/grpc/xds_client_grpc.cc
  7. 251
      src/cpp/ext/otel/otel_plugin.cc
  8. 20
      src/cpp/ext/otel/otel_plugin.h
  9. 534
      test/core/channel/metrics_test.cc
  10. 13
      test/core/load_balancing/pick_first_test.cc
  11. 23
      test/core/load_balancing/weighted_round_robin_test.cc
  12. 52
      test/core/test_util/fake_stats_plugin.cc
  13. 84
      test/core/test_util/fake_stats_plugin.h
  14. 32
      test/cpp/end2end/rls_end2end_test.cc
  15. 48
      test/cpp/end2end/xds/xds_core_end2end_test.cc
  16. 8
      test/cpp/end2end/xds/xds_wrr_end2end_test.cc
  17. 116
      test/cpp/ext/otel/otel_plugin_test.cc

@ -34,12 +34,14 @@ GlobalInstrumentsRegistry::GetInstrumentList() {
return *instruments;
}
GlobalInstrumentsRegistry::GlobalUInt64CounterHandle
GlobalInstrumentsRegistry::RegisterUInt64Counter(
GlobalInstrumentsRegistry::InstrumentID
GlobalInstrumentsRegistry::RegisterInstrument(
GlobalInstrumentsRegistry::ValueType value_type,
GlobalInstrumentsRegistry::InstrumentType instrument_type,
absl::string_view name, absl::string_view description,
absl::string_view unit, absl::Span<const absl::string_view> label_keys,
absl::Span<const absl::string_view> optional_label_keys,
bool enable_by_default) {
absl::string_view unit, bool enable_by_default,
absl::Span<const absl::string_view> label_keys,
absl::Span<const absl::string_view> optional_label_keys) {
auto& instruments = GetInstrumentList();
for (const auto& descriptor : instruments) {
if (descriptor.name == name) {
@ -47,11 +49,11 @@ GlobalInstrumentsRegistry::RegisterUInt64Counter(
absl::StrFormat("Metric name %s has already been registered.", name));
}
}
uint32_t index = instruments.size();
InstrumentID index = instruments.size();
CHECK_LT(index, std::numeric_limits<uint32_t>::max());
GlobalInstrumentDescriptor descriptor;
descriptor.value_type = ValueType::kUInt64;
descriptor.instrument_type = InstrumentType::kCounter;
descriptor.value_type = value_type;
descriptor.instrument_type = instrument_type;
descriptor.index = index;
descriptor.enable_by_default = enable_by_default;
descriptor.name = name;
@ -61,169 +63,7 @@ GlobalInstrumentsRegistry::RegisterUInt64Counter(
descriptor.optional_label_keys = {optional_label_keys.begin(),
optional_label_keys.end()};
instruments.push_back(std::move(descriptor));
GlobalUInt64CounterHandle handle;
handle.index = index;
return handle;
}
GlobalInstrumentsRegistry::GlobalDoubleCounterHandle
GlobalInstrumentsRegistry::RegisterDoubleCounter(
absl::string_view name, absl::string_view description,
absl::string_view unit, absl::Span<const absl::string_view> label_keys,
absl::Span<const absl::string_view> optional_label_keys,
bool enable_by_default) {
auto& instruments = GetInstrumentList();
for (const auto& descriptor : instruments) {
if (descriptor.name == name) {
Crash(
absl::StrFormat("Metric name %s has already been registered.", name));
}
}
uint32_t index = instruments.size();
CHECK_LT(index, std::numeric_limits<uint32_t>::max());
GlobalInstrumentDescriptor descriptor;
descriptor.value_type = ValueType::kDouble;
descriptor.instrument_type = InstrumentType::kCounter;
descriptor.index = index;
descriptor.enable_by_default = enable_by_default;
descriptor.name = name;
descriptor.description = description;
descriptor.unit = unit;
descriptor.label_keys = {label_keys.begin(), label_keys.end()};
descriptor.optional_label_keys = {optional_label_keys.begin(),
optional_label_keys.end()};
instruments.push_back(std::move(descriptor));
GlobalDoubleCounterHandle handle;
handle.index = index;
return handle;
}
GlobalInstrumentsRegistry::GlobalUInt64HistogramHandle
GlobalInstrumentsRegistry::RegisterUInt64Histogram(
absl::string_view name, absl::string_view description,
absl::string_view unit, absl::Span<const absl::string_view> label_keys,
absl::Span<const absl::string_view> optional_label_keys,
bool enable_by_default) {
auto& instruments = GetInstrumentList();
for (const auto& descriptor : instruments) {
if (descriptor.name == name) {
Crash(
absl::StrFormat("Metric name %s has already been registered.", name));
}
}
uint32_t index = instruments.size();
CHECK_LT(index, std::numeric_limits<uint32_t>::max());
GlobalInstrumentDescriptor descriptor;
descriptor.value_type = ValueType::kUInt64;
descriptor.instrument_type = InstrumentType::kHistogram;
descriptor.index = index;
descriptor.enable_by_default = enable_by_default;
descriptor.name = name;
descriptor.description = description;
descriptor.unit = unit;
descriptor.label_keys = {label_keys.begin(), label_keys.end()};
descriptor.optional_label_keys = {optional_label_keys.begin(),
optional_label_keys.end()};
instruments.push_back(std::move(descriptor));
GlobalUInt64HistogramHandle handle;
handle.index = index;
return handle;
}
GlobalInstrumentsRegistry::GlobalDoubleHistogramHandle
GlobalInstrumentsRegistry::RegisterDoubleHistogram(
absl::string_view name, absl::string_view description,
absl::string_view unit, absl::Span<const absl::string_view> label_keys,
absl::Span<const absl::string_view> optional_label_keys,
bool enable_by_default) {
auto& instruments = GetInstrumentList();
for (const auto& descriptor : instruments) {
if (descriptor.name == name) {
Crash(
absl::StrFormat("Metric name %s has already been registered.", name));
}
}
uint32_t index = instruments.size();
CHECK_LT(index, std::numeric_limits<uint32_t>::max());
GlobalInstrumentDescriptor descriptor;
descriptor.value_type = ValueType::kDouble;
descriptor.instrument_type = InstrumentType::kHistogram;
descriptor.index = index;
descriptor.enable_by_default = enable_by_default;
descriptor.name = name;
descriptor.description = description;
descriptor.unit = unit;
descriptor.label_keys = {label_keys.begin(), label_keys.end()};
descriptor.optional_label_keys = {optional_label_keys.begin(),
optional_label_keys.end()};
instruments.push_back(std::move(descriptor));
GlobalDoubleHistogramHandle handle;
handle.index = index;
return handle;
}
GlobalInstrumentsRegistry::GlobalCallbackInt64GaugeHandle
GlobalInstrumentsRegistry::RegisterCallbackInt64Gauge(
absl::string_view name, absl::string_view description,
absl::string_view unit, absl::Span<const absl::string_view> label_keys,
absl::Span<const absl::string_view> optional_label_keys,
bool enable_by_default) {
auto& instruments = GetInstrumentList();
for (const auto& descriptor : instruments) {
if (descriptor.name == name) {
Crash(
absl::StrFormat("Metric name %s has already been registered.", name));
}
}
uint32_t index = instruments.size();
CHECK_LT(index, std::numeric_limits<uint32_t>::max());
GlobalInstrumentDescriptor descriptor;
descriptor.value_type = ValueType::kInt64;
descriptor.instrument_type = InstrumentType::kCallbackGauge;
descriptor.index = index;
descriptor.enable_by_default = enable_by_default;
descriptor.name = name;
descriptor.description = description;
descriptor.unit = unit;
descriptor.label_keys = {label_keys.begin(), label_keys.end()};
descriptor.optional_label_keys = {optional_label_keys.begin(),
optional_label_keys.end()};
instruments.push_back(std::move(descriptor));
GlobalCallbackInt64GaugeHandle handle;
handle.index = index;
return handle;
}
GlobalInstrumentsRegistry::GlobalCallbackDoubleGaugeHandle
GlobalInstrumentsRegistry::RegisterCallbackDoubleGauge(
absl::string_view name, absl::string_view description,
absl::string_view unit, absl::Span<const absl::string_view> label_keys,
absl::Span<const absl::string_view> optional_label_keys,
bool enable_by_default) {
auto& instruments = GetInstrumentList();
for (const auto& descriptor : instruments) {
if (descriptor.name == name) {
Crash(
absl::StrFormat("Metric name %s has already been registered.", name));
}
}
uint32_t index = instruments.size();
CHECK_LT(index, std::numeric_limits<uint32_t>::max());
GlobalInstrumentDescriptor descriptor;
descriptor.value_type = ValueType::kDouble;
descriptor.instrument_type = InstrumentType::kCallbackGauge;
descriptor.index = index;
descriptor.enable_by_default = enable_by_default;
descriptor.name = name;
descriptor.description = description;
descriptor.unit = unit;
descriptor.label_keys = {label_keys.begin(), label_keys.end()};
descriptor.optional_label_keys = {optional_label_keys.begin(),
optional_label_keys.end()};
instruments.push_back(std::move(descriptor));
GlobalCallbackDoubleGaugeHandle handle;
handle.index = index;
return handle;
return index;
}
void GlobalInstrumentsRegistry::ForEach(
@ -242,7 +82,7 @@ GlobalInstrumentsRegistry::GetInstrumentDescriptor(
RegisteredMetricCallback::RegisteredMetricCallback(
GlobalStatsPluginRegistry::StatsPluginGroup& stats_plugin_group,
absl::AnyInvocable<void(CallbackMetricReporter&)> callback,
std::vector<GlobalInstrumentsRegistry::GlobalCallbackHandle> metrics,
std::vector<GlobalInstrumentsRegistry::GlobalInstrumentHandle> metrics,
Duration min_interval)
: stats_plugin_group_(stats_plugin_group),
callback_(std::move(callback)),
@ -259,15 +99,6 @@ RegisteredMetricCallback::~RegisteredMetricCallback() {
}
}
std::unique_ptr<RegisteredMetricCallback>
GlobalStatsPluginRegistry::StatsPluginGroup::RegisterCallback(
absl::AnyInvocable<void(CallbackMetricReporter&)> callback,
std::vector<GlobalInstrumentsRegistry::GlobalCallbackHandle> metrics,
Duration min_interval) {
return std::make_unique<RegisteredMetricCallback>(
*this, std::move(callback), std::move(metrics), min_interval);
}
void GlobalStatsPluginRegistry::StatsPluginGroup::AddClientCallTracers(
const Slice& path, bool registered_method,
grpc_call_context_element* call_context) {

@ -17,6 +17,7 @@
#include <cstdint>
#include <memory>
#include <type_traits>
#include <vector>
#include "absl/functional/any_invocable.h"
@ -45,6 +46,27 @@ constexpr absl::string_view kMetricLabelTarget = "grpc.target";
// startup, before the execution of the main function (during dynamic
// initialization time). Using this API after the main function begins may
// result into missing instruments. This API is thread-unsafe.
//
// The registration of instruments is done through the templated
// RegistrationBuilder API and gets back a handle with an opaque type. At
// runtime, the handle should be used with the StatsPluginGroup API to record
// metrics for the instruments.
//
// At dynamic initialization time:
// const auto kMetricHandle =
// GlobalInstrumentsRegistry::RegisterUInt64Counter(
// "name",
// "description",
// "unit", /*enable_by_default=*/false)
// .Labels(kLabel1, kLabel2, kLabel3)
// .OptionalLabels(kOptionalLabel1, kOptionalLabel2)
// .Build();
//
// At runtime time:
// stats_plugin_group.AddCounter(kMetricHandle, 1,
// {"label_value_1", "label_value_2", "label_value_3"},
// {"optional_label_value_1", "optional_label_value_2"});
//
class GlobalInstrumentsRegistry {
public:
enum class ValueType {
@ -78,46 +100,113 @@ class GlobalInstrumentsRegistry {
// runs or between different versions.
InstrumentID index;
};
struct GlobalUInt64CounterHandle : public GlobalInstrumentHandle {};
struct GlobalDoubleCounterHandle : public GlobalInstrumentHandle {};
struct GlobalUInt64HistogramHandle : public GlobalInstrumentHandle {};
struct GlobalDoubleHistogramHandle : public GlobalInstrumentHandle {};
struct GlobalCallbackInt64GaugeHandle : public GlobalInstrumentHandle {};
struct GlobalCallbackDoubleGaugeHandle : public GlobalInstrumentHandle {};
using GlobalCallbackHandle = absl::variant<GlobalCallbackInt64GaugeHandle,
GlobalCallbackDoubleGaugeHandle>;
template <ValueType V, InstrumentType I, size_t M, size_t N>
struct TypedGlobalInstrumentHandle : public GlobalInstrumentHandle {};
template <ValueType V, InstrumentType I, std::size_t M, std::size_t N>
class RegistrationBuilder {
public:
template <typename... Args>
RegistrationBuilder<V, I, sizeof...(Args), N> Labels(Args&&... args) {
return RegistrationBuilder<V, I, sizeof...(Args), N>(
name_, description_, unit_, enable_by_default_,
std::array<absl::string_view, sizeof...(Args)>({args...}),
optional_label_keys_);
}
template <typename... Args>
RegistrationBuilder<V, I, M, sizeof...(Args)> OptionalLabels(
Args&&... args) {
return RegistrationBuilder<V, I, M, sizeof...(Args)>(
name_, description_, unit_, enable_by_default_, label_keys_,
std::array<absl::string_view, sizeof...(Args)>({args...}));
}
TypedGlobalInstrumentHandle<V, I, M, N> Build() {
TypedGlobalInstrumentHandle<V, I, M, N> handle;
handle.index = RegisterInstrument(V, I, name_, description_, unit_,
enable_by_default_, label_keys_,
optional_label_keys_);
return handle;
}
private:
friend class GlobalInstrumentsRegistry;
RegistrationBuilder(absl::string_view name, absl::string_view description,
absl::string_view unit, bool enable_by_default)
: name_(name),
description_(description),
unit_(unit),
enable_by_default_(enable_by_default) {}
RegistrationBuilder(absl::string_view name, absl::string_view description,
absl::string_view unit, bool enable_by_default,
std::array<absl::string_view, M> label_keys,
std::array<absl::string_view, N> optional_label_keys)
: name_(name),
description_(description),
unit_(unit),
enable_by_default_(enable_by_default),
label_keys_(std::move(label_keys)),
optional_label_keys_(std::move(optional_label_keys)) {}
absl::string_view name_;
absl::string_view description_;
absl::string_view unit_;
bool enable_by_default_;
std::array<absl::string_view, M> label_keys_;
std::array<absl::string_view, N> optional_label_keys_;
};
// Creates instrument in the GlobalInstrumentsRegistry.
static GlobalUInt64CounterHandle RegisterUInt64Counter(
absl::string_view name, absl::string_view description,
absl::string_view unit, absl::Span<const absl::string_view> label_keys,
absl::Span<const absl::string_view> optional_label_keys,
bool enable_by_default);
static GlobalDoubleCounterHandle RegisterDoubleCounter(
absl::string_view name, absl::string_view description,
absl::string_view unit, absl::Span<const absl::string_view> label_keys,
absl::Span<const absl::string_view> optional_label_keys,
bool enable_by_default);
static GlobalUInt64HistogramHandle RegisterUInt64Histogram(
absl::string_view name, absl::string_view description,
absl::string_view unit, absl::Span<const absl::string_view> label_keys,
absl::Span<const absl::string_view> optional_label_keys,
bool enable_by_default);
static GlobalDoubleHistogramHandle RegisterDoubleHistogram(
absl::string_view name, absl::string_view description,
absl::string_view unit, absl::Span<const absl::string_view> label_keys,
absl::Span<const absl::string_view> optional_label_keys,
bool enable_by_default);
static GlobalCallbackInt64GaugeHandle RegisterCallbackInt64Gauge(
absl::string_view name, absl::string_view description,
absl::string_view unit, absl::Span<const absl::string_view> label_keys,
absl::Span<const absl::string_view> optional_label_keys,
bool enable_by_default);
static GlobalCallbackDoubleGaugeHandle RegisterCallbackDoubleGauge(
absl::string_view name, absl::string_view description,
absl::string_view unit, absl::Span<const absl::string_view> label_keys,
absl::Span<const absl::string_view> optional_label_keys,
bool enable_by_default);
static RegistrationBuilder<ValueType::kUInt64, InstrumentType::kCounter, 0, 0>
RegisterUInt64Counter(absl::string_view name, absl::string_view description,
absl::string_view unit, bool enable_by_default) {
return RegistrationBuilder<ValueType::kUInt64, InstrumentType::kCounter, 0,
0>(name, description, unit, enable_by_default);
}
static RegistrationBuilder<ValueType::kDouble, InstrumentType::kCounter, 0, 0>
RegisterDoubleCounter(absl::string_view name, absl::string_view description,
absl::string_view unit, bool enable_by_default) {
return RegistrationBuilder<ValueType::kDouble, InstrumentType::kCounter, 0,
0>(name, description, unit, enable_by_default);
}
static RegistrationBuilder<ValueType::kUInt64, InstrumentType::kHistogram, 0,
0>
RegisterUInt64Histogram(absl::string_view name, absl::string_view description,
absl::string_view unit, bool enable_by_default) {
return RegistrationBuilder<ValueType::kUInt64, InstrumentType::kHistogram,
0, 0>(name, description, unit,
enable_by_default);
}
static RegistrationBuilder<ValueType::kDouble, InstrumentType::kHistogram, 0,
0>
RegisterDoubleHistogram(absl::string_view name, absl::string_view description,
absl::string_view unit, bool enable_by_default) {
return RegistrationBuilder<ValueType::kDouble, InstrumentType::kHistogram,
0, 0>(name, description, unit,
enable_by_default);
}
static RegistrationBuilder<ValueType::kInt64, InstrumentType::kCallbackGauge,
0, 0>
RegisterCallbackInt64Gauge(absl::string_view name,
absl::string_view description,
absl::string_view unit, bool enable_by_default) {
return RegistrationBuilder<ValueType::kInt64,
InstrumentType::kCallbackGauge, 0, 0>(
name, description, unit, enable_by_default);
}
static RegistrationBuilder<ValueType::kDouble, InstrumentType::kCallbackGauge,
0, 0>
RegisterCallbackDoubleGauge(absl::string_view name,
absl::string_view description,
absl::string_view unit, bool enable_by_default) {
return RegistrationBuilder<ValueType::kDouble,
InstrumentType::kCallbackGauge, 0, 0>(
name, description, unit, enable_by_default);
}
static void ForEach(
absl::FunctionRef<void(const GlobalInstrumentDescriptor&)> f);
@ -131,6 +220,12 @@ class GlobalInstrumentsRegistry {
static std::vector<GlobalInstrumentsRegistry::GlobalInstrumentDescriptor>&
GetInstrumentList();
static InstrumentID RegisterInstrument(
ValueType value_type, InstrumentType instrument_type,
absl::string_view name, absl::string_view description,
absl::string_view unit, bool enable_by_default,
absl::Span<const absl::string_view> label_keys,
absl::Span<const absl::string_view> optional_label_keys);
};
// An interface for implementing callback-style metrics.
@ -139,13 +234,35 @@ class CallbackMetricReporter {
public:
virtual ~CallbackMetricReporter() = default;
virtual void Report(
GlobalInstrumentsRegistry::GlobalCallbackInt64GaugeHandle handle,
int64_t value, absl::Span<const absl::string_view> label_values,
template <std::size_t M, std::size_t N>
void Report(
GlobalInstrumentsRegistry::TypedGlobalInstrumentHandle<
GlobalInstrumentsRegistry::ValueType::kInt64,
GlobalInstrumentsRegistry::InstrumentType::kCallbackGauge, M, N>
handle,
int64_t value, std::array<absl::string_view, M> label_values,
std::array<absl::string_view, N> optional_values) {
ReportInt64(handle, value, label_values, optional_values);
}
template <std::size_t M, std::size_t N>
void Report(
GlobalInstrumentsRegistry::TypedGlobalInstrumentHandle<
GlobalInstrumentsRegistry::ValueType::kDouble,
GlobalInstrumentsRegistry::InstrumentType::kCallbackGauge, M, N>
handle,
double value, std::array<absl::string_view, M> label_values,
std::array<absl::string_view, N> optional_values) {
ReportDouble(handle, value, label_values, optional_values);
}
private:
virtual void ReportInt64(
GlobalInstrumentsRegistry::GlobalInstrumentHandle handle, int64_t value,
absl::Span<const absl::string_view> label_values,
absl::Span<const absl::string_view> optional_values) = 0;
virtual void Report(
GlobalInstrumentsRegistry::GlobalCallbackDoubleGaugeHandle handle,
double value, absl::Span<const absl::string_view> label_values,
virtual void ReportDouble(
GlobalInstrumentsRegistry::GlobalInstrumentHandle handle, double value,
absl::Span<const absl::string_view> label_values,
absl::Span<const absl::string_view> optional_values) = 0;
};
@ -179,15 +296,15 @@ class StatsPlugin {
// this measurement and must match with their corresponding keys in
// GlobalInstrumentsRegistry::RegisterUInt64Counter().
virtual void AddCounter(
GlobalInstrumentsRegistry::GlobalUInt64CounterHandle handle,
uint64_t value, absl::Span<const absl::string_view> label_values,
GlobalInstrumentsRegistry::GlobalInstrumentHandle handle, uint64_t value,
absl::Span<const absl::string_view> label_values,
absl::Span<const absl::string_view> optional_label_values) = 0;
// Adds \a value to the double counter specified by \a handle. \a label_values
// and \a optional_label_values specify attributes that are associated with
// this measurement and must match with their corresponding keys in
// GlobalInstrumentsRegistry::RegisterDoubleCounter().
virtual void AddCounter(
GlobalInstrumentsRegistry::GlobalDoubleCounterHandle handle, double value,
GlobalInstrumentsRegistry::GlobalInstrumentHandle handle, double value,
absl::Span<const absl::string_view> label_values,
absl::Span<const absl::string_view> optional_label_values) = 0;
// Records a uint64 \a value to the histogram specified by \a handle. \a
@ -195,16 +312,16 @@ class StatsPlugin {
// associated with this measurement and must match with their corresponding
// keys in GlobalInstrumentsRegistry::RegisterUInt64Histogram().
virtual void RecordHistogram(
GlobalInstrumentsRegistry::GlobalUInt64HistogramHandle handle,
uint64_t value, absl::Span<const absl::string_view> label_values,
GlobalInstrumentsRegistry::GlobalInstrumentHandle handle, uint64_t value,
absl::Span<const absl::string_view> label_values,
absl::Span<const absl::string_view> optional_label_values) = 0;
// Records a double \a value to the histogram specified by \a handle. \a
// label_values and \a optional_label_values specify attributes that are
// associated with this measurement and must match with their corresponding
// keys in GlobalInstrumentsRegistry::RegisterDoubleHistogram().
virtual void RecordHistogram(
GlobalInstrumentsRegistry::GlobalDoubleHistogramHandle handle,
double value, absl::Span<const absl::string_view> label_values,
GlobalInstrumentsRegistry::GlobalInstrumentHandle handle, double value,
absl::Span<const absl::string_view> label_values,
absl::Span<const absl::string_view> optional_label_values) = 0;
// Adds a callback to be invoked when the stats plugin wants to
// populate the corresponding metrics (see callback->metrics() for list).
@ -255,20 +372,53 @@ class GlobalStatsPluginRegistry {
}
// Adds a counter in all stats plugins within the group. See the StatsPlugin
// interface for more documentation and valid types.
template <class HandleType, class ValueType>
void AddCounter(HandleType handle, ValueType value,
absl::Span<const absl::string_view> label_values,
absl::Span<const absl::string_view> optional_values) {
template <std::size_t M, std::size_t N>
void AddCounter(
GlobalInstrumentsRegistry::TypedGlobalInstrumentHandle<
GlobalInstrumentsRegistry::ValueType::kUInt64,
GlobalInstrumentsRegistry::InstrumentType::kCounter, M, N>
handle,
uint64_t value, std::array<absl::string_view, M> label_values,
std::array<absl::string_view, N> optional_values) {
for (auto& state : plugins_state_) {
state.plugin->AddCounter(handle, value, label_values, optional_values);
}
}
template <std::size_t M, std::size_t N>
void AddCounter(
GlobalInstrumentsRegistry::TypedGlobalInstrumentHandle<
GlobalInstrumentsRegistry::ValueType::kDouble,
GlobalInstrumentsRegistry::InstrumentType::kCounter, M, N>
handle,
double value, std::array<absl::string_view, M> label_values,
std::array<absl::string_view, N> optional_values) {
for (auto& state : plugins_state_) {
state.plugin->AddCounter(handle, value, label_values, optional_values);
}
}
// Records a value to a histogram in all stats plugins within the group. See
// the StatsPlugin interface for more documentation and valid types.
template <class HandleType, class ValueType>
void RecordHistogram(HandleType handle, ValueType value,
absl::Span<const absl::string_view> label_values,
absl::Span<const absl::string_view> optional_values) {
template <std::size_t M, std::size_t N>
void RecordHistogram(
GlobalInstrumentsRegistry::TypedGlobalInstrumentHandle<
GlobalInstrumentsRegistry::ValueType::kUInt64,
GlobalInstrumentsRegistry::InstrumentType::kHistogram, M, N>
handle,
uint64_t value, std::array<absl::string_view, M> label_values,
std::array<absl::string_view, N> optional_values) {
for (auto& state : plugins_state_) {
state.plugin->RecordHistogram(handle, value, label_values,
optional_values);
}
}
template <std::size_t M, std::size_t N>
void RecordHistogram(
GlobalInstrumentsRegistry::TypedGlobalInstrumentHandle<
GlobalInstrumentsRegistry::ValueType::kDouble,
GlobalInstrumentsRegistry::InstrumentType::kHistogram, M, N>
handle,
double value, std::array<absl::string_view, M> label_values,
std::array<absl::string_view, N> optional_values) {
for (auto& state : plugins_state_) {
state.plugin->RecordHistogram(handle, value, label_values,
optional_values);
@ -285,11 +435,17 @@ class GlobalStatsPluginRegistry {
// the lifetime of the callback; when the returned object is
// destroyed, the callback is de-registered. The returned object
// must not outlive the StatsPluginGroup object that created it.
template <typename... Args>
GRPC_MUST_USE_RESULT std::unique_ptr<RegisteredMetricCallback>
RegisterCallback(
absl::AnyInvocable<void(CallbackMetricReporter&)> callback,
std::vector<GlobalInstrumentsRegistry::GlobalCallbackHandle> metrics,
Duration min_interval = Duration::Seconds(5));
RegisterCallback(absl::AnyInvocable<void(CallbackMetricReporter&)> callback,
Duration min_interval, Args... args) {
AssertIsCallbackGaugeHandle(args...);
return std::make_unique<RegisteredMetricCallback>(
*this, std::move(callback),
std::vector<GlobalInstrumentsRegistry::GlobalInstrumentHandle>{
args...},
min_interval);
}
// Adds all available client call tracers associated with the stats plugins
// within the group to \a call_context.
@ -307,6 +463,24 @@ class GlobalStatsPluginRegistry {
std::shared_ptr<StatsPlugin> plugin;
};
// C++17 has fold expression that may simplify this.
template <GlobalInstrumentsRegistry::ValueType V,
GlobalInstrumentsRegistry::InstrumentType I, size_t M, size_t N>
static constexpr void AssertIsCallbackGaugeHandle(
GlobalInstrumentsRegistry::TypedGlobalInstrumentHandle<V, I, M, N>) {
static_assert(V == GlobalInstrumentsRegistry::ValueType::kInt64 ||
V == GlobalInstrumentsRegistry::ValueType::kDouble,
"ValueType must be kInt64 or kDouble");
static_assert(
I == GlobalInstrumentsRegistry::InstrumentType::kCallbackGauge,
"InstrumentType must be kCallbackGauge");
}
template <typename T, typename... Args>
static constexpr void AssertIsCallbackGaugeHandle(T t, Args&&... args) {
AssertIsCallbackGaugeHandle(t);
AssertIsCallbackGaugeHandle(args...);
}
std::vector<PluginState> plugins_state_;
};
@ -335,7 +509,7 @@ class RegisteredMetricCallback {
RegisteredMetricCallback(
GlobalStatsPluginRegistry::StatsPluginGroup& stats_plugin_group,
absl::AnyInvocable<void(CallbackMetricReporter&)> callback,
std::vector<GlobalInstrumentsRegistry::GlobalCallbackHandle> metrics,
std::vector<GlobalInstrumentsRegistry::GlobalInstrumentHandle> metrics,
Duration min_interval);
~RegisteredMetricCallback();
@ -344,8 +518,8 @@ class RegisteredMetricCallback {
void Run(CallbackMetricReporter& reporter) { callback_(reporter); }
// Returns the set of metrics that this callback will modify.
const std::vector<GlobalInstrumentsRegistry::GlobalCallbackHandle>& metrics()
const {
const std::vector<GlobalInstrumentsRegistry::GlobalInstrumentHandle>&
metrics() const {
return metrics_;
}
@ -356,7 +530,7 @@ class RegisteredMetricCallback {
private:
GlobalStatsPluginRegistry::StatsPluginGroup& stats_plugin_group_;
absl::AnyInvocable<void(CallbackMetricReporter&)> callback_;
std::vector<GlobalInstrumentsRegistry::GlobalCallbackHandle> metrics_;
std::vector<GlobalInstrumentsRegistry::GlobalInstrumentHandle> metrics_;
Duration min_interval_;
};

@ -84,19 +84,25 @@ const auto kMetricDisconnections =
"grpc.lb.pick_first.disconnections",
"EXPERIMENTAL. Number of times the selected subchannel becomes "
"disconnected.",
"{disconnection}", {kMetricLabelTarget}, {}, false);
"{disconnection}", false)
.Labels(kMetricLabelTarget)
.Build();
const auto kMetricConnectionAttemptsSucceeded =
GlobalInstrumentsRegistry::RegisterUInt64Counter(
"grpc.lb.pick_first.connection_attempts_succeeded",
"EXPERIMENTAL. Number of successful connection attempts.", "{attempt}",
{kMetricLabelTarget}, {}, false);
false)
.Labels(kMetricLabelTarget)
.Build();
const auto kMetricConnectionAttemptsFailed =
GlobalInstrumentsRegistry::RegisterUInt64Counter(
"grpc.lb.pick_first.connection_attempts_failed",
"EXPERIMENTAL. Number of failed connection attempts.", "{attempt}",
{kMetricLabelTarget}, {}, false);
false)
.Labels(kMetricLabelTarget)
.Build();
class PickFirstConfig final : public LoadBalancingPolicy::Config {
public:

@ -128,26 +128,27 @@ constexpr absl::string_view kMetricLabelPickResult = "grpc.lb.pick_result";
const auto kMetricCacheSize =
GlobalInstrumentsRegistry::RegisterCallbackInt64Gauge(
"grpc.lb.rls.cache_size", "EXPERIMENTAL. Size of the RLS cache.", "By",
{kMetricLabelTarget, kMetricLabelRlsServerTarget,
kMetricLabelRlsInstanceUuid},
{}, false);
false)
.Labels(kMetricLabelTarget, kMetricLabelRlsServerTarget,
kMetricLabelRlsInstanceUuid)
.Build();
const auto kMetricCacheEntries =
GlobalInstrumentsRegistry::RegisterCallbackInt64Gauge(
"grpc.lb.rls.cache_entries",
"EXPERIMENTAL. Number of entries in the RLS cache.", "{entry}",
{kMetricLabelTarget, kMetricLabelRlsServerTarget,
kMetricLabelRlsInstanceUuid},
{}, false);
"EXPERIMENTAL. Number of entries in the RLS cache.", "{entry}", false)
.Labels(kMetricLabelTarget, kMetricLabelRlsServerTarget,
kMetricLabelRlsInstanceUuid)
.Build();
const auto kMetricDefaultTargetPicks =
GlobalInstrumentsRegistry::RegisterUInt64Counter(
"grpc.lb.rls.default_target_picks",
"EXPERIMENTAL. Number of LB picks sent to the default target.",
"{pick}",
{kMetricLabelTarget, kMetricLabelRlsServerTarget,
kMetricRlsDataPlaneTarget, kMetricLabelPickResult},
{}, false);
"{pick}", false)
.Labels(kMetricLabelTarget, kMetricLabelRlsServerTarget,
kMetricRlsDataPlaneTarget, kMetricLabelPickResult)
.Build();
const auto kMetricTargetPicks =
GlobalInstrumentsRegistry::RegisterUInt64Counter(
@ -156,17 +157,19 @@ const auto kMetricTargetPicks =
"if the default target is also returned by the RLS server, RPCs sent "
"to that target from the cache will be counted in this metric, not "
"in grpc.rls.default_target_picks.",
"{pick}",
{kMetricLabelTarget, kMetricLabelRlsServerTarget,
kMetricRlsDataPlaneTarget, kMetricLabelPickResult},
{}, false);
"{pick}", false)
.Labels(kMetricLabelTarget, kMetricLabelRlsServerTarget,
kMetricRlsDataPlaneTarget, kMetricLabelPickResult)
.Build();
const auto kMetricFailedPicks =
GlobalInstrumentsRegistry::RegisterUInt64Counter(
"grpc.lb.rls.failed_picks",
"EXPERIMENTAL. Number of LB picks failed due to either a failed RLS "
"request or the RLS channel being throttled.",
"{pick}", {kMetricLabelTarget, kMetricLabelRlsServerTarget}, {}, false);
"{pick}", false)
.Labels(kMetricLabelTarget, kMetricLabelRlsServerTarget)
.Build();
constexpr absl::string_view kRls = "rls_experimental";
const char kGrpc[] = "grpc";
@ -754,9 +757,9 @@ class RlsLb final : public LoadBalancingPolicy {
// Updates the picker in the work serializer.
void UpdatePickerLocked() ABSL_LOCKS_EXCLUDED(&mu_);
void MaybeExportPickCount(
GlobalInstrumentsRegistry::GlobalUInt64CounterHandle handle,
absl::string_view target, const PickResult& pick_result);
template <typename HandleType>
void MaybeExportPickCount(HandleType handle, absl::string_view target,
const PickResult& pick_result);
const std::string instance_uuid_;
@ -1961,7 +1964,7 @@ RlsLb::RlsLb(Args args)
MutexLock lock(&mu_);
cache_.ReportMetricsLocked(reporter);
},
{kMetricCacheSize, kMetricCacheEntries})) {
Duration::Seconds(5), kMetricCacheSize, kMetricCacheEntries)) {
if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_rls_trace)) {
gpr_log(GPR_INFO, "[rlslb %p] policy created", this);
}
@ -2230,9 +2233,9 @@ void RlsLb::UpdatePickerLocked() {
MakeRefCounted<Picker>(RefAsSubclass<RlsLb>(DEBUG_LOCATION, "Picker")));
}
void RlsLb::MaybeExportPickCount(
GlobalInstrumentsRegistry::GlobalUInt64CounterHandle handle,
absl::string_view target, const PickResult& pick_result) {
template <typename HandleType>
void RlsLb::MaybeExportPickCount(HandleType handle, absl::string_view target,
const PickResult& pick_result) {
absl::string_view pick_result_string = Match(
pick_result.result,
[](const LoadBalancingPolicy::PickResult::Complete&) {

@ -85,12 +85,16 @@ constexpr absl::string_view kWeightedRoundRobin = "weighted_round_robin";
constexpr absl::string_view kMetricLabelLocality = "grpc.lb.locality";
const auto kMetricRrFallback = GlobalInstrumentsRegistry::RegisterUInt64Counter(
"grpc.lb.wrr.rr_fallback",
"EXPERIMENTAL. Number of scheduler updates in which there were not "
"enough endpoints with valid weight, which caused the WRR policy to "
"fall back to RR behavior.",
"{update}", {kMetricLabelTarget}, {kMetricLabelLocality}, false);
const auto kMetricRrFallback =
GlobalInstrumentsRegistry::RegisterUInt64Counter(
"grpc.lb.wrr.rr_fallback",
"EXPERIMENTAL. Number of scheduler updates in which there were not "
"enough endpoints with valid weight, which caused the WRR policy to "
"fall back to RR behavior.",
"{update}", false)
.Labels(kMetricLabelTarget)
.OptionalLabels(kMetricLabelLocality)
.Build();
const auto kMetricEndpointWeightNotYetUsable =
GlobalInstrumentsRegistry::RegisterUInt64Counter(
@ -99,14 +103,20 @@ const auto kMetricEndpointWeightNotYetUsable =
"don't yet have usable weight information (i.e., either the load "
"report has not yet been received, or it is within the blackout "
"period).",
"{endpoint}", {kMetricLabelTarget}, {kMetricLabelLocality}, false);
"{endpoint}", false)
.Labels(kMetricLabelTarget)
.OptionalLabels(kMetricLabelLocality)
.Build();
const auto kMetricEndpointWeightStale =
GlobalInstrumentsRegistry::RegisterUInt64Counter(
"grpc.lb.wrr.endpoint_weight_stale",
"EXPERIMENTAL. Number of endpoints from each scheduler update whose "
"latest weight is older than the expiration period.",
"{endpoint}", {kMetricLabelTarget}, {kMetricLabelLocality}, false);
"{endpoint}", false)
.Labels(kMetricLabelTarget)
.OptionalLabels(kMetricLabelLocality)
.Build();
const auto kMetricEndpointWeights =
GlobalInstrumentsRegistry::RegisterDoubleHistogram(
@ -115,7 +125,10 @@ const auto kMetricEndpointWeights =
"Each bucket will be a counter that is incremented once for every "
"endpoint whose weight is within that range. Note that endpoints "
"without usable weights will have weight 0.",
"{weight}", {kMetricLabelTarget}, {kMetricLabelLocality}, false);
"{weight}", false)
.Labels(kMetricLabelTarget)
.OptionalLabels(kMetricLabelLocality)
.Build();
// Config for WRR policy.
class WeightedRoundRobinConfig final : public LoadBalancingPolicy::Config {

@ -99,20 +99,20 @@ const auto kMetricResourceUpdatesValid =
"EXPERIMENTAL. A counter of resources received that were considered "
"valid. The counter will be incremented even for resources that "
"have not changed.",
"{resource}",
{kMetricLabelTarget, kMetricLabelXdsServer,
kMetricLabelXdsResourceType},
{}, false);
"{resource}", false)
.Labels(kMetricLabelTarget, kMetricLabelXdsServer,
kMetricLabelXdsResourceType)
.Build();
const auto kMetricResourceUpdatesInvalid =
GlobalInstrumentsRegistry::RegisterUInt64Counter(
"grpc.xds_client.resource_updates_invalid",
"EXPERIMENTAL. A counter of resources received that were considered "
"invalid.",
"{resource}",
{kMetricLabelTarget, kMetricLabelXdsServer,
kMetricLabelXdsResourceType},
{}, false);
"{resource}", false)
.Labels(kMetricLabelTarget, kMetricLabelXdsServer,
kMetricLabelXdsResourceType)
.Build();
const auto kMetricServerFailure =
GlobalInstrumentsRegistry::RegisterUInt64Counter(
@ -121,7 +121,9 @@ const auto kMetricServerFailure =
"unhealthy. A server goes unhealthy when we have a connectivity "
"failure or when the ADS stream fails without seeing a response "
"message, as per gRFC A57.",
"{failure}", {kMetricLabelTarget, kMetricLabelXdsServer}, {}, false);
"{failure}", false)
.Labels(kMetricLabelTarget, kMetricLabelXdsServer)
.Build();
const auto kMetricConnected =
GlobalInstrumentsRegistry::RegisterCallbackInt64Gauge(
@ -132,15 +134,17 @@ const auto kMetricConnected =
"ADS stream fails without seeing a response message, as per gRFC "
"A57. It will be set to 1 when we receive the first response on "
"an ADS stream.",
"{bool}", {kMetricLabelTarget, kMetricLabelXdsServer}, {}, false);
"{bool}", false)
.Labels(kMetricLabelTarget, kMetricLabelXdsServer)
.Build();
const auto kMetricResources =
GlobalInstrumentsRegistry::RegisterCallbackInt64Gauge(
"grpc.xds_client.resources", "EXPERIMENTAL. Number of xDS resources.",
"{resource}",
{kMetricLabelTarget, kMetricLabelXdsAuthority,
kMetricLabelXdsResourceType, kMetricLabelXdsCacheState},
{}, false);
"{resource}", false)
.Labels(kMetricLabelTarget, kMetricLabelXdsAuthority,
kMetricLabelXdsResourceType, kMetricLabelXdsCacheState)
.Build();
} // namespace
@ -316,7 +320,7 @@ GrpcXdsClient::GrpcXdsClient(
[this](CallbackMetricReporter& reporter) {
ReportCallbackMetrics(reporter);
},
{kMetricConnected, kMetricResources})) {}
Duration::Seconds(5), kMetricConnected, kMetricResources)) {}
void GrpcXdsClient::Orphaned() {
registered_metric_callback_.reset();

@ -249,27 +249,35 @@ OpenTelemetryPlugin::CallbackMetricReporter::CallbackMetricReporter(
// that if a particular combination of labels was previously present but
// is no longer present, we won't continue to report it.
for (const auto& handle : key->metrics()) {
grpc_core::Match(
handle,
[&](const grpc_core::GlobalInstrumentsRegistry::
GlobalCallbackInt64GaugeHandle& handle) {
auto& callback_gauge_state =
absl::get<std::unique_ptr<CallbackGaugeState<int64_t>>>(
ot_plugin_->instruments_data_.at(handle.index).instrument);
callback_gauge_state->caches[key].clear();
},
[&](const grpc_core::GlobalInstrumentsRegistry::
GlobalCallbackDoubleGaugeHandle& handle) {
auto& callback_gauge_state =
absl::get<std::unique_ptr<CallbackGaugeState<double>>>(
ot_plugin_->instruments_data_.at(handle.index).instrument);
callback_gauge_state->caches[key].clear();
});
const auto& descriptor =
grpc_core::GlobalInstrumentsRegistry::GetInstrumentDescriptor(handle);
GPR_ASSERT(
descriptor.instrument_type ==
grpc_core::GlobalInstrumentsRegistry::InstrumentType::kCallbackGauge);
switch (descriptor.value_type) {
case grpc_core::GlobalInstrumentsRegistry::ValueType::kInt64: {
auto& callback_gauge_state =
absl::get<std::unique_ptr<CallbackGaugeState<int64_t>>>(
ot_plugin_->instruments_data_.at(handle.index).instrument);
callback_gauge_state->caches[key].clear();
break;
}
case grpc_core::GlobalInstrumentsRegistry::ValueType::kDouble: {
auto& callback_gauge_state =
absl::get<std::unique_ptr<CallbackGaugeState<double>>>(
ot_plugin_->instruments_data_.at(handle.index).instrument);
callback_gauge_state->caches[key].clear();
break;
}
default:
grpc_core::Crash(absl::StrFormat(
"Unknown or unsupported value type: %d", descriptor.value_type));
}
}
}
void OpenTelemetryPlugin::CallbackMetricReporter::Report(
grpc_core::GlobalInstrumentsRegistry::GlobalCallbackInt64GaugeHandle handle,
void OpenTelemetryPlugin::CallbackMetricReporter::ReportInt64(
grpc_core::GlobalInstrumentsRegistry::GlobalInstrumentHandle handle,
int64_t value, absl::Span<const absl::string_view> label_values,
absl::Span<const absl::string_view> optional_values) {
const auto& instrument_data = ot_plugin_->instruments_data_.at(handle.index);
@ -296,9 +304,8 @@ void OpenTelemetryPlugin::CallbackMetricReporter::Report(
cell.insert_or_assign(std::move(key), value);
}
void OpenTelemetryPlugin::CallbackMetricReporter::Report(
grpc_core::GlobalInstrumentsRegistry::GlobalCallbackDoubleGaugeHandle
handle,
void OpenTelemetryPlugin::CallbackMetricReporter::ReportDouble(
grpc_core::GlobalInstrumentsRegistry::GlobalInstrumentHandle handle,
double value, absl::Span<const absl::string_view> label_values,
absl::Span<const absl::string_view> optional_values) {
const auto& instrument_data = ot_plugin_->instruments_data_.at(handle.index);
@ -574,8 +581,8 @@ OpenTelemetryPlugin::IsEnabledForChannel(
std::pair<bool, std::shared_ptr<grpc_core::StatsPlugin::ScopeConfig>>
OpenTelemetryPlugin::IsEnabledForServer(
const grpc_core::ChannelArgs& args) const {
// Return true only if there is no server selector registered or if the server
// selector returns true.
// Return true only if there is no server selector registered or if the
// server selector returns true.
if (server_selector_ == nullptr || server_selector_(args)) {
return {true, std::make_shared<ServerScopeConfig>(this, args)};
}
@ -583,7 +590,7 @@ OpenTelemetryPlugin::IsEnabledForServer(
}
void OpenTelemetryPlugin::AddCounter(
grpc_core::GlobalInstrumentsRegistry::GlobalUInt64CounterHandle handle,
grpc_core::GlobalInstrumentsRegistry::GlobalInstrumentHandle handle,
uint64_t value, absl::Span<const absl::string_view> label_values,
absl::Span<const absl::string_view> optional_values) {
const auto& instrument_data = instruments_data_.at(handle.index);
@ -607,7 +614,7 @@ void OpenTelemetryPlugin::AddCounter(
}
void OpenTelemetryPlugin::AddCounter(
grpc_core::GlobalInstrumentsRegistry::GlobalDoubleCounterHandle handle,
grpc_core::GlobalInstrumentsRegistry::GlobalInstrumentHandle handle,
double value, absl::Span<const absl::string_view> label_values,
absl::Span<const absl::string_view> optional_values) {
const auto& instrument_data = instruments_data_.at(handle.index);
@ -631,7 +638,7 @@ void OpenTelemetryPlugin::AddCounter(
}
void OpenTelemetryPlugin::RecordHistogram(
grpc_core::GlobalInstrumentsRegistry::GlobalUInt64HistogramHandle handle,
grpc_core::GlobalInstrumentsRegistry::GlobalInstrumentHandle handle,
uint64_t value, absl::Span<const absl::string_view> label_values,
absl::Span<const absl::string_view> optional_values) {
const auto& instrument_data = instruments_data_.at(handle.index);
@ -657,7 +664,7 @@ void OpenTelemetryPlugin::RecordHistogram(
}
void OpenTelemetryPlugin::RecordHistogram(
grpc_core::GlobalInstrumentsRegistry::GlobalDoubleHistogramHandle handle,
grpc_core::GlobalInstrumentsRegistry::GlobalInstrumentHandle handle,
double value, absl::Span<const absl::string_view> label_values,
absl::Span<const absl::string_view> optional_values) {
const auto& instrument_data = instruments_data_.at(handle.index);
@ -691,51 +698,59 @@ void OpenTelemetryPlugin::AddCallback(
grpc_core::MutexLock lock(&mu_);
callback_timestamps_.emplace(callback, grpc_core::Timestamp::InfPast());
for (const auto& handle : callback->metrics()) {
grpc_core::Match(
handle,
[&](const grpc_core::GlobalInstrumentsRegistry::
GlobalCallbackInt64GaugeHandle& handle) {
const auto& instrument_data = instruments_data_.at(handle.index);
if (absl::holds_alternative<Disabled>(instrument_data.instrument)) {
// This instrument is disabled.
return;
}
auto* callback_gauge_state =
absl::get_if<std::unique_ptr<CallbackGaugeState<int64_t>>>(
&instrument_data.instrument);
CHECK_NE(callback_gauge_state, nullptr);
(*callback_gauge_state)
->caches.emplace(callback,
CallbackGaugeState<int64_t>::Cache{});
if (!std::exchange((*callback_gauge_state)->ot_callback_registered,
true)) {
gauges_that_need_to_add_callback.push_back(
callback_gauge_state->get());
}
},
[&](const grpc_core::GlobalInstrumentsRegistry::
GlobalCallbackDoubleGaugeHandle& handle) {
const auto& instrument_data = instruments_data_.at(handle.index);
if (absl::holds_alternative<Disabled>(instrument_data.instrument)) {
// This instrument is disabled.
return;
}
auto* callback_gauge_state =
absl::get_if<std::unique_ptr<CallbackGaugeState<double>>>(
&instrument_data.instrument);
CHECK_NE(callback_gauge_state, nullptr);
(*callback_gauge_state)
->caches.emplace(callback, CallbackGaugeState<double>::Cache{});
if (!std::exchange((*callback_gauge_state)->ot_callback_registered,
true)) {
gauges_that_need_to_add_callback.push_back(
callback_gauge_state->get());
}
});
const auto& descriptor =
grpc_core::GlobalInstrumentsRegistry::GetInstrumentDescriptor(handle);
GPR_ASSERT(
descriptor.instrument_type ==
grpc_core::GlobalInstrumentsRegistry::InstrumentType::kCallbackGauge);
switch (descriptor.value_type) {
case grpc_core::GlobalInstrumentsRegistry::ValueType::kInt64: {
const auto& instrument_data = instruments_data_.at(handle.index);
if (absl::holds_alternative<Disabled>(instrument_data.instrument)) {
// This instrument is disabled.
continue;
}
auto* callback_gauge_state =
absl::get_if<std::unique_ptr<CallbackGaugeState<int64_t>>>(
&instrument_data.instrument);
CHECK_NE(callback_gauge_state, nullptr);
(*callback_gauge_state)
->caches.emplace(callback, CallbackGaugeState<int64_t>::Cache{});
if (!std::exchange((*callback_gauge_state)->ot_callback_registered,
true)) {
gauges_that_need_to_add_callback.push_back(
callback_gauge_state->get());
}
break;
}
case grpc_core::GlobalInstrumentsRegistry::ValueType::kDouble: {
const auto& instrument_data = instruments_data_.at(handle.index);
if (absl::holds_alternative<Disabled>(instrument_data.instrument)) {
// This instrument is disabled.
continue;
}
auto* callback_gauge_state =
absl::get_if<std::unique_ptr<CallbackGaugeState<double>>>(
&instrument_data.instrument);
CHECK_NE(callback_gauge_state, nullptr);
(*callback_gauge_state)
->caches.emplace(callback, CallbackGaugeState<double>::Cache{});
if (!std::exchange((*callback_gauge_state)->ot_callback_registered,
true)) {
gauges_that_need_to_add_callback.push_back(
callback_gauge_state->get());
}
break;
}
default:
grpc_core::Crash(absl::StrFormat(
"Unknown or unsupported value type: %d", descriptor.value_type));
}
}
}
// AddCallback internally grabs OpenTelemetry's observable_registry's lock. So
// we need to call it without our plugin lock otherwise we may deadlock.
// AddCallback internally grabs OpenTelemetry's observable_registry's
// lock. So we need to call it without our plugin lock otherwise we may
// deadlock.
for (const auto& gauge : gauges_that_need_to_add_callback) {
grpc_core::Match(
gauge,
@ -759,50 +774,59 @@ void OpenTelemetryPlugin::RemoveCallback(
grpc_core::MutexLock lock(&mu_);
callback_timestamps_.erase(callback);
for (const auto& handle : callback->metrics()) {
grpc_core::Match(
handle,
[&](const grpc_core::GlobalInstrumentsRegistry::
GlobalCallbackInt64GaugeHandle& handle) {
const auto& instrument_data = instruments_data_.at(handle.index);
if (absl::holds_alternative<Disabled>(instrument_data.instrument)) {
// This instrument is disabled.
return;
}
auto* callback_gauge_state =
absl::get_if<std::unique_ptr<CallbackGaugeState<int64_t>>>(
&instrument_data.instrument);
CHECK_NE(callback_gauge_state, nullptr);
CHECK((*callback_gauge_state)->ot_callback_registered);
CHECK_EQ((*callback_gauge_state)->caches.erase(callback), 1u);
if ((*callback_gauge_state)->caches.empty()) {
gauges_that_need_to_remove_callback.push_back(
callback_gauge_state->get());
(*callback_gauge_state)->ot_callback_registered = false;
}
},
[&](const grpc_core::GlobalInstrumentsRegistry::
GlobalCallbackDoubleGaugeHandle& handle) {
const auto& instrument_data = instruments_data_.at(handle.index);
if (absl::holds_alternative<Disabled>(instrument_data.instrument)) {
// This instrument is disabled.
return;
}
auto* callback_gauge_state =
absl::get_if<std::unique_ptr<CallbackGaugeState<double>>>(
&instrument_data.instrument);
CHECK_NE(callback_gauge_state, nullptr);
CHECK((*callback_gauge_state)->ot_callback_registered);
CHECK_EQ((*callback_gauge_state)->caches.erase(callback), 1u);
if ((*callback_gauge_state)->caches.empty()) {
gauges_that_need_to_remove_callback.push_back(
callback_gauge_state->get());
(*callback_gauge_state)->ot_callback_registered = false;
}
});
const auto& descriptor =
grpc_core::GlobalInstrumentsRegistry::GetInstrumentDescriptor(handle);
GPR_ASSERT(
descriptor.instrument_type ==
grpc_core::GlobalInstrumentsRegistry::InstrumentType::kCallbackGauge);
switch (descriptor.value_type) {
case grpc_core::GlobalInstrumentsRegistry::ValueType::kInt64: {
const auto& instrument_data = instruments_data_.at(handle.index);
if (absl::holds_alternative<Disabled>(instrument_data.instrument)) {
// This instrument is disabled.
continue;
}
auto* callback_gauge_state =
absl::get_if<std::unique_ptr<CallbackGaugeState<int64_t>>>(
&instrument_data.instrument);
CHECK_NE(callback_gauge_state, nullptr);
CHECK((*callback_gauge_state)->ot_callback_registered);
CHECK_EQ((*callback_gauge_state)->caches.erase(callback), 1u);
if ((*callback_gauge_state)->caches.empty()) {
gauges_that_need_to_remove_callback.push_back(
callback_gauge_state->get());
(*callback_gauge_state)->ot_callback_registered = false;
}
break;
}
case grpc_core::GlobalInstrumentsRegistry::ValueType::kDouble: {
const auto& instrument_data = instruments_data_.at(handle.index);
if (absl::holds_alternative<Disabled>(instrument_data.instrument)) {
// This instrument is disabled.
continue;
}
auto* callback_gauge_state =
absl::get_if<std::unique_ptr<CallbackGaugeState<double>>>(
&instrument_data.instrument);
CHECK_NE(callback_gauge_state, nullptr);
CHECK((*callback_gauge_state)->ot_callback_registered);
CHECK_EQ((*callback_gauge_state)->caches.erase(callback), 1u);
if ((*callback_gauge_state)->caches.empty()) {
gauges_that_need_to_remove_callback.push_back(
callback_gauge_state->get());
(*callback_gauge_state)->ot_callback_registered = false;
}
break;
}
default:
grpc_core::Crash(absl::StrFormat(
"Unknown or unsupported value type: %d", descriptor.value_type));
}
}
}
// RemoveCallback internally grabs OpenTelemetry's observable_registry's lock.
// So we need to call it without our plugin lock otherwise we may deadlock.
// RemoveCallback internally grabs OpenTelemetry's observable_registry's
// lock. So we need to call it without our plugin lock otherwise we may
// deadlock.
for (const auto& gauge : gauges_that_need_to_remove_callback) {
grpc_core::Match(
gauge,
@ -842,7 +866,8 @@ void OpenTelemetryPlugin::CallbackGaugeState<ValueType>::Observe(
}
}
// OpenTelemetry calls our callback with its observable_registry's lock held.
// OpenTelemetry calls our callback with its observable_registry's lock
// held.
template <typename ValueType>
void OpenTelemetryPlugin::CallbackGaugeState<ValueType>::CallbackGaugeCallback(
opentelemetry::metrics::ObserverResult result, void* arg) {

@ -343,22 +343,20 @@ class OpenTelemetryPlugin : public grpc_core::StatsPlugin {
grpc_core::RegisteredMetricCallback* key)
ABSL_EXCLUSIVE_LOCKS_REQUIRED(ot_plugin->mu_);
void Report(
grpc_core::GlobalInstrumentsRegistry::GlobalCallbackInt64GaugeHandle
handle,
private:
void ReportInt64(
grpc_core::GlobalInstrumentsRegistry::GlobalInstrumentHandle handle,
int64_t value, absl::Span<const absl::string_view> label_values,
absl::Span<const absl::string_view> optional_values)
ABSL_EXCLUSIVE_LOCKS_REQUIRED(
CallbackGaugeState<int64_t>::ot_plugin->mu_) override;
void Report(
grpc_core::GlobalInstrumentsRegistry::GlobalCallbackDoubleGaugeHandle
handle,
void ReportDouble(
grpc_core::GlobalInstrumentsRegistry::GlobalInstrumentHandle handle,
double value, absl::Span<const absl::string_view> label_values,
absl::Span<const absl::string_view> optional_values)
ABSL_EXCLUSIVE_LOCKS_REQUIRED(
CallbackGaugeState<double>::ot_plugin->mu_) override;
private:
OpenTelemetryPlugin* ot_plugin_;
grpc_core::RegisteredMetricCallback* key_;
};
@ -380,19 +378,19 @@ class OpenTelemetryPlugin : public grpc_core::StatsPlugin {
std::pair<bool, std::shared_ptr<grpc_core::StatsPlugin::ScopeConfig>>
IsEnabledForServer(const grpc_core::ChannelArgs& args) const override;
void AddCounter(
grpc_core::GlobalInstrumentsRegistry::GlobalUInt64CounterHandle handle,
grpc_core::GlobalInstrumentsRegistry::GlobalInstrumentHandle handle,
uint64_t value, absl::Span<const absl::string_view> label_values,
absl::Span<const absl::string_view> optional_values) override;
void AddCounter(
grpc_core::GlobalInstrumentsRegistry::GlobalDoubleCounterHandle handle,
grpc_core::GlobalInstrumentsRegistry::GlobalInstrumentHandle handle,
double value, absl::Span<const absl::string_view> label_values,
absl::Span<const absl::string_view> optional_values) override;
void RecordHistogram(
grpc_core::GlobalInstrumentsRegistry::GlobalUInt64HistogramHandle handle,
grpc_core::GlobalInstrumentsRegistry::GlobalInstrumentHandle handle,
uint64_t value, absl::Span<const absl::string_view> label_values,
absl::Span<const absl::string_view> optional_values) override;
void RecordHistogram(
grpc_core::GlobalInstrumentsRegistry::GlobalDoubleHistogramHandle handle,
grpc_core::GlobalInstrumentsRegistry::GlobalInstrumentHandle handle,
double value, absl::Span<const absl::string_view> label_values,
absl::Span<const absl::string_view> optional_values) override;
void AddCallback(grpc_core::RegisteredMetricCallback* callback)

@ -16,10 +16,6 @@
#include <memory>
#include "absl/container/flat_hash_map.h"
#include "absl/strings/match.h"
#include "absl/strings/str_cat.h"
#include "absl/strings/str_join.h"
#include "gmock/gmock.h"
#include "gtest/gtest.h"
@ -40,15 +36,15 @@ class MetricsTest : public ::testing::Test {
};
TEST_F(MetricsTest, UInt64Counter) {
const absl::string_view kLabelKeys[] = {"label_key_1", "label_key_2"};
const absl::string_view kOptionalLabelKeys[] = {"optional_label_key_1",
"optional_label_key_2"};
auto uint64_counter_handle = GlobalInstrumentsRegistry::RegisterUInt64Counter(
"uint64_counter", "A simple uint64 counter.", "unit", kLabelKeys,
kOptionalLabelKeys, true);
constexpr absl::string_view kLabelValues[] = {"label_value_1",
"label_value_2"};
constexpr absl::string_view kOptionalLabelValues[] = {
auto uint64_counter_handle =
GlobalInstrumentsRegistry::RegisterUInt64Counter(
"uint64_counter", "A simple uint64 counter.", "unit", true)
.Labels("label_key_1", "label_key_2")
.OptionalLabels("optional_label_key_1", "optional_label_key_2")
.Build();
std::array<absl::string_view, 2> kLabelValues = {"label_value_1",
"label_value_2"};
std::array<absl::string_view, 2> kOptionalLabelValues = {
"optional_label_value_1", "optional_label_value_2"};
constexpr absl::string_view kDomain1To4 = "domain1.domain2.domain3.domain4";
constexpr absl::string_view kDomain2To4 = "domain2.domain3.domain4";
@ -58,34 +54,37 @@ TEST_F(MetricsTest, UInt64Counter) {
auto plugin3 = MakeStatsPluginForTarget(kDomain3To4);
GlobalStatsPluginRegistry::GetStatsPluginsForChannel(
StatsPluginChannelScope(kDomain1To4, ""))
.AddCounter(uint64_counter_handle, 1, kLabelValues, kOptionalLabelValues);
.AddCounter(uint64_counter_handle, uint64_t(1), kLabelValues,
kOptionalLabelValues);
GlobalStatsPluginRegistry::GetStatsPluginsForChannel(
StatsPluginChannelScope(kDomain2To4, ""))
.AddCounter(uint64_counter_handle, 2, kLabelValues, kOptionalLabelValues);
.AddCounter(uint64_counter_handle, uint64_t(2), kLabelValues,
kOptionalLabelValues);
GlobalStatsPluginRegistry::GetStatsPluginsForChannel(
StatsPluginChannelScope(kDomain3To4, ""))
.AddCounter(uint64_counter_handle, 3, kLabelValues, kOptionalLabelValues);
EXPECT_THAT(plugin1->GetCounterValue(uint64_counter_handle, kLabelValues,
kOptionalLabelValues),
.AddCounter(uint64_counter_handle, uint64_t(3), kLabelValues,
kOptionalLabelValues);
EXPECT_THAT(plugin1->GetUInt64CounterValue(
uint64_counter_handle, kLabelValues, kOptionalLabelValues),
::testing::Optional(1));
EXPECT_THAT(plugin2->GetCounterValue(uint64_counter_handle, kLabelValues,
kOptionalLabelValues),
EXPECT_THAT(plugin2->GetUInt64CounterValue(
uint64_counter_handle, kLabelValues, kOptionalLabelValues),
::testing::Optional(3));
EXPECT_THAT(plugin3->GetCounterValue(uint64_counter_handle, kLabelValues,
kOptionalLabelValues),
EXPECT_THAT(plugin3->GetUInt64CounterValue(
uint64_counter_handle, kLabelValues, kOptionalLabelValues),
::testing::Optional(6));
}
TEST_F(MetricsTest, DoubleCounter) {
const absl::string_view kLabelKeys[] = {"label_key_1", "label_key_2"};
const absl::string_view kOptionalLabelKeys[] = {"optional_label_key_1",
"optional_label_key_2"};
auto double_counter_handle = GlobalInstrumentsRegistry::RegisterDoubleCounter(
"double_counter", "A simple double counter.", "unit", kLabelKeys,
kOptionalLabelKeys, true);
constexpr absl::string_view kLabelValues[] = {"label_value_1",
"label_value_2"};
constexpr absl::string_view kOptionalLabelValues[] = {
auto double_counter_handle =
GlobalInstrumentsRegistry::RegisterDoubleCounter(
"double_counter", "A simple double counter.", "unit", true)
.Labels("label_key_1", "label_key_2")
.OptionalLabels("optional_label_key_1", "optional_label_key_2")
.Build();
std::array<absl::string_view, 2> kLabelValues = {"label_value_1",
"label_value_2"};
std::array<absl::string_view, 2> kOptionalLabelValues = {
"optional_label_value_1", "optional_label_value_2"};
constexpr absl::string_view kDomain1To4 = "domain1.domain2.domain3.domain4";
constexpr absl::string_view kDomain2To4 = "domain2.domain3.domain4";
@ -105,28 +104,27 @@ TEST_F(MetricsTest, DoubleCounter) {
StatsPluginChannelScope(kDomain3To4, ""))
.AddCounter(double_counter_handle, 3.45, kLabelValues,
kOptionalLabelValues);
EXPECT_THAT(plugin1->GetCounterValue(double_counter_handle, kLabelValues,
kOptionalLabelValues),
EXPECT_THAT(plugin1->GetDoubleCounterValue(
double_counter_handle, kLabelValues, kOptionalLabelValues),
::testing::Optional(1.23));
EXPECT_THAT(plugin2->GetCounterValue(double_counter_handle, kLabelValues,
kOptionalLabelValues),
EXPECT_THAT(plugin2->GetDoubleCounterValue(
double_counter_handle, kLabelValues, kOptionalLabelValues),
::testing::Optional(3.57));
EXPECT_THAT(plugin3->GetCounterValue(double_counter_handle, kLabelValues,
kOptionalLabelValues),
EXPECT_THAT(plugin3->GetDoubleCounterValue(
double_counter_handle, kLabelValues, kOptionalLabelValues),
::testing::Optional(7.02));
}
TEST_F(MetricsTest, UInt64Histogram) {
const absl::string_view kLabelKeys[] = {"label_key_1", "label_key_2"};
const absl::string_view kOptionalLabelKeys[] = {"optional_label_key_1",
"optional_label_key_2"};
auto uint64_histogram_handle =
GlobalInstrumentsRegistry::RegisterUInt64Histogram(
"uint64_histogram", "A simple uint64 histogram.", "unit", kLabelKeys,
kOptionalLabelKeys, true);
constexpr absl::string_view kLabelValues[] = {"label_value_1",
"label_value_2"};
constexpr absl::string_view kOptionalLabelValues[] = {
"uint64_histogram", "A simple uint64 histogram.", "unit", true)
.Labels("label_key_1", "label_key_2")
.OptionalLabels("optional_label_key_1", "optional_label_key_2")
.Build();
std::array<absl::string_view, 2> kLabelValues = {"label_value_1",
"label_value_2"};
std::array<absl::string_view, 2> kOptionalLabelValues = {
"optional_label_value_1", "optional_label_value_2"};
constexpr absl::string_view kDomain1To4 = "domain1.domain2.domain3.domain4";
constexpr absl::string_view kDomain2To4 = "domain2.domain3.domain4";
@ -136,38 +134,37 @@ TEST_F(MetricsTest, UInt64Histogram) {
auto plugin3 = MakeStatsPluginForTarget(kDomain3To4);
GlobalStatsPluginRegistry::GetStatsPluginsForChannel(
StatsPluginChannelScope(kDomain1To4, ""))
.RecordHistogram(uint64_histogram_handle, 1, kLabelValues,
.RecordHistogram(uint64_histogram_handle, uint64_t(1), kLabelValues,
kOptionalLabelValues);
GlobalStatsPluginRegistry::GetStatsPluginsForChannel(
StatsPluginChannelScope(kDomain2To4, ""))
.RecordHistogram(uint64_histogram_handle, 2, kLabelValues,
.RecordHistogram(uint64_histogram_handle, uint64_t(2), kLabelValues,
kOptionalLabelValues);
GlobalStatsPluginRegistry::GetStatsPluginsForChannel(
StatsPluginChannelScope(kDomain3To4, ""))
.RecordHistogram(uint64_histogram_handle, 3, kLabelValues,
.RecordHistogram(uint64_histogram_handle, uint64_t(3), kLabelValues,
kOptionalLabelValues);
EXPECT_THAT(plugin1->GetHistogramValue(uint64_histogram_handle, kLabelValues,
kOptionalLabelValues),
EXPECT_THAT(plugin1->GetUInt64HistogramValue(
uint64_histogram_handle, kLabelValues, kOptionalLabelValues),
::testing::Optional(::testing::UnorderedElementsAre(1)));
EXPECT_THAT(plugin2->GetHistogramValue(uint64_histogram_handle, kLabelValues,
kOptionalLabelValues),
EXPECT_THAT(plugin2->GetUInt64HistogramValue(
uint64_histogram_handle, kLabelValues, kOptionalLabelValues),
::testing::Optional(::testing::UnorderedElementsAre(1, 2)));
EXPECT_THAT(plugin3->GetHistogramValue(uint64_histogram_handle, kLabelValues,
kOptionalLabelValues),
EXPECT_THAT(plugin3->GetUInt64HistogramValue(
uint64_histogram_handle, kLabelValues, kOptionalLabelValues),
::testing::Optional(::testing::UnorderedElementsAre(1, 2, 3)));
}
TEST_F(MetricsTest, DoubleHistogram) {
const absl::string_view kLabelKeys[] = {"label_key_1", "label_key_2"};
const absl::string_view kOptionalLabelKeys[] = {"optional_label_key_1",
"optional_label_key_2"};
auto double_histogram_handle =
GlobalInstrumentsRegistry::RegisterDoubleHistogram(
"double_histogram", "A simple double histogram.", "unit", kLabelKeys,
kOptionalLabelKeys, true);
constexpr absl::string_view kLabelValues[] = {"label_value_1",
"label_value_2"};
constexpr absl::string_view kOptionalLabelValues[] = {
"double_histogram", "A simple double histogram.", "unit", true)
.Labels("label_key_1", "label_key_2")
.OptionalLabels("optional_label_key_1", "optional_label_key_2")
.Build();
std::array<absl::string_view, 2> kLabelValues = {"label_value_1",
"label_value_2"};
std::array<absl::string_view, 2> kOptionalLabelValues = {
"optional_label_value_1", "optional_label_value_2"};
constexpr absl::string_view kDomain1To4 = "domain1.domain2.domain3.domain4";
constexpr absl::string_view kDomain2To4 = "domain2.domain3.domain4";
@ -187,31 +184,30 @@ TEST_F(MetricsTest, DoubleHistogram) {
StatsPluginChannelScope(kDomain3To4, ""))
.RecordHistogram(double_histogram_handle, 3.45, kLabelValues,
kOptionalLabelValues);
EXPECT_THAT(plugin1->GetHistogramValue(double_histogram_handle, kLabelValues,
kOptionalLabelValues),
EXPECT_THAT(plugin1->GetDoubleHistogramValue(
double_histogram_handle, kLabelValues, kOptionalLabelValues),
::testing::Optional(::testing::UnorderedElementsAre(1.23)));
EXPECT_THAT(plugin2->GetHistogramValue(double_histogram_handle, kLabelValues,
kOptionalLabelValues),
EXPECT_THAT(plugin2->GetDoubleHistogramValue(
double_histogram_handle, kLabelValues, kOptionalLabelValues),
::testing::Optional(::testing::UnorderedElementsAre(1.23, 2.34)));
EXPECT_THAT(
plugin3->GetHistogramValue(double_histogram_handle, kLabelValues,
kOptionalLabelValues),
plugin3->GetDoubleHistogramValue(double_histogram_handle, kLabelValues,
kOptionalLabelValues),
::testing::Optional(::testing::UnorderedElementsAre(1.23, 2.34, 3.45)));
}
TEST_F(MetricsTest, Int64CallbackGauge) {
const absl::string_view kLabelKeys[] = {"label_key_1", "label_key_2"};
const absl::string_view kOptionalLabelKeys[] = {"optional_label_key_1",
"optional_label_key_2"};
auto int64_gauge_handle =
GlobalInstrumentsRegistry::RegisterCallbackInt64Gauge(
"int64_gauge", "A simple int64 gauge.", "unit", kLabelKeys,
kOptionalLabelKeys, true);
constexpr absl::string_view kLabelValues[] = {"label_value_1",
"label_value_2"};
constexpr absl::string_view kLabelValues2[] = {"label_value_3",
"label_value_2"};
constexpr absl::string_view kOptionalLabelValues[] = {
"int64_gauge", "A simple int64 gauge.", "unit", true)
.Labels("label_key_1", "label_key_2")
.OptionalLabels("optional_label_key_1", "optional_label_key_2")
.Build();
std::array<absl::string_view, 2> kLabelValues = {"label_value_1",
"label_value_2"};
std::array<absl::string_view, 2> kLabelValues2 = {"label_value_3",
"label_value_2"};
std::array<absl::string_view, 2> kOptionalLabelValues = {
"optional_label_value_1", "optional_label_value_2"};
constexpr absl::string_view kDomain1To4 = "domain1.domain2.domain3.domain4";
constexpr absl::string_view kDomain2To4 = "domain2.domain3.domain4";
@ -226,57 +222,57 @@ TEST_F(MetricsTest, Int64CallbackGauge) {
StatsPluginChannelScope(kDomain3To4, ""));
auto callback1 = group1.RegisterCallback(
[&](CallbackMetricReporter& reporter) {
reporter.Report(int64_gauge_handle, 1, kLabelValues,
reporter.Report(int64_gauge_handle, int64_t(1), kLabelValues,
kOptionalLabelValues);
},
{int64_gauge_handle});
Duration::Seconds(5), int64_gauge_handle);
auto callback2 = group1.RegisterCallback(
[&](CallbackMetricReporter& reporter) {
reporter.Report(int64_gauge_handle, 2, kLabelValues2,
reporter.Report(int64_gauge_handle, int64_t(2), kLabelValues2,
kOptionalLabelValues);
},
{int64_gauge_handle});
Duration::Seconds(5), int64_gauge_handle);
// No plugins have data yet.
EXPECT_EQ(plugin1->GetCallbackGaugeValue(int64_gauge_handle, kLabelValues,
kOptionalLabelValues),
EXPECT_EQ(plugin1->GetInt64CallbackGaugeValue(
int64_gauge_handle, kLabelValues, kOptionalLabelValues),
absl::nullopt);
EXPECT_EQ(plugin1->GetCallbackGaugeValue(int64_gauge_handle, kLabelValues2,
kOptionalLabelValues),
EXPECT_EQ(plugin1->GetInt64CallbackGaugeValue(
int64_gauge_handle, kLabelValues2, kOptionalLabelValues),
absl::nullopt);
EXPECT_EQ(plugin2->GetCallbackGaugeValue(int64_gauge_handle, kLabelValues,
kOptionalLabelValues),
EXPECT_EQ(plugin2->GetInt64CallbackGaugeValue(
int64_gauge_handle, kLabelValues, kOptionalLabelValues),
absl::nullopt);
EXPECT_EQ(plugin2->GetCallbackGaugeValue(int64_gauge_handle, kLabelValues2,
kOptionalLabelValues),
EXPECT_EQ(plugin2->GetInt64CallbackGaugeValue(
int64_gauge_handle, kLabelValues2, kOptionalLabelValues),
absl::nullopt);
EXPECT_EQ(plugin3->GetCallbackGaugeValue(int64_gauge_handle, kLabelValues,
kOptionalLabelValues),
EXPECT_EQ(plugin3->GetInt64CallbackGaugeValue(
int64_gauge_handle, kLabelValues, kOptionalLabelValues),
absl::nullopt);
EXPECT_EQ(plugin3->GetCallbackGaugeValue(int64_gauge_handle, kLabelValues2,
kOptionalLabelValues),
EXPECT_EQ(plugin3->GetInt64CallbackGaugeValue(
int64_gauge_handle, kLabelValues2, kOptionalLabelValues),
absl::nullopt);
// Now invoke the callbacks.
plugin1->TriggerCallbacks();
plugin2->TriggerCallbacks();
plugin3->TriggerCallbacks();
// Now plugin1 should have data, but the others should not.
EXPECT_THAT(plugin1->GetCallbackGaugeValue(int64_gauge_handle, kLabelValues,
kOptionalLabelValues),
EXPECT_THAT(plugin1->GetInt64CallbackGaugeValue(
int64_gauge_handle, kLabelValues, kOptionalLabelValues),
::testing::Optional(1));
EXPECT_THAT(plugin1->GetCallbackGaugeValue(int64_gauge_handle, kLabelValues2,
kOptionalLabelValues),
EXPECT_THAT(plugin1->GetInt64CallbackGaugeValue(
int64_gauge_handle, kLabelValues2, kOptionalLabelValues),
::testing::Optional(2));
EXPECT_EQ(plugin2->GetCallbackGaugeValue(int64_gauge_handle, kLabelValues,
kOptionalLabelValues),
EXPECT_EQ(plugin2->GetInt64CallbackGaugeValue(
int64_gauge_handle, kLabelValues, kOptionalLabelValues),
absl::nullopt);
EXPECT_EQ(plugin2->GetCallbackGaugeValue(int64_gauge_handle, kLabelValues2,
kOptionalLabelValues),
EXPECT_EQ(plugin2->GetInt64CallbackGaugeValue(
int64_gauge_handle, kLabelValues2, kOptionalLabelValues),
absl::nullopt);
EXPECT_EQ(plugin3->GetCallbackGaugeValue(int64_gauge_handle, kLabelValues,
kOptionalLabelValues),
EXPECT_EQ(plugin3->GetInt64CallbackGaugeValue(
int64_gauge_handle, kLabelValues, kOptionalLabelValues),
absl::nullopt);
EXPECT_EQ(plugin3->GetCallbackGaugeValue(int64_gauge_handle, kLabelValues2,
kOptionalLabelValues),
EXPECT_EQ(plugin3->GetInt64CallbackGaugeValue(
int64_gauge_handle, kLabelValues2, kOptionalLabelValues),
absl::nullopt);
// De-register the callbacks.
callback1.reset();
@ -287,57 +283,57 @@ TEST_F(MetricsTest, Int64CallbackGauge) {
StatsPluginChannelScope(kDomain2To4, ""));
callback1 = group2.RegisterCallback(
[&](CallbackMetricReporter& reporter) {
reporter.Report(int64_gauge_handle, 3, kLabelValues,
reporter.Report(int64_gauge_handle, int64_t(3), kLabelValues,
kOptionalLabelValues);
},
{int64_gauge_handle});
Duration::Seconds(5), int64_gauge_handle);
callback2 = group2.RegisterCallback(
[&](CallbackMetricReporter& reporter) {
reporter.Report(int64_gauge_handle, 4, kLabelValues2,
reporter.Report(int64_gauge_handle, int64_t(4), kLabelValues2,
kOptionalLabelValues);
},
{int64_gauge_handle});
Duration::Seconds(5), int64_gauge_handle);
// Plugin1 still has data from before, but the others have none.
EXPECT_THAT(plugin1->GetCallbackGaugeValue(int64_gauge_handle, kLabelValues,
kOptionalLabelValues),
EXPECT_THAT(plugin1->GetInt64CallbackGaugeValue(
int64_gauge_handle, kLabelValues, kOptionalLabelValues),
::testing::Optional(1));
EXPECT_THAT(plugin1->GetCallbackGaugeValue(int64_gauge_handle, kLabelValues2,
kOptionalLabelValues),
EXPECT_THAT(plugin1->GetInt64CallbackGaugeValue(
int64_gauge_handle, kLabelValues2, kOptionalLabelValues),
::testing::Optional(2));
EXPECT_EQ(plugin2->GetCallbackGaugeValue(int64_gauge_handle, kLabelValues,
kOptionalLabelValues),
EXPECT_EQ(plugin2->GetInt64CallbackGaugeValue(
int64_gauge_handle, kLabelValues, kOptionalLabelValues),
absl::nullopt);
EXPECT_EQ(plugin2->GetCallbackGaugeValue(int64_gauge_handle, kLabelValues2,
kOptionalLabelValues),
EXPECT_EQ(plugin2->GetInt64CallbackGaugeValue(
int64_gauge_handle, kLabelValues2, kOptionalLabelValues),
absl::nullopt);
EXPECT_EQ(plugin3->GetCallbackGaugeValue(int64_gauge_handle, kLabelValues,
kOptionalLabelValues),
EXPECT_EQ(plugin3->GetInt64CallbackGaugeValue(
int64_gauge_handle, kLabelValues, kOptionalLabelValues),
absl::nullopt);
EXPECT_EQ(plugin3->GetCallbackGaugeValue(int64_gauge_handle, kLabelValues2,
kOptionalLabelValues),
EXPECT_EQ(plugin3->GetInt64CallbackGaugeValue(
int64_gauge_handle, kLabelValues2, kOptionalLabelValues),
absl::nullopt);
// Now invoke the callbacks.
plugin1->TriggerCallbacks();
plugin2->TriggerCallbacks();
plugin3->TriggerCallbacks();
// Now plugin1 and plugin2 should have data, but plugin3 should not.
EXPECT_THAT(plugin1->GetCallbackGaugeValue(int64_gauge_handle, kLabelValues,
kOptionalLabelValues),
EXPECT_THAT(plugin1->GetInt64CallbackGaugeValue(
int64_gauge_handle, kLabelValues, kOptionalLabelValues),
::testing::Optional(3));
EXPECT_THAT(plugin1->GetCallbackGaugeValue(int64_gauge_handle, kLabelValues2,
kOptionalLabelValues),
EXPECT_THAT(plugin1->GetInt64CallbackGaugeValue(
int64_gauge_handle, kLabelValues2, kOptionalLabelValues),
::testing::Optional(4));
EXPECT_THAT(plugin2->GetCallbackGaugeValue(int64_gauge_handle, kLabelValues,
kOptionalLabelValues),
EXPECT_THAT(plugin2->GetInt64CallbackGaugeValue(
int64_gauge_handle, kLabelValues, kOptionalLabelValues),
::testing::Optional(3));
EXPECT_THAT(plugin2->GetCallbackGaugeValue(int64_gauge_handle, kLabelValues2,
kOptionalLabelValues),
EXPECT_THAT(plugin2->GetInt64CallbackGaugeValue(
int64_gauge_handle, kLabelValues2, kOptionalLabelValues),
::testing::Optional(4));
EXPECT_EQ(plugin3->GetCallbackGaugeValue(int64_gauge_handle, kLabelValues,
kOptionalLabelValues),
EXPECT_EQ(plugin3->GetInt64CallbackGaugeValue(
int64_gauge_handle, kLabelValues, kOptionalLabelValues),
absl::nullopt);
EXPECT_EQ(plugin3->GetCallbackGaugeValue(int64_gauge_handle, kLabelValues2,
kOptionalLabelValues),
EXPECT_EQ(plugin3->GetInt64CallbackGaugeValue(
int64_gauge_handle, kLabelValues2, kOptionalLabelValues),
absl::nullopt);
// De-register the callbacks.
callback1.reset();
@ -348,57 +344,57 @@ TEST_F(MetricsTest, Int64CallbackGauge) {
StatsPluginChannelScope(kDomain1To4, ""));
callback1 = group3.RegisterCallback(
[&](CallbackMetricReporter& reporter) {
reporter.Report(int64_gauge_handle, 5, kLabelValues,
reporter.Report(int64_gauge_handle, int64_t(5), kLabelValues,
kOptionalLabelValues);
},
{int64_gauge_handle});
Duration::Seconds(5), int64_gauge_handle);
callback2 = group3.RegisterCallback(
[&](CallbackMetricReporter& reporter) {
reporter.Report(int64_gauge_handle, 6, kLabelValues2,
reporter.Report(int64_gauge_handle, int64_t(6), kLabelValues2,
kOptionalLabelValues);
},
{int64_gauge_handle});
Duration::Seconds(5), int64_gauge_handle);
// Plugin1 and plugin2 still has data from before, but plugin3 has none.
EXPECT_THAT(plugin1->GetCallbackGaugeValue(int64_gauge_handle, kLabelValues,
kOptionalLabelValues),
EXPECT_THAT(plugin1->GetInt64CallbackGaugeValue(
int64_gauge_handle, kLabelValues, kOptionalLabelValues),
::testing::Optional(3));
EXPECT_THAT(plugin1->GetCallbackGaugeValue(int64_gauge_handle, kLabelValues2,
kOptionalLabelValues),
EXPECT_THAT(plugin1->GetInt64CallbackGaugeValue(
int64_gauge_handle, kLabelValues2, kOptionalLabelValues),
::testing::Optional(4));
EXPECT_THAT(plugin2->GetCallbackGaugeValue(int64_gauge_handle, kLabelValues,
kOptionalLabelValues),
EXPECT_THAT(plugin2->GetInt64CallbackGaugeValue(
int64_gauge_handle, kLabelValues, kOptionalLabelValues),
::testing::Optional(3));
EXPECT_THAT(plugin2->GetCallbackGaugeValue(int64_gauge_handle, kLabelValues2,
kOptionalLabelValues),
EXPECT_THAT(plugin2->GetInt64CallbackGaugeValue(
int64_gauge_handle, kLabelValues2, kOptionalLabelValues),
::testing::Optional(4));
EXPECT_EQ(plugin3->GetCallbackGaugeValue(int64_gauge_handle, kLabelValues,
kOptionalLabelValues),
EXPECT_EQ(plugin3->GetInt64CallbackGaugeValue(
int64_gauge_handle, kLabelValues, kOptionalLabelValues),
absl::nullopt);
EXPECT_EQ(plugin3->GetCallbackGaugeValue(int64_gauge_handle, kLabelValues2,
kOptionalLabelValues),
EXPECT_EQ(plugin3->GetInt64CallbackGaugeValue(
int64_gauge_handle, kLabelValues2, kOptionalLabelValues),
absl::nullopt);
// Now invoke the callbacks.
plugin1->TriggerCallbacks();
plugin2->TriggerCallbacks();
plugin3->TriggerCallbacks();
// Now plugin1 and plugin2 should have data, but plugin3 should not.
EXPECT_THAT(plugin1->GetCallbackGaugeValue(int64_gauge_handle, kLabelValues,
kOptionalLabelValues),
EXPECT_THAT(plugin1->GetInt64CallbackGaugeValue(
int64_gauge_handle, kLabelValues, kOptionalLabelValues),
::testing::Optional(5));
EXPECT_THAT(plugin1->GetCallbackGaugeValue(int64_gauge_handle, kLabelValues2,
kOptionalLabelValues),
EXPECT_THAT(plugin1->GetInt64CallbackGaugeValue(
int64_gauge_handle, kLabelValues2, kOptionalLabelValues),
::testing::Optional(6));
EXPECT_THAT(plugin2->GetCallbackGaugeValue(int64_gauge_handle, kLabelValues,
kOptionalLabelValues),
EXPECT_THAT(plugin2->GetInt64CallbackGaugeValue(
int64_gauge_handle, kLabelValues, kOptionalLabelValues),
::testing::Optional(5));
EXPECT_THAT(plugin2->GetCallbackGaugeValue(int64_gauge_handle, kLabelValues2,
kOptionalLabelValues),
EXPECT_THAT(plugin2->GetInt64CallbackGaugeValue(
int64_gauge_handle, kLabelValues2, kOptionalLabelValues),
::testing::Optional(6));
EXPECT_THAT(plugin3->GetCallbackGaugeValue(int64_gauge_handle, kLabelValues,
kOptionalLabelValues),
EXPECT_THAT(plugin3->GetInt64CallbackGaugeValue(
int64_gauge_handle, kLabelValues, kOptionalLabelValues),
::testing::Optional(5));
EXPECT_THAT(plugin3->GetCallbackGaugeValue(int64_gauge_handle, kLabelValues2,
kOptionalLabelValues),
EXPECT_THAT(plugin3->GetInt64CallbackGaugeValue(
int64_gauge_handle, kLabelValues2, kOptionalLabelValues),
::testing::Optional(6));
// Need to destroy callbacks before the plugin group that created them.
callback1.reset();
@ -406,18 +402,17 @@ TEST_F(MetricsTest, Int64CallbackGauge) {
}
TEST_F(MetricsTest, DoubleCallbackGauge) {
const absl::string_view kLabelKeys[] = {"label_key_1", "label_key_2"};
const absl::string_view kOptionalLabelKeys[] = {"optional_label_key_1",
"optional_label_key_2"};
auto double_gauge_handle =
GlobalInstrumentsRegistry::RegisterCallbackDoubleGauge(
"double_gauge", "A simple double gauge.", "unit", kLabelKeys,
kOptionalLabelKeys, true);
constexpr absl::string_view kLabelValues[] = {"label_value_1",
"label_value_2"};
constexpr absl::string_view kLabelValues2[] = {"label_value_3",
"label_value_2"};
constexpr absl::string_view kOptionalLabelValues[] = {
"double_gauge", "A simple double gauge.", "unit", true)
.Labels("label_key_1", "label_key_2")
.OptionalLabels("optional_label_key_1", "optional_label_key_2")
.Build();
std::array<absl::string_view, 2> kLabelValues = {"label_value_1",
"label_value_2"};
std::array<absl::string_view, 2> kLabelValues2 = {"label_value_3",
"label_value_2"};
std::array<absl::string_view, 2> kOptionalLabelValues = {
"optional_label_value_1", "optional_label_value_2"};
constexpr absl::string_view kDomain1To4 = "domain1.domain2.domain3.domain4";
constexpr absl::string_view kDomain2To4 = "domain2.domain3.domain4";
@ -435,54 +430,54 @@ TEST_F(MetricsTest, DoubleCallbackGauge) {
reporter.Report(double_gauge_handle, 1.23, kLabelValues,
kOptionalLabelValues);
},
{double_gauge_handle});
Duration::Seconds(5), double_gauge_handle);
auto callback2 = group1.RegisterCallback(
[&](CallbackMetricReporter& reporter) {
reporter.Report(double_gauge_handle, 2.34, kLabelValues2,
kOptionalLabelValues);
},
{double_gauge_handle});
Duration::Seconds(5), double_gauge_handle);
// No plugins have data yet.
EXPECT_EQ(plugin1->GetCallbackGaugeValue(double_gauge_handle, kLabelValues,
kOptionalLabelValues),
EXPECT_EQ(plugin1->GetDoubleCallbackGaugeValue(
double_gauge_handle, kLabelValues, kOptionalLabelValues),
absl::nullopt);
EXPECT_EQ(plugin1->GetCallbackGaugeValue(double_gauge_handle, kLabelValues2,
kOptionalLabelValues),
EXPECT_EQ(plugin1->GetDoubleCallbackGaugeValue(
double_gauge_handle, kLabelValues2, kOptionalLabelValues),
absl::nullopt);
EXPECT_EQ(plugin2->GetCallbackGaugeValue(double_gauge_handle, kLabelValues,
kOptionalLabelValues),
EXPECT_EQ(plugin2->GetDoubleCallbackGaugeValue(
double_gauge_handle, kLabelValues, kOptionalLabelValues),
absl::nullopt);
EXPECT_EQ(plugin2->GetCallbackGaugeValue(double_gauge_handle, kLabelValues2,
kOptionalLabelValues),
EXPECT_EQ(plugin2->GetDoubleCallbackGaugeValue(
double_gauge_handle, kLabelValues2, kOptionalLabelValues),
absl::nullopt);
EXPECT_EQ(plugin3->GetCallbackGaugeValue(double_gauge_handle, kLabelValues,
kOptionalLabelValues),
EXPECT_EQ(plugin3->GetDoubleCallbackGaugeValue(
double_gauge_handle, kLabelValues, kOptionalLabelValues),
absl::nullopt);
EXPECT_EQ(plugin3->GetCallbackGaugeValue(double_gauge_handle, kLabelValues2,
kOptionalLabelValues),
EXPECT_EQ(plugin3->GetDoubleCallbackGaugeValue(
double_gauge_handle, kLabelValues2, kOptionalLabelValues),
absl::nullopt);
// Now invoke the callbacks.
plugin1->TriggerCallbacks();
plugin2->TriggerCallbacks();
plugin3->TriggerCallbacks();
// Now plugin1 should have data, but the others should not.
EXPECT_THAT(plugin1->GetCallbackGaugeValue(double_gauge_handle, kLabelValues,
kOptionalLabelValues),
EXPECT_THAT(plugin1->GetDoubleCallbackGaugeValue(
double_gauge_handle, kLabelValues, kOptionalLabelValues),
::testing::Optional(1.23));
EXPECT_THAT(plugin1->GetCallbackGaugeValue(double_gauge_handle, kLabelValues2,
kOptionalLabelValues),
EXPECT_THAT(plugin1->GetDoubleCallbackGaugeValue(
double_gauge_handle, kLabelValues2, kOptionalLabelValues),
::testing::Optional(2.34));
EXPECT_EQ(plugin2->GetCallbackGaugeValue(double_gauge_handle, kLabelValues,
kOptionalLabelValues),
EXPECT_EQ(plugin2->GetDoubleCallbackGaugeValue(
double_gauge_handle, kLabelValues, kOptionalLabelValues),
absl::nullopt);
EXPECT_EQ(plugin2->GetCallbackGaugeValue(double_gauge_handle, kLabelValues2,
kOptionalLabelValues),
EXPECT_EQ(plugin2->GetDoubleCallbackGaugeValue(
double_gauge_handle, kLabelValues2, kOptionalLabelValues),
absl::nullopt);
EXPECT_EQ(plugin3->GetCallbackGaugeValue(double_gauge_handle, kLabelValues,
kOptionalLabelValues),
EXPECT_EQ(plugin3->GetDoubleCallbackGaugeValue(
double_gauge_handle, kLabelValues, kOptionalLabelValues),
absl::nullopt);
EXPECT_EQ(plugin3->GetCallbackGaugeValue(double_gauge_handle, kLabelValues2,
kOptionalLabelValues),
EXPECT_EQ(plugin3->GetDoubleCallbackGaugeValue(
double_gauge_handle, kLabelValues2, kOptionalLabelValues),
absl::nullopt);
// De-register the callbacks.
callback1.reset();
@ -496,54 +491,54 @@ TEST_F(MetricsTest, DoubleCallbackGauge) {
reporter.Report(double_gauge_handle, 3.45, kLabelValues,
kOptionalLabelValues);
},
{double_gauge_handle});
Duration::Seconds(5), double_gauge_handle);
callback2 = group2.RegisterCallback(
[&](CallbackMetricReporter& reporter) {
reporter.Report(double_gauge_handle, 4.56, kLabelValues2,
kOptionalLabelValues);
},
{double_gauge_handle});
Duration::Seconds(5), double_gauge_handle);
// Plugin1 still has data from before, but the others have none.
EXPECT_THAT(plugin1->GetCallbackGaugeValue(double_gauge_handle, kLabelValues,
kOptionalLabelValues),
EXPECT_THAT(plugin1->GetDoubleCallbackGaugeValue(
double_gauge_handle, kLabelValues, kOptionalLabelValues),
::testing::Optional(1.23));
EXPECT_THAT(plugin1->GetCallbackGaugeValue(double_gauge_handle, kLabelValues2,
kOptionalLabelValues),
EXPECT_THAT(plugin1->GetDoubleCallbackGaugeValue(
double_gauge_handle, kLabelValues2, kOptionalLabelValues),
::testing::Optional(2.34));
EXPECT_EQ(plugin2->GetCallbackGaugeValue(double_gauge_handle, kLabelValues,
kOptionalLabelValues),
EXPECT_EQ(plugin2->GetDoubleCallbackGaugeValue(
double_gauge_handle, kLabelValues, kOptionalLabelValues),
absl::nullopt);
EXPECT_EQ(plugin2->GetCallbackGaugeValue(double_gauge_handle, kLabelValues2,
kOptionalLabelValues),
EXPECT_EQ(plugin2->GetDoubleCallbackGaugeValue(
double_gauge_handle, kLabelValues2, kOptionalLabelValues),
absl::nullopt);
EXPECT_EQ(plugin3->GetCallbackGaugeValue(double_gauge_handle, kLabelValues,
kOptionalLabelValues),
EXPECT_EQ(plugin3->GetDoubleCallbackGaugeValue(
double_gauge_handle, kLabelValues, kOptionalLabelValues),
absl::nullopt);
EXPECT_EQ(plugin3->GetCallbackGaugeValue(double_gauge_handle, kLabelValues2,
kOptionalLabelValues),
EXPECT_EQ(plugin3->GetDoubleCallbackGaugeValue(
double_gauge_handle, kLabelValues2, kOptionalLabelValues),
absl::nullopt);
// Now invoke the callbacks.
plugin1->TriggerCallbacks();
plugin2->TriggerCallbacks();
plugin3->TriggerCallbacks();
// Now plugin1 and plugin2 should have data, but plugin3 should not.
EXPECT_THAT(plugin1->GetCallbackGaugeValue(double_gauge_handle, kLabelValues,
kOptionalLabelValues),
EXPECT_THAT(plugin1->GetDoubleCallbackGaugeValue(
double_gauge_handle, kLabelValues, kOptionalLabelValues),
::testing::Optional(3.45));
EXPECT_THAT(plugin1->GetCallbackGaugeValue(double_gauge_handle, kLabelValues2,
kOptionalLabelValues),
EXPECT_THAT(plugin1->GetDoubleCallbackGaugeValue(
double_gauge_handle, kLabelValues2, kOptionalLabelValues),
::testing::Optional(4.56));
EXPECT_THAT(plugin2->GetCallbackGaugeValue(double_gauge_handle, kLabelValues,
kOptionalLabelValues),
EXPECT_THAT(plugin2->GetDoubleCallbackGaugeValue(
double_gauge_handle, kLabelValues, kOptionalLabelValues),
::testing::Optional(3.45));
EXPECT_THAT(plugin2->GetCallbackGaugeValue(double_gauge_handle, kLabelValues2,
kOptionalLabelValues),
EXPECT_THAT(plugin2->GetDoubleCallbackGaugeValue(
double_gauge_handle, kLabelValues2, kOptionalLabelValues),
::testing::Optional(4.56));
EXPECT_EQ(plugin3->GetCallbackGaugeValue(double_gauge_handle, kLabelValues,
kOptionalLabelValues),
EXPECT_EQ(plugin3->GetDoubleCallbackGaugeValue(
double_gauge_handle, kLabelValues, kOptionalLabelValues),
absl::nullopt);
EXPECT_EQ(plugin3->GetCallbackGaugeValue(double_gauge_handle, kLabelValues2,
kOptionalLabelValues),
EXPECT_EQ(plugin3->GetDoubleCallbackGaugeValue(
double_gauge_handle, kLabelValues2, kOptionalLabelValues),
absl::nullopt);
// De-register the callbacks.
callback1.reset();
@ -557,54 +552,54 @@ TEST_F(MetricsTest, DoubleCallbackGauge) {
reporter.Report(double_gauge_handle, 5.67, kLabelValues,
kOptionalLabelValues);
},
{double_gauge_handle});
Duration::Seconds(5), double_gauge_handle);
callback2 = group3.RegisterCallback(
[&](CallbackMetricReporter& reporter) {
reporter.Report(double_gauge_handle, 6.78, kLabelValues2,
kOptionalLabelValues);
},
{double_gauge_handle});
Duration::Seconds(5), double_gauge_handle);
// Plugin1 and plugin2 still has data from before, but plugin3 has none.
EXPECT_THAT(plugin1->GetCallbackGaugeValue(double_gauge_handle, kLabelValues,
kOptionalLabelValues),
EXPECT_THAT(plugin1->GetDoubleCallbackGaugeValue(
double_gauge_handle, kLabelValues, kOptionalLabelValues),
::testing::Optional(3.45));
EXPECT_THAT(plugin1->GetCallbackGaugeValue(double_gauge_handle, kLabelValues2,
kOptionalLabelValues),
EXPECT_THAT(plugin1->GetDoubleCallbackGaugeValue(
double_gauge_handle, kLabelValues2, kOptionalLabelValues),
::testing::Optional(4.56));
EXPECT_THAT(plugin2->GetCallbackGaugeValue(double_gauge_handle, kLabelValues,
kOptionalLabelValues),
EXPECT_THAT(plugin2->GetDoubleCallbackGaugeValue(
double_gauge_handle, kLabelValues, kOptionalLabelValues),
::testing::Optional(3.45));
EXPECT_THAT(plugin2->GetCallbackGaugeValue(double_gauge_handle, kLabelValues2,
kOptionalLabelValues),
EXPECT_THAT(plugin2->GetDoubleCallbackGaugeValue(
double_gauge_handle, kLabelValues2, kOptionalLabelValues),
::testing::Optional(4.56));
EXPECT_EQ(plugin3->GetCallbackGaugeValue(double_gauge_handle, kLabelValues,
kOptionalLabelValues),
EXPECT_EQ(plugin3->GetDoubleCallbackGaugeValue(
double_gauge_handle, kLabelValues, kOptionalLabelValues),
absl::nullopt);
EXPECT_EQ(plugin3->GetCallbackGaugeValue(double_gauge_handle, kLabelValues2,
kOptionalLabelValues),
EXPECT_EQ(plugin3->GetDoubleCallbackGaugeValue(
double_gauge_handle, kLabelValues2, kOptionalLabelValues),
absl::nullopt);
// Now invoke the callbacks.
plugin1->TriggerCallbacks();
plugin2->TriggerCallbacks();
plugin3->TriggerCallbacks();
// Now plugin1 and plugin2 should have data, but plugin3 should not.
EXPECT_THAT(plugin1->GetCallbackGaugeValue(double_gauge_handle, kLabelValues,
kOptionalLabelValues),
EXPECT_THAT(plugin1->GetDoubleCallbackGaugeValue(
double_gauge_handle, kLabelValues, kOptionalLabelValues),
::testing::Optional(5.67));
EXPECT_THAT(plugin1->GetCallbackGaugeValue(double_gauge_handle, kLabelValues2,
kOptionalLabelValues),
EXPECT_THAT(plugin1->GetDoubleCallbackGaugeValue(
double_gauge_handle, kLabelValues2, kOptionalLabelValues),
::testing::Optional(6.78));
EXPECT_THAT(plugin2->GetCallbackGaugeValue(double_gauge_handle, kLabelValues,
kOptionalLabelValues),
EXPECT_THAT(plugin2->GetDoubleCallbackGaugeValue(
double_gauge_handle, kLabelValues, kOptionalLabelValues),
::testing::Optional(5.67));
EXPECT_THAT(plugin2->GetCallbackGaugeValue(double_gauge_handle, kLabelValues2,
kOptionalLabelValues),
EXPECT_THAT(plugin2->GetDoubleCallbackGaugeValue(
double_gauge_handle, kLabelValues2, kOptionalLabelValues),
::testing::Optional(6.78));
EXPECT_THAT(plugin3->GetCallbackGaugeValue(double_gauge_handle, kLabelValues,
kOptionalLabelValues),
EXPECT_THAT(plugin3->GetDoubleCallbackGaugeValue(
double_gauge_handle, kLabelValues, kOptionalLabelValues),
::testing::Optional(5.67));
EXPECT_THAT(plugin3->GetCallbackGaugeValue(double_gauge_handle, kLabelValues2,
kOptionalLabelValues),
EXPECT_THAT(plugin3->GetDoubleCallbackGaugeValue(
double_gauge_handle, kLabelValues2, kOptionalLabelValues),
::testing::Optional(6.78));
// Need to destroy callbacks before the plugin group that created them.
callback1.reset();
@ -612,16 +607,15 @@ TEST_F(MetricsTest, DoubleCallbackGauge) {
}
TEST_F(MetricsTest, DisableByDefaultMetricIsNotRecordedByFakeStatsPlugin) {
const absl::string_view kLabelKeys[] = {"label_key_1", "label_key_2"};
const absl::string_view kOptionalLabelKeys[] = {"optional_label_key_1",
"optional_label_key_2"};
auto double_histogram_handle =
GlobalInstrumentsRegistry::RegisterDoubleHistogram(
"double_histogram", "A simple double histogram.", "unit", kLabelKeys,
kOptionalLabelKeys, /*enable_by_default=*/false);
constexpr absl::string_view kLabelValues[] = {"label_value_1",
"label_value_2"};
constexpr absl::string_view kOptionalLabelValues[] = {
"double_histogram", "A simple double histogram.", "unit", false)
.Labels("label_key_1", "label_key_2")
.OptionalLabels("optional_label_key_1", "optional_label_key_2")
.Build();
std::array<absl::string_view, 2> kLabelValues = {"label_value_1",
"label_value_2"};
std::array<absl::string_view, 2> kOptionalLabelValues = {
"optional_label_value_1", "optional_label_value_2"};
constexpr absl::string_view kDomain1To4 = "domain1.domain2.domain3.domain4";
auto plugin = MakeStatsPluginForTarget(kDomain1To4);
@ -629,24 +623,26 @@ TEST_F(MetricsTest, DisableByDefaultMetricIsNotRecordedByFakeStatsPlugin) {
StatsPluginChannelScope(kDomain1To4, ""))
.RecordHistogram(double_histogram_handle, 1.23, kLabelValues,
kOptionalLabelValues);
EXPECT_EQ(plugin->GetHistogramValue(double_histogram_handle, kLabelValues,
kOptionalLabelValues),
EXPECT_EQ(plugin->GetDoubleHistogramValue(double_histogram_handle,
kLabelValues, kOptionalLabelValues),
absl::nullopt);
}
using MetricsDeathTest = MetricsTest;
TEST_F(MetricsDeathTest, RegisterTheSameMetricNameWouldCrash) {
const absl::string_view kLabelKeys[] = {"label_key_1", "label_key_2"};
const absl::string_view kOptionalLabelKeys[] = {"optional_label_key_1",
"optional_label_key_2"};
(void)GlobalInstrumentsRegistry::RegisterDoubleHistogram(
"double_histogram", "A simple double histogram.", "unit", kLabelKeys,
kOptionalLabelKeys, true);
EXPECT_DEATH(GlobalInstrumentsRegistry::RegisterDoubleHistogram(
"double_histogram", "A simple double histogram.", "unit",
kLabelKeys, kOptionalLabelKeys, true),
"Metric name double_histogram has already been registered.");
"double_histogram", "A simple double histogram.", "unit", true)
.Labels("label_key_1", "label_key_2")
.OptionalLabels("optional_label_key_1", "optional_label_key_2")
.Build();
EXPECT_DEATH(
GlobalInstrumentsRegistry::RegisterDoubleHistogram(
"double_histogram", "A simple double histogram.", "unit", true)
.Labels("label_key_1", "label_key_2")
.OptionalLabels("optional_label_key_1", "optional_label_key_2")
.Build(),
"Metric name double_histogram has already been registered.");
}
} // namespace

@ -1307,8 +1307,8 @@ TEST_F(PickFirstTest, MetricValues) {
// The first subchannel's connection attempt fails.
subchannel->SetConnectivityState(GRPC_CHANNEL_TRANSIENT_FAILURE,
absl::UnavailableError("failed to connect"));
EXPECT_THAT(stats_plugin->GetCounterValue(kConnectionAttemptsFailed,
kLabelValues, {}),
EXPECT_THAT(stats_plugin->GetUInt64CounterValue(kConnectionAttemptsFailed,
kLabelValues, {}),
::testing::Optional(1));
// The LB policy will start a connection attempt on the second subchannel.
EXPECT_TRUE(subchannel2->ConnectionRequested());
@ -1317,8 +1317,8 @@ TEST_F(PickFirstTest, MetricValues) {
subchannel2->SetConnectivityState(GRPC_CHANNEL_CONNECTING);
// The connection attempt succeeds.
subchannel2->SetConnectivityState(GRPC_CHANNEL_READY);
EXPECT_THAT(stats_plugin->GetCounterValue(kConnectionAttemptsSucceeded,
kLabelValues, {}),
EXPECT_THAT(stats_plugin->GetUInt64CounterValue(kConnectionAttemptsSucceeded,
kLabelValues, {}),
::testing::Optional(1));
// The LB policy will report CONNECTING some number of times (doesn't
// matter how many) and then report READY.
@ -1332,8 +1332,9 @@ TEST_F(PickFirstTest, MetricValues) {
subchannel2->SetConnectivityState(GRPC_CHANNEL_IDLE);
ExpectReresolutionRequest();
ExpectState(GRPC_CHANNEL_IDLE);
EXPECT_THAT(stats_plugin->GetCounterValue(kDisconnections, kLabelValues, {}),
::testing::Optional(1));
EXPECT_THAT(
stats_plugin->GetUInt64CounterValue(kDisconnections, kLabelValues, {}),
::testing::Optional(1));
}
class PickFirstHealthCheckingEnabledTest : public PickFirstTest {

@ -1113,8 +1113,8 @@ TEST_F(WeightedRoundRobinTest, MetricValues) {
/*qps=*/100.0, /*eps=*/0.0)}},
{{kAddresses[0], 1}, {kAddresses[1], 3}, {kAddresses[2], 3}});
// Check endpoint weights.
EXPECT_THAT(stats_plugin->GetHistogramValue(kEndpointWeights, kLabelValues,
kOptionalLabelValues),
EXPECT_THAT(stats_plugin->GetDoubleHistogramValue(
kEndpointWeights, kLabelValues, kOptionalLabelValues),
::testing::Optional(::testing::ElementsAre(
// Picker created for first endpoint becoming READY.
0,
@ -1135,17 +1135,18 @@ TEST_F(WeightedRoundRobinTest, MetricValues) {
::testing::DoubleNear(333.333344, 0.000001))));
// RR fallback should trigger for the first 5 updates above, because
// there are less than two endpoints with valid weights.
EXPECT_THAT(stats_plugin->GetCounterValue(kRrFallback, kLabelValues,
kOptionalLabelValues),
EXPECT_THAT(stats_plugin->GetUInt64CounterValue(kRrFallback, kLabelValues,
kOptionalLabelValues),
::testing::Optional(5));
// Endpoint-not-yet-usable will be incremented once for every endpoint
// with weight 0 above.
EXPECT_THAT(stats_plugin->GetCounterValue(kEndpointWeightNotYetUsable,
kLabelValues, kOptionalLabelValues),
::testing::Optional(10));
EXPECT_THAT(
stats_plugin->GetUInt64CounterValue(kEndpointWeightNotYetUsable,
kLabelValues, kOptionalLabelValues),
::testing::Optional(10));
// There are no stale endpoint weights so far.
EXPECT_THAT(stats_plugin->GetCounterValue(kEndpointWeightStale, kLabelValues,
kOptionalLabelValues),
EXPECT_THAT(stats_plugin->GetUInt64CounterValue(
kEndpointWeightStale, kLabelValues, kOptionalLabelValues),
::testing::Optional(0));
// Advance time to make weights stale and trigger the timer callback
// to recompute weights.
@ -1156,8 +1157,8 @@ TEST_F(WeightedRoundRobinTest, MetricValues) {
picker.get(), {},
{{kAddresses[0], 3}, {kAddresses[1], 3}, {kAddresses[2], 3}});
// All three endpoints should now have stale weights.
EXPECT_THAT(stats_plugin->GetCounterValue(kEndpointWeightStale, kLabelValues,
kOptionalLabelValues),
EXPECT_THAT(stats_plugin->GetUInt64CounterValue(
kEndpointWeightStale, kLabelValues, kOptionalLabelValues),
::testing::Optional(3));
}

@ -125,8 +125,8 @@ void GlobalInstrumentsRegistryTestPeer::ResetGlobalInstrumentsRegistry() {
namespace {
template <typename HandleType>
absl::optional<HandleType> FindInstrument(
absl::optional<GlobalInstrumentsRegistry::GlobalInstrumentHandle>
FindInstrument(
const std::vector<GlobalInstrumentsRegistry::GlobalInstrumentDescriptor>&
instruments,
absl::string_view name, GlobalInstrumentsRegistry::ValueType value_type,
@ -134,7 +134,7 @@ absl::optional<HandleType> FindInstrument(
for (const auto& descriptor : instruments) {
if (descriptor.name == name && descriptor.value_type == value_type &&
descriptor.instrument_type == instrument_type) {
HandleType handle;
GlobalInstrumentsRegistry::GlobalInstrumentHandle handle;
handle.index = descriptor.index;
return handle;
}
@ -144,57 +144,51 @@ absl::optional<HandleType> FindInstrument(
} // namespace
absl::optional<GlobalInstrumentsRegistry::GlobalUInt64CounterHandle>
absl::optional<GlobalInstrumentsRegistry::GlobalInstrumentHandle>
GlobalInstrumentsRegistryTestPeer::FindUInt64CounterHandleByName(
absl::string_view name) {
return FindInstrument<GlobalInstrumentsRegistry::GlobalUInt64CounterHandle>(
GlobalInstrumentsRegistry::GetInstrumentList(), name,
GlobalInstrumentsRegistry::ValueType::kUInt64,
GlobalInstrumentsRegistry::InstrumentType::kCounter);
return FindInstrument(GlobalInstrumentsRegistry::GetInstrumentList(), name,
GlobalInstrumentsRegistry::ValueType::kUInt64,
GlobalInstrumentsRegistry::InstrumentType::kCounter);
}
absl::optional<GlobalInstrumentsRegistry::GlobalDoubleCounterHandle>
absl::optional<GlobalInstrumentsRegistry::GlobalInstrumentHandle>
GlobalInstrumentsRegistryTestPeer::FindDoubleCounterHandleByName(
absl::string_view name) {
return FindInstrument<GlobalInstrumentsRegistry::GlobalDoubleCounterHandle>(
GlobalInstrumentsRegistry::GetInstrumentList(), name,
GlobalInstrumentsRegistry::ValueType::kDouble,
GlobalInstrumentsRegistry::InstrumentType::kCounter);
return FindInstrument(GlobalInstrumentsRegistry::GetInstrumentList(), name,
GlobalInstrumentsRegistry::ValueType::kDouble,
GlobalInstrumentsRegistry::InstrumentType::kCounter);
}
absl::optional<GlobalInstrumentsRegistry::GlobalUInt64HistogramHandle>
absl::optional<GlobalInstrumentsRegistry::GlobalInstrumentHandle>
GlobalInstrumentsRegistryTestPeer::FindUInt64HistogramHandleByName(
absl::string_view name) {
return FindInstrument<GlobalInstrumentsRegistry::GlobalUInt64HistogramHandle>(
GlobalInstrumentsRegistry::GetInstrumentList(), name,
GlobalInstrumentsRegistry::ValueType::kUInt64,
GlobalInstrumentsRegistry::InstrumentType::kHistogram);
return FindInstrument(GlobalInstrumentsRegistry::GetInstrumentList(), name,
GlobalInstrumentsRegistry::ValueType::kUInt64,
GlobalInstrumentsRegistry::InstrumentType::kHistogram);
}
absl::optional<GlobalInstrumentsRegistry::GlobalDoubleHistogramHandle>
absl::optional<GlobalInstrumentsRegistry::GlobalInstrumentHandle>
GlobalInstrumentsRegistryTestPeer::FindDoubleHistogramHandleByName(
absl::string_view name) {
return FindInstrument<GlobalInstrumentsRegistry::GlobalDoubleHistogramHandle>(
GlobalInstrumentsRegistry::GetInstrumentList(), name,
GlobalInstrumentsRegistry::ValueType::kDouble,
GlobalInstrumentsRegistry::InstrumentType::kHistogram);
return FindInstrument(GlobalInstrumentsRegistry::GetInstrumentList(), name,
GlobalInstrumentsRegistry::ValueType::kDouble,
GlobalInstrumentsRegistry::InstrumentType::kHistogram);
}
absl::optional<GlobalInstrumentsRegistry::GlobalCallbackInt64GaugeHandle>
absl::optional<GlobalInstrumentsRegistry::GlobalInstrumentHandle>
GlobalInstrumentsRegistryTestPeer::FindCallbackInt64GaugeHandleByName(
absl::string_view name) {
return FindInstrument<
GlobalInstrumentsRegistry::GlobalCallbackInt64GaugeHandle>(
return FindInstrument(
GlobalInstrumentsRegistry::GetInstrumentList(), name,
GlobalInstrumentsRegistry::ValueType::kInt64,
GlobalInstrumentsRegistry::InstrumentType::kCallbackGauge);
}
absl::optional<GlobalInstrumentsRegistry::GlobalCallbackDoubleGaugeHandle>
absl::optional<GlobalInstrumentsRegistry::GlobalInstrumentHandle>
GlobalInstrumentsRegistryTestPeer::FindCallbackDoubleGaugeHandleByName(
absl::string_view name) {
return FindInstrument<
GlobalInstrumentsRegistry::GlobalCallbackDoubleGaugeHandle>(
return FindInstrument(
GlobalInstrumentsRegistry::GetInstrumentList(), name,
GlobalInstrumentsRegistry::ValueType::kDouble,
GlobalInstrumentsRegistry::InstrumentType::kCallbackGauge);

@ -17,6 +17,7 @@
#include <memory>
#include <string>
#include <type_traits>
#include <vector>
#include "absl/container/flat_hash_map.h"
@ -270,8 +271,8 @@ class FakeStatsPlugin : public StatsPlugin {
}
void AddCounter(
GlobalInstrumentsRegistry::GlobalUInt64CounterHandle handle,
uint64_t value, absl::Span<const absl::string_view> label_values,
GlobalInstrumentsRegistry::GlobalInstrumentHandle handle, uint64_t value,
absl::Span<const absl::string_view> label_values,
absl::Span<const absl::string_view> optional_values) override {
// The problem with this approach is that we initialize uint64_counters_ in
// BuildAndRegister by querying the GlobalInstrumentsRegistry at the time.
@ -283,7 +284,8 @@ class FakeStatsPlugin : public StatsPlugin {
// GlobalInstrumentsRegistry everytime a metric is recorded. But this is not
// a concern for now.
gpr_log(GPR_INFO,
"FakeStatsPlugin[%p]::AddCounter(index=%u, value=(uint64)%lu, "
"FakeStatsPlugin[%p]::AddCounter(index=%u, value=(uint64)%" PRIu64
", "
"label_values={%s}, optional_label_values={%s}",
this, handle.index, value,
absl::StrJoin(label_values, ", ").c_str(),
@ -294,7 +296,7 @@ class FakeStatsPlugin : public StatsPlugin {
iter->second.Add(value, label_values, optional_values);
}
void AddCounter(
GlobalInstrumentsRegistry::GlobalDoubleCounterHandle handle, double value,
GlobalInstrumentsRegistry::GlobalInstrumentHandle handle, double value,
absl::Span<const absl::string_view> label_values,
absl::Span<const absl::string_view> optional_values) override {
gpr_log(GPR_INFO,
@ -309,23 +311,24 @@ class FakeStatsPlugin : public StatsPlugin {
iter->second.Add(value, label_values, optional_values);
}
void RecordHistogram(
GlobalInstrumentsRegistry::GlobalUInt64HistogramHandle handle,
uint64_t value, absl::Span<const absl::string_view> label_values,
GlobalInstrumentsRegistry::GlobalInstrumentHandle handle, uint64_t value,
absl::Span<const absl::string_view> label_values,
absl::Span<const absl::string_view> optional_values) override {
gpr_log(GPR_INFO,
"FakeStatsPlugin[%p]::RecordHistogram(index=%u, value=(uint64)%lu, "
"label_values={%s}, optional_label_values={%s}",
this, handle.index, value,
absl::StrJoin(label_values, ", ").c_str(),
absl::StrJoin(optional_values, ", ").c_str());
gpr_log(
GPR_INFO,
"FakeStatsPlugin[%p]::RecordHistogram(index=%u, value=(uint64)%" PRIu64
", "
"label_values={%s}, optional_label_values={%s}",
this, handle.index, value, absl::StrJoin(label_values, ", ").c_str(),
absl::StrJoin(optional_values, ", ").c_str());
MutexLock lock(&mu_);
auto iter = uint64_histograms_.find(handle.index);
if (iter == uint64_histograms_.end()) return;
iter->second.Record(value, label_values, optional_values);
}
void RecordHistogram(
GlobalInstrumentsRegistry::GlobalDoubleHistogramHandle handle,
double value, absl::Span<const absl::string_view> label_values,
GlobalInstrumentsRegistry::GlobalInstrumentHandle handle, double value,
absl::Span<const absl::string_view> label_values,
absl::Span<const absl::string_view> optional_values) override {
gpr_log(GPR_INFO,
"FakeStatsPlugin[%p]::RecordHistogram(index=%u, value=(double)%f, "
@ -358,8 +361,8 @@ class FakeStatsPlugin : public StatsPlugin {
return nullptr;
}
absl::optional<uint64_t> GetCounterValue(
GlobalInstrumentsRegistry::GlobalUInt64CounterHandle handle,
absl::optional<uint64_t> GetUInt64CounterValue(
GlobalInstrumentsRegistry::GlobalInstrumentHandle handle,
absl::Span<const absl::string_view> label_values,
absl::Span<const absl::string_view> optional_values) {
MutexLock lock(&mu_);
@ -369,8 +372,8 @@ class FakeStatsPlugin : public StatsPlugin {
}
return iter->second.GetValue(label_values, optional_values);
}
absl::optional<double> GetCounterValue(
GlobalInstrumentsRegistry::GlobalDoubleCounterHandle handle,
absl::optional<double> GetDoubleCounterValue(
GlobalInstrumentsRegistry::GlobalInstrumentHandle handle,
absl::Span<const absl::string_view> label_values,
absl::Span<const absl::string_view> optional_values) {
MutexLock lock(&mu_);
@ -380,8 +383,8 @@ class FakeStatsPlugin : public StatsPlugin {
}
return iter->second.GetValue(label_values, optional_values);
}
absl::optional<std::vector<uint64_t>> GetHistogramValue(
GlobalInstrumentsRegistry::GlobalUInt64HistogramHandle handle,
absl::optional<std::vector<uint64_t>> GetUInt64HistogramValue(
GlobalInstrumentsRegistry::GlobalInstrumentHandle handle,
absl::Span<const absl::string_view> label_values,
absl::Span<const absl::string_view> optional_values) {
MutexLock lock(&mu_);
@ -391,8 +394,8 @@ class FakeStatsPlugin : public StatsPlugin {
}
return iter->second.GetValues(label_values, optional_values);
}
absl::optional<std::vector<double>> GetHistogramValue(
GlobalInstrumentsRegistry::GlobalDoubleHistogramHandle handle,
absl::optional<std::vector<double>> GetDoubleHistogramValue(
GlobalInstrumentsRegistry::GlobalInstrumentHandle handle,
absl::Span<const absl::string_view> label_values,
absl::Span<const absl::string_view> optional_values) {
MutexLock lock(&mu_);
@ -410,8 +413,8 @@ class FakeStatsPlugin : public StatsPlugin {
}
gpr_log(GPR_INFO, "FakeStatsPlugin[%p]::TriggerCallbacks(): END", this);
}
absl::optional<int64_t> GetCallbackGaugeValue(
GlobalInstrumentsRegistry::GlobalCallbackInt64GaugeHandle handle,
absl::optional<int64_t> GetInt64CallbackGaugeValue(
GlobalInstrumentsRegistry::GlobalInstrumentHandle handle,
absl::Span<const absl::string_view> label_values,
absl::Span<const absl::string_view> optional_values) {
MutexLock lock(&callback_mu_);
@ -421,8 +424,8 @@ class FakeStatsPlugin : public StatsPlugin {
}
return iter->second.GetValue(label_values, optional_values);
}
absl::optional<double> GetCallbackGaugeValue(
GlobalInstrumentsRegistry::GlobalCallbackDoubleGaugeHandle handle,
absl::optional<double> GetDoubleCallbackGaugeValue(
GlobalInstrumentsRegistry::GlobalInstrumentHandle handle,
absl::Span<const absl::string_view> label_values,
absl::Span<const absl::string_view> optional_values) {
MutexLock lock(&callback_mu_);
@ -438,13 +441,14 @@ class FakeStatsPlugin : public StatsPlugin {
public:
explicit Reporter(FakeStatsPlugin& plugin) : plugin_(plugin) {}
void Report(
GlobalInstrumentsRegistry::GlobalCallbackInt64GaugeHandle handle,
int64_t value, absl::Span<const absl::string_view> label_values,
void ReportInt64(
GlobalInstrumentsRegistry::GlobalInstrumentHandle handle, int64_t value,
absl::Span<const absl::string_view> label_values,
absl::Span<const absl::string_view> optional_values) override {
gpr_log(GPR_INFO,
"FakeStatsPlugin[%p]::Reporter::Report(index=%u, "
"value=(uint64)%ld, label_values={%s}, "
"value=(int64_t)%" PRId64
", label_values={%s}, "
"optional_label_values={%s}",
this, handle.index, value,
absl::StrJoin(label_values, ", ").c_str(),
@ -455,9 +459,9 @@ class FakeStatsPlugin : public StatsPlugin {
iter->second.Set(value, label_values, optional_values);
}
void Report(
GlobalInstrumentsRegistry::GlobalCallbackDoubleGaugeHandle handle,
double value, absl::Span<const absl::string_view> label_values,
void ReportDouble(
GlobalInstrumentsRegistry::GlobalInstrumentHandle handle, double value,
absl::Span<const absl::string_view> label_values,
absl::Span<const absl::string_view> optional_values) override {
gpr_log(GPR_INFO,
"FakeStatsPlugin[%p]::Reporter::Report(index=%u, "
@ -654,19 +658,17 @@ class GlobalInstrumentsRegistryTestPeer {
public:
static void ResetGlobalInstrumentsRegistry();
static absl::optional<GlobalInstrumentsRegistry::GlobalUInt64CounterHandle>
static absl::optional<GlobalInstrumentsRegistry::GlobalInstrumentHandle>
FindUInt64CounterHandleByName(absl::string_view name);
static absl::optional<GlobalInstrumentsRegistry::GlobalDoubleCounterHandle>
static absl::optional<GlobalInstrumentsRegistry::GlobalInstrumentHandle>
FindDoubleCounterHandleByName(absl::string_view name);
static absl::optional<GlobalInstrumentsRegistry::GlobalUInt64HistogramHandle>
static absl::optional<GlobalInstrumentsRegistry::GlobalInstrumentHandle>
FindUInt64HistogramHandleByName(absl::string_view name);
static absl::optional<GlobalInstrumentsRegistry::GlobalDoubleHistogramHandle>
static absl::optional<GlobalInstrumentsRegistry::GlobalInstrumentHandle>
FindDoubleHistogramHandleByName(absl::string_view name);
static absl::optional<
GlobalInstrumentsRegistry::GlobalCallbackInt64GaugeHandle>
static absl::optional<GlobalInstrumentsRegistry::GlobalInstrumentHandle>
FindCallbackInt64GaugeHandleByName(absl::string_view name);
static absl::optional<
GlobalInstrumentsRegistry::GlobalCallbackDoubleGaugeHandle>
static absl::optional<GlobalInstrumentsRegistry::GlobalInstrumentHandle>
FindCallbackDoubleGaugeHandleByName(absl::string_view name);
static GlobalInstrumentsRegistry::GlobalInstrumentDescriptor*

@ -1535,24 +1535,24 @@ TEST_F(RlsMetricsEnd2endTest, MetricValues) {
EXPECT_EQ(backends_[1]->service_.request_count(), 0);
// Check exported metrics.
EXPECT_THAT(
stats_plugin_->GetCounterValue(
stats_plugin_->GetUInt64CounterValue(
kMetricTargetPicks,
{target_uri_, rls_server_target_, rls_target0, "complete"}, {}),
::testing::Optional(1));
EXPECT_THAT(
stats_plugin_->GetCounterValue(
stats_plugin_->GetUInt64CounterValue(
kMetricTargetPicks,
{target_uri_, rls_server_target_, rls_target1, "complete"}, {}),
absl::nullopt);
EXPECT_EQ(stats_plugin_->GetCounterValue(
EXPECT_EQ(stats_plugin_->GetUInt64CounterValue(
kMetricFailedPicks, {target_uri_, rls_server_target_}, {}),
absl::nullopt);
stats_plugin_->TriggerCallbacks();
EXPECT_THAT(stats_plugin_->GetCallbackGaugeValue(
EXPECT_THAT(stats_plugin_->GetInt64CallbackGaugeValue(
kMetricCacheEntries,
{target_uri_, rls_server_target_, kRlsInstanceUuid}, {}),
::testing::Optional(1));
auto cache_size = stats_plugin_->GetCallbackGaugeValue(
auto cache_size = stats_plugin_->GetInt64CallbackGaugeValue(
kMetricCacheSize, {target_uri_, rls_server_target_, kRlsInstanceUuid},
{});
EXPECT_THAT(cache_size, ::testing::Optional(::testing::Ge(1)));
@ -1567,24 +1567,24 @@ TEST_F(RlsMetricsEnd2endTest, MetricValues) {
EXPECT_EQ(backends_[1]->service_.request_count(), 1);
// Check exported metrics.
EXPECT_THAT(
stats_plugin_->GetCounterValue(
stats_plugin_->GetUInt64CounterValue(
kMetricTargetPicks,
{target_uri_, rls_server_target_, rls_target0, "complete"}, {}),
::testing::Optional(1));
EXPECT_THAT(
stats_plugin_->GetCounterValue(
stats_plugin_->GetUInt64CounterValue(
kMetricTargetPicks,
{target_uri_, rls_server_target_, rls_target1, "complete"}, {}),
::testing::Optional(1));
EXPECT_EQ(stats_plugin_->GetCounterValue(
EXPECT_EQ(stats_plugin_->GetUInt64CounterValue(
kMetricFailedPicks, {target_uri_, rls_server_target_}, {}),
absl::nullopt);
stats_plugin_->TriggerCallbacks();
EXPECT_THAT(stats_plugin_->GetCallbackGaugeValue(
EXPECT_THAT(stats_plugin_->GetInt64CallbackGaugeValue(
kMetricCacheEntries,
{target_uri_, rls_server_target_, kRlsInstanceUuid}, {}),
::testing::Optional(2));
auto cache_size2 = stats_plugin_->GetCallbackGaugeValue(
auto cache_size2 = stats_plugin_->GetInt64CallbackGaugeValue(
kMetricCacheSize, {target_uri_, rls_server_target_, kRlsInstanceUuid},
{});
EXPECT_THAT(cache_size2, ::testing::Optional(::testing::Ge(2)));
@ -1611,24 +1611,24 @@ TEST_F(RlsMetricsEnd2endTest, MetricValues) {
EXPECT_EQ(backends_[1]->service_.request_count(), 1);
// Check exported metrics.
EXPECT_THAT(
stats_plugin_->GetCounterValue(
stats_plugin_->GetUInt64CounterValue(
kMetricTargetPicks,
{target_uri_, rls_server_target_, rls_target0, "complete"}, {}),
::testing::Optional(1));
EXPECT_THAT(
stats_plugin_->GetCounterValue(
stats_plugin_->GetUInt64CounterValue(
kMetricTargetPicks,
{target_uri_, rls_server_target_, rls_target1, "complete"}, {}),
::testing::Optional(1));
EXPECT_THAT(stats_plugin_->GetCounterValue(
EXPECT_THAT(stats_plugin_->GetUInt64CounterValue(
kMetricFailedPicks, {target_uri_, rls_server_target_}, {}),
::testing::Optional(1));
stats_plugin_->TriggerCallbacks();
EXPECT_THAT(stats_plugin_->GetCallbackGaugeValue(
EXPECT_THAT(stats_plugin_->GetInt64CallbackGaugeValue(
kMetricCacheEntries,
{target_uri_, rls_server_target_, kRlsInstanceUuid}, {}),
::testing::Optional(3));
auto cache_size3 = stats_plugin_->GetCallbackGaugeValue(
auto cache_size3 = stats_plugin_->GetInt64CallbackGaugeValue(
kMetricCacheSize, {target_uri_, rls_server_target_, kRlsInstanceUuid},
{});
EXPECT_THAT(cache_size3, ::testing::Optional(::testing::Ge(3)));
@ -1678,7 +1678,7 @@ TEST_F(RlsMetricsEnd2endTest, MetricValuesDefaultTargetRpcs) {
EXPECT_EQ(backends_[0]->service_.request_count(), 1);
// Check expected metrics.
EXPECT_THAT(
stats_plugin_->GetCounterValue(
stats_plugin_->GetUInt64CounterValue(
kMetricDefaultTargetPicks,
{target_uri_, rls_server_target_, default_target, "complete"}, {}),
::testing::Optional(1));

@ -1217,11 +1217,11 @@ TEST_P(XdsMetricsTest, MetricValues) {
CheckRpcSendOk(DEBUG_LOCATION);
stats_plugin_->TriggerCallbacks();
// Check client metrics.
EXPECT_THAT(stats_plugin_->GetCallbackGaugeValue(kMetricConnected,
{kTarget, kXdsServer}, {}),
EXPECT_THAT(stats_plugin_->GetInt64CallbackGaugeValue(
kMetricConnected, {kTarget, kXdsServer}, {}),
::testing::Optional(1));
EXPECT_THAT(stats_plugin_->GetCounterValue(kMetricServerFailure,
{kTarget, kXdsServer}, {}),
EXPECT_THAT(stats_plugin_->GetUInt64CounterValue(kMetricServerFailure,
{kTarget, kXdsServer}, {}),
absl::nullopt);
for (absl::string_view type_url :
{"envoy.config.listener.v3.Listener",
@ -1229,37 +1229,37 @@ TEST_P(XdsMetricsTest, MetricValues) {
"envoy.config.cluster.v3.Cluster",
"envoy.config.endpoint.v3.ClusterLoadAssignment"}) {
EXPECT_THAT(
stats_plugin_->GetCounterValue(kMetricResourceUpdatesValid,
{kTarget, kXdsServer, type_url}, {}),
stats_plugin_->GetUInt64CounterValue(
kMetricResourceUpdatesValid, {kTarget, kXdsServer, type_url}, {}),
::testing::Optional(1));
EXPECT_THAT(
stats_plugin_->GetCounterValue(kMetricResourceUpdatesInvalid,
{kTarget, kXdsServer, type_url}, {}),
stats_plugin_->GetUInt64CounterValue(
kMetricResourceUpdatesInvalid, {kTarget, kXdsServer, type_url}, {}),
::testing::Optional(0));
EXPECT_THAT(stats_plugin_->GetCallbackGaugeValue(
EXPECT_THAT(stats_plugin_->GetInt64CallbackGaugeValue(
kMetricResources, {kTarget, "#old", type_url, "acked"}, {}),
::testing::Optional(1));
}
// Check server metrics.
EXPECT_THAT(stats_plugin_->GetCallbackGaugeValue(kMetricConnected,
{"#server", kXdsServer}, {}),
EXPECT_THAT(stats_plugin_->GetInt64CallbackGaugeValue(
kMetricConnected, {"#server", kXdsServer}, {}),
::testing::Optional(1));
EXPECT_THAT(stats_plugin_->GetCounterValue(kMetricServerFailure,
{"#server", kXdsServer}, {}),
EXPECT_THAT(stats_plugin_->GetUInt64CounterValue(kMetricServerFailure,
{"#server", kXdsServer}, {}),
absl::nullopt);
for (absl::string_view type_url :
{"envoy.config.listener.v3.Listener",
"envoy.config.route.v3.RouteConfiguration"}) {
EXPECT_THAT(
stats_plugin_->GetCounterValue(kMetricResourceUpdatesValid,
{"#server", kXdsServer, type_url}, {}),
stats_plugin_->GetUInt64CounterValue(
kMetricResourceUpdatesValid, {"#server", kXdsServer, type_url}, {}),
::testing::Optional(1));
EXPECT_THAT(stats_plugin_->GetUInt64CounterValue(
kMetricResourceUpdatesInvalid,
{"#server", kXdsServer, type_url}, {}),
::testing::Optional(0));
EXPECT_THAT(
stats_plugin_->GetCounterValue(kMetricResourceUpdatesInvalid,
{"#server", kXdsServer, type_url}, {}),
::testing::Optional(0));
EXPECT_THAT(
stats_plugin_->GetCallbackGaugeValue(
stats_plugin_->GetInt64CallbackGaugeValue(
kMetricResources, {"#server", "#old", type_url, "acked"}, {}),
::testing::Optional(1));
}
@ -1269,8 +1269,8 @@ TEST_P(XdsMetricsTest, MetricValues) {
const absl::Time deadline =
absl::Now() + absl::Seconds(5 * grpc_test_slowdown_factor());
while (true) {
auto value = stats_plugin_->GetCounterValue(kMetricServerFailure,
{target, kXdsServer}, {});
auto value = stats_plugin_->GetUInt64CounterValue(
kMetricServerFailure, {target, kXdsServer}, {});
if (value.has_value()) {
EXPECT_EQ(1, *value);
break;
@ -1279,8 +1279,8 @@ TEST_P(XdsMetricsTest, MetricValues) {
absl::SleepFor(absl::Seconds(1));
}
stats_plugin_->TriggerCallbacks();
EXPECT_THAT(stats_plugin_->GetCallbackGaugeValue(kMetricConnected,
{target, kXdsServer}, {}),
EXPECT_THAT(stats_plugin_->GetInt64CallbackGaugeValue(
kMetricConnected, {target, kXdsServer}, {}),
::testing::Optional(0));
}
}

@ -132,12 +132,12 @@ TEST_P(WrrTest, MetricsHaveLocalityLabel) {
WaitForAllBackends(DEBUG_LOCATION);
// Make sure we have a metric value for each of the two localities.
EXPECT_THAT(
stats_plugin->GetHistogramValue(kEndpointWeights, kLabelValues,
{LocalityNameString("locality0")}),
stats_plugin->GetDoubleHistogramValue(kEndpointWeights, kLabelValues,
{LocalityNameString("locality0")}),
::testing::Optional(::testing::Not(::testing::IsEmpty())));
EXPECT_THAT(
stats_plugin->GetHistogramValue(kEndpointWeights, kLabelValues,
{LocalityNameString("locality1")}),
stats_plugin->GetDoubleHistogramValue(kEndpointWeights, kLabelValues,
{LocalityNameString("locality1")}),
::testing::Optional(::testing::Not(::testing::IsEmpty())));
}

@ -1263,7 +1263,7 @@ using OpenTelemetryPluginNPCMetricsTest = OpenTelemetryPluginEnd2EndTest;
TEST_F(OpenTelemetryPluginNPCMetricsTest, RecordUInt64Counter) {
constexpr absl::string_view kMetricName = "uint64_counter";
constexpr int kCounterValues[] = {1, 2, 3};
constexpr uint64_t kCounterValues[] = {1, 2, 3};
constexpr int64_t kCounterResult = 6;
constexpr std::array<absl::string_view, 2> kLabelKeys = {"label_key_1",
"label_key_2"};
@ -1273,9 +1273,13 @@ TEST_F(OpenTelemetryPluginNPCMetricsTest, RecordUInt64Counter) {
"label_value_2"};
constexpr std::array<absl::string_view, 2> kOptionalLabelValues = {
"optional_label_value_1", "optional_label_value_2"};
auto handle = grpc_core::GlobalInstrumentsRegistry::RegisterUInt64Counter(
kMetricName, "A simple uint64 counter.", "unit", kLabelKeys,
kOptionalLabelKeys, /*enable_by_default=*/true);
auto handle =
grpc_core::GlobalInstrumentsRegistry::RegisterUInt64Counter(
kMetricName, "A simple uint64 counter.", "unit",
/*enable_by_default=*/true)
.Labels(kLabelKeys[0], kLabelKeys[1])
.OptionalLabels(kOptionalLabelKeys[0], kOptionalLabelKeys[1])
.Build();
Init(std::move(Options()
.set_metric_names({kMetricName})
.set_channel_scope_filter(
@ -1319,9 +1323,13 @@ TEST_F(OpenTelemetryPluginNPCMetricsTest, RecordDoubleCounter) {
"label_value_2"};
constexpr std::array<absl::string_view, 2> kOptionalLabelValues = {
"optional_label_value_1", "optional_label_value_2"};
auto handle = grpc_core::GlobalInstrumentsRegistry::RegisterDoubleCounter(
kMetricName, "A simple double counter.", "unit", kLabelKeys,
kOptionalLabelKeys, /*enable_by_default=*/false);
auto handle =
grpc_core::GlobalInstrumentsRegistry::RegisterDoubleCounter(
kMetricName, "A simple double counter.", "unit",
/*enable_by_default=*/false)
.Labels(kLabelKeys[0], kLabelKeys[1])
.OptionalLabels(kOptionalLabelKeys[0], kOptionalLabelKeys[1])
.Build();
Init(std::move(Options()
.set_metric_names({kMetricName})
.set_channel_scope_filter(
@ -1355,7 +1363,7 @@ TEST_F(OpenTelemetryPluginNPCMetricsTest, RecordDoubleCounter) {
TEST_F(OpenTelemetryPluginNPCMetricsTest, RecordUInt64Histogram) {
constexpr absl::string_view kMetricName = "uint64_histogram";
constexpr int kHistogramValues[] = {1, 1, 2, 3, 4, 4, 5, 6};
constexpr uint64_t kHistogramValues[] = {1, 1, 2, 3, 4, 4, 5, 6};
constexpr int64_t kSum = 26;
constexpr int64_t kMin = 1;
constexpr int64_t kMax = 6;
@ -1368,9 +1376,13 @@ TEST_F(OpenTelemetryPluginNPCMetricsTest, RecordUInt64Histogram) {
"label_value_2"};
constexpr std::array<absl::string_view, 2> kOptionalLabelValues = {
"optional_label_value_1", "optional_label_value_2"};
auto handle = grpc_core::GlobalInstrumentsRegistry::RegisterUInt64Histogram(
kMetricName, "A simple uint64 histogram.", "unit", kLabelKeys,
kOptionalLabelKeys, /*enable_by_default=*/true);
auto handle =
grpc_core::GlobalInstrumentsRegistry::RegisterUInt64Histogram(
kMetricName, "A simple uint64 histogram.", "unit",
/*enable_by_default=*/true)
.Labels(kLabelKeys[0], kLabelKeys[1])
.OptionalLabels(kOptionalLabelKeys[0], kOptionalLabelKeys[1])
.Build();
Init(std::move(
Options()
.set_metric_names({kMetricName})
@ -1419,9 +1431,13 @@ TEST_F(OpenTelemetryPluginNPCMetricsTest, RecordDoubleHistogram) {
"label_value_2"};
constexpr std::array<absl::string_view, 2> kOptionalLabelValues = {
"optional_label_value_1", "optional_label_value_2"};
auto handle = grpc_core::GlobalInstrumentsRegistry::RegisterDoubleHistogram(
kMetricName, "A simple double histogram.", "unit", kLabelKeys,
kOptionalLabelKeys, /*enable_by_default=*/true);
auto handle =
grpc_core::GlobalInstrumentsRegistry::RegisterDoubleHistogram(
kMetricName, "A simple double histogram.", "unit",
/*enable_by_default=*/true)
.Labels(kLabelKeys[0], kLabelKeys[1])
.OptionalLabels(kOptionalLabelKeys[0], kOptionalLabelKeys[1])
.Build();
Init(std::move(
Options()
.set_metric_names({kMetricName})
@ -1466,9 +1482,13 @@ TEST_F(OpenTelemetryPluginNPCMetricsTest,
"label_value_2"};
constexpr std::array<absl::string_view, 2> kOptionalLabelValues = {
"optional_label_value_1", "optional_label_value_2"};
auto handle = grpc_core::GlobalInstrumentsRegistry::RegisterDoubleHistogram(
kMetricName, "A simple double histogram.", "unit", kLabelKeys,
kOptionalLabelKeys, /*enable_by_default=*/true);
auto handle =
grpc_core::GlobalInstrumentsRegistry::RegisterDoubleHistogram(
kMetricName, "A simple double histogram.", "unit",
/*enable_by_default=*/true)
.Labels(kLabelKeys[0], kLabelKeys[1])
.OptionalLabels(kOptionalLabelKeys[0], kOptionalLabelKeys[1])
.Build();
// Build and register a separate OpenTelemetryPlugin and verify its histogram
// recording.
grpc::internal::OpenTelemetryPluginBuilderImpl ot_builder;
@ -1592,9 +1612,14 @@ TEST_F(OpenTelemetryPluginNPCMetricsTest,
constexpr std::array<absl::string_view, 3> kActualOptionalLabelValues = {
"optional_label_value_1", "optional_label_value_2",
"optional_label_value_4"};
auto handle = grpc_core::GlobalInstrumentsRegistry::RegisterDoubleHistogram(
kMetricName, "A simple double histogram.", "unit", kLabelKeys,
kOptionalLabelKeys, /*enable_by_default=*/true);
auto handle =
grpc_core::GlobalInstrumentsRegistry::RegisterDoubleHistogram(
kMetricName, "A simple double histogram.", "unit",
/*enable_by_default=*/true)
.Labels(kLabelKeys[0], kLabelKeys[1])
.OptionalLabels(kOptionalLabelKeys[0], kOptionalLabelKeys[1],
kOptionalLabelKeys[2], kOptionalLabelKeys[3])
.Build();
Init(std::move(
Options()
.set_metric_names({kMetricName})
@ -1655,13 +1680,17 @@ TEST_F(OpenTelemetryPluginCallbackMetricsTest,
auto integer_gauge_handle =
grpc_core::GlobalInstrumentsRegistry::RegisterCallbackInt64Gauge(
kInt64CallbackGaugeMetric, "An int64 callback gauge.", "unit",
kLabelKeys, kOptionalLabelKeys,
/*enable_by_default=*/true);
/*enable_by_default=*/true)
.Labels(kLabelKeys[0], kLabelKeys[1])
.OptionalLabels(kOptionalLabelKeys[0], kOptionalLabelKeys[1])
.Build();
auto double_gauge_handle =
grpc_core::GlobalInstrumentsRegistry::RegisterCallbackDoubleGauge(
kDoubleCallbackGaugeMetric, "A double callback gauge.", "unit",
kLabelKeys, kOptionalLabelKeys,
/*enable_by_default=*/true);
/*enable_by_default=*/true)
.Labels(kLabelKeys[0], kLabelKeys[1])
.OptionalLabels(kOptionalLabelKeys[0], kOptionalLabelKeys[1])
.Build();
Init(std::move(Options()
.set_metric_names({kInt64CallbackGaugeMetric,
kDoubleCallbackGaugeMetric})
@ -1671,8 +1700,8 @@ TEST_F(OpenTelemetryPluginCallbackMetricsTest,
grpc_core::GlobalStatsPluginRegistry::GetStatsPluginsForChannel(
grpc_core::experimental::StatsPluginChannelScope(
"dns:///localhost:8080", ""));
// Multiple callbacks for the same metrics, each reporting different label
// values.
// Multiple callbacks for the same metrics, each reporting different
// label values.
int report_count_1 = 0;
int64_t int_value_1 = 1;
double double_value_1 = 0.5;
@ -1688,8 +1717,8 @@ TEST_F(OpenTelemetryPluginCallbackMetricsTest,
reporter.Report(double_gauge_handle, double_value_1++, kLabelValuesSet2,
kOptionalLabelValuesSet2);
},
{integer_gauge_handle, double_gauge_handle},
grpc_core::Duration::Milliseconds(100) * grpc_test_slowdown_factor());
grpc_core::Duration::Milliseconds(100) * grpc_test_slowdown_factor(),
integer_gauge_handle, double_gauge_handle);
int report_count_2 = 0;
int64_t int_value_2 = 1;
double double_value_2 = 0.5;
@ -1705,8 +1734,8 @@ TEST_F(OpenTelemetryPluginCallbackMetricsTest,
reporter.Report(double_gauge_handle, double_value_2++, kLabelValuesSet2,
kOptionalLabelValuesSet2);
},
{integer_gauge_handle, double_gauge_handle},
grpc_core::Duration::Milliseconds(100) * grpc_test_slowdown_factor());
grpc_core::Duration::Milliseconds(100) * grpc_test_slowdown_factor(),
integer_gauge_handle, double_gauge_handle);
constexpr int kIterations = 100;
MetricsCollectorThread collector{
this, grpc_core::Duration::Milliseconds(10) * grpc_test_slowdown_factor(),
@ -1786,13 +1815,17 @@ TEST_F(OpenTelemetryPluginCallbackMetricsTest,
auto integer_gauge_handle =
grpc_core::GlobalInstrumentsRegistry::RegisterCallbackInt64Gauge(
kInt64CallbackGaugeMetric, "An int64 callback gauge.", "unit",
kLabelKeys, kOptionalLabelKeys,
/*enable_by_default=*/true);
/*enable_by_default=*/true)
.Labels(kLabelKeys[0], kLabelKeys[1])
.OptionalLabels(kOptionalLabelKeys[0], kOptionalLabelKeys[1])
.Build();
auto double_gauge_handle =
grpc_core::GlobalInstrumentsRegistry::RegisterCallbackDoubleGauge(
kDoubleCallbackGaugeMetric, "A double callback gauge.", "unit",
kLabelKeys, kOptionalLabelKeys,
/*enable_by_default=*/true);
/*enable_by_default=*/true)
.Labels(kLabelKeys[0], kLabelKeys[1])
.OptionalLabels(kOptionalLabelKeys[0], kOptionalLabelKeys[1])
.Build();
Init(std::move(Options()
.set_metric_names({kInt64CallbackGaugeMetric,
kDoubleCallbackGaugeMetric})
@ -1802,8 +1835,8 @@ TEST_F(OpenTelemetryPluginCallbackMetricsTest,
grpc_core::GlobalStatsPluginRegistry::GetStatsPluginsForChannel(
grpc_core::experimental::StatsPluginChannelScope(
"dns:///localhost:8080", ""));
// Multiple callbacks for the same metrics, each reporting different label
// values.
// Multiple callbacks for the same metrics, each reporting different
// label values.
int report_count_1 = 0;
int64_t int_value_1 = 1;
double double_value_1 = 0.5;
@ -1819,8 +1852,8 @@ TEST_F(OpenTelemetryPluginCallbackMetricsTest,
reporter.Report(double_gauge_handle, double_value_1++, kLabelValuesSet2,
kOptionalLabelValuesSet2);
},
{integer_gauge_handle, double_gauge_handle},
grpc_core::Duration::Milliseconds(10) * grpc_test_slowdown_factor());
grpc_core::Duration::Milliseconds(10) * grpc_test_slowdown_factor(),
integer_gauge_handle, double_gauge_handle);
int report_count_2 = 0;
int64_t int_value_2 = 1;
double double_value_2 = 0.5;
@ -1836,8 +1869,8 @@ TEST_F(OpenTelemetryPluginCallbackMetricsTest,
reporter.Report(double_gauge_handle, double_value_2++, kLabelValuesSet2,
kOptionalLabelValuesSet2);
},
{integer_gauge_handle, double_gauge_handle},
grpc_core::Duration::Milliseconds(10) * grpc_test_slowdown_factor());
grpc_core::Duration::Milliseconds(10) * grpc_test_slowdown_factor(),
integer_gauge_handle, double_gauge_handle);
constexpr int kIterations = 100;
MetricsCollectorThread collector{
this,
@ -1854,7 +1887,8 @@ TEST_F(OpenTelemetryPluginCallbackMetricsTest,
std::string,
std::vector<opentelemetry::sdk::metrics::PointDataAttributes>>
data = collector.Stop();
// Verify that data is incremental without duplications (cached values).
// Verify that data is incremental without duplications (cached
// values).
EXPECT_EQ(report_count_1, kIterations);
EXPECT_EQ(report_count_2, kIterations);
EXPECT_EQ(data[kInt64CallbackGaugeMetric].size(),

Loading…
Cancel
Save