Skip to content

Commit b68564c

Browse files
authored
impl(bigtable): test grpc otel plugin configuration (#16347)
1 parent 35f0af3 commit b68564c

3 files changed

Lines changed: 126 additions & 16 deletions

File tree

google/cloud/bigtable/internal/grpc_metrics_exporter.cc

Lines changed: 39 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -289,15 +289,11 @@ MonitoredResourceResult MakeMonitoredResource(
289289
return MonitoredResourceResult{std::move(project_id), std::move(resource)};
290290
}
291291

292-
void EnableGrpcMetrics(
292+
GrpcMetricsPluginConfig MakeGrpcMetricsPluginConfig(
293+
// NOLINTNEXTLINE(performance-unnecessary-value-param)
294+
opentelemetry::sdk::resource::Resource detected_resource,
293295
std::shared_ptr<monitoring_v3::MetricServiceConnection> const& conn,
294296
Options const& options, std::string const& client_uid) {
295-
auto authority = options.get<AuthorityOption>();
296-
if (!GrpcMetricsExporterRegistry::Singleton().Register(authority)) return;
297-
298-
auto detector = otel::MakeResourceDetector();
299-
auto detected_resource = detector->Detect();
300-
301297
auto dynamic_resource_fn =
302298
[options, client_uid, detected_resource = std::move(detected_resource)](
303299
opentelemetry::sdk::metrics::PointDataAttributes const& pda) {
@@ -357,7 +353,7 @@ void EnableGrpcMetrics(
357353
auto provider =
358354
MakeGrpcMeterProvider(std::move(exporter), std::move(reader_options));
359355

360-
auto const metrics = std::vector<std::string_view>{
356+
auto metrics = std::vector<std::string_view>{
361357
std::string_view{"grpc.client.attempt.duration"},
362358
std::string_view{"grpc.lb.rls.default_target_picks"},
363359
std::string_view{"grpc.lb.rls.target_picks"},
@@ -370,13 +366,14 @@ void EnableGrpcMetrics(
370366
std::string_view{"grpc.subchannel.open_connections"},
371367
};
372368

373-
auto const disable_metrics = std::vector<std::string_view>{
369+
auto disable_metrics = std::vector<std::string_view>{
374370
std::string_view{
375371
"grpc.client.attempt.sent_total_compressed_message_size"},
376372
std::string_view{
377373
"grpc.client.attempt.rcvd_total_compressed_message_size"},
378374
};
379375

376+
auto authority = options.get<AuthorityOption>();
380377
auto scope_filter =
381378
[authority = std::move(authority)](
382379
grpc::OpenTelemetryPluginBuilder::ChannelScope const& scope) {
@@ -386,15 +383,41 @@ void EnableGrpcMetrics(
386383
<< " vs expected authority=" << authority;
387384
return scope.default_authority() == authority;
388385
};
386+
387+
auto generic_method_filter = [](std::string_view target) {
388+
return absl::StartsWith(target, "google.bigtable.v2");
389+
};
390+
391+
return GrpcMetricsPluginConfig{
392+
std::move(provider), std::move(metrics),
393+
std::move(disable_metrics), std::move(generic_method_filter),
394+
std::move(scope_filter),
395+
};
396+
}
397+
398+
GrpcMetricsPluginConfig MakeGrpcMetricsPluginConfig(
399+
std::shared_ptr<monitoring_v3::MetricServiceConnection> const& conn,
400+
Options const& options, std::string const& client_uid) {
401+
auto detector = otel::MakeResourceDetector();
402+
return MakeGrpcMetricsPluginConfig(detector->Detect(), conn, options,
403+
client_uid);
404+
}
405+
406+
void EnableGrpcMetrics(
407+
std::shared_ptr<monitoring_v3::MetricServiceConnection> const& conn,
408+
Options const& options, std::string const& client_uid) {
409+
auto const& authority = options.get<AuthorityOption>();
410+
if (!GrpcMetricsExporterRegistry::Singleton().Register(authority)) return;
411+
412+
auto config = MakeGrpcMetricsPluginConfig(conn, options, client_uid);
389413
auto status =
390414
grpc::OpenTelemetryPluginBuilder()
391-
.SetMeterProvider(provider)
392-
.EnableMetrics(metrics)
393-
.DisableMetrics(disable_metrics)
394-
.SetGenericMethodAttributeFilter([](std::string_view target) {
395-
return absl::StartsWith(target, "google.bigtable.v2");
396-
})
397-
.SetChannelScopeFilter(std::move(scope_filter))
415+
.SetMeterProvider(config.meter_provider)
416+
.EnableMetrics(config.enabled_metrics)
417+
.DisableMetrics(config.disabled_metrics)
418+
.SetGenericMethodAttributeFilter(
419+
std::move(config.generic_method_filter))
420+
.SetChannelScopeFilter(std::move(config.channel_scope_filter))
398421
.BuildAndRegisterGlobal();
399422
if (!status.ok()) {
400423
GCP_LOG(ERROR) << "Cannot register provider status=" << status.ToString();

google/cloud/bigtable/internal/grpc_metrics_exporter.h

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,11 +25,14 @@
2525
#ifdef GOOGLE_CLOUD_CPP_BIGTABLE_WITH_GRPC_OTEL_METRICS
2626
#include "google/cloud/monitoring/v3/metric_connection.h"
2727
#include "google/api/monitored_resource.pb.h"
28+
#include <grpcpp/ext/otel_plugin.h>
2829
#include <opentelemetry/metrics/meter_provider.h>
2930
#include <opentelemetry/sdk/metrics/data/metric_data.h>
3031
#include <opentelemetry/sdk/metrics/export/periodic_exporting_metric_reader.h>
3132
#include <opentelemetry/sdk/metrics/push_metric_exporter.h>
3233
#include <opentelemetry/sdk/resource/resource.h>
34+
#include <functional>
35+
#include <string_view>
3336
#include <vector>
3437
#endif // GOOGLE_CLOUD_CPP_BIGTABLE_WITH_GRPC_OTEL_METRICS
3538

@@ -95,6 +98,24 @@ std::shared_ptr<opentelemetry::metrics::MeterProvider> MakeGrpcMeterProvider(
9598
opentelemetry::sdk::metrics::PeriodicExportingMetricReaderOptions
9699
reader_options);
97100

101+
struct GrpcMetricsPluginConfig {
102+
std::shared_ptr<opentelemetry::metrics::MeterProvider> meter_provider;
103+
std::vector<std::string_view> enabled_metrics;
104+
std::vector<std::string_view> disabled_metrics;
105+
std::function<bool(std::string_view)> generic_method_filter;
106+
std::function<bool(grpc::OpenTelemetryPluginBuilder::ChannelScope const&)>
107+
channel_scope_filter;
108+
};
109+
110+
GrpcMetricsPluginConfig MakeGrpcMetricsPluginConfig(
111+
opentelemetry::sdk::resource::Resource detected_resource,
112+
std::shared_ptr<monitoring_v3::MetricServiceConnection> const& conn,
113+
Options const& options, std::string const& client_uid);
114+
115+
GrpcMetricsPluginConfig MakeGrpcMetricsPluginConfig(
116+
std::shared_ptr<monitoring_v3::MetricServiceConnection> const& conn,
117+
Options const& options, std::string const& client_uid);
118+
98119
void EnableGrpcMetrics(
99120
std::shared_ptr<monitoring_v3::MetricServiceConnection> const& conn,
100121
Options const& options, std::string const& client_uid);

google/cloud/bigtable/internal/grpc_metrics_exporter_test.cc

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
#include "google/cloud/bigtable/version.h"
2020
#include "google/cloud/grpc_options.h"
2121
#include "google/cloud/options.h"
22+
#include <grpc/event_engine/endpoint_config.h>
2223
#include <gmock/gmock.h>
2324
#include <grpcpp/grpcpp.h>
2425
#include <opentelemetry/metrics/meter.h>
@@ -57,6 +58,7 @@ using ::testing::Ge;
5758
using ::testing::IsEmpty;
5859
using ::testing::Le;
5960
using ::testing::Not;
61+
using ::testing::NotNull;
6062
using ::testing::ResultOf;
6163
using ::testing::Return;
6264
using ::testing::SizeIs;
@@ -161,6 +163,19 @@ auto TestReaderOptions() {
161163
return reader_options;
162164
}
163165

166+
class DummyEndpointConfig
167+
: public grpc_event_engine::experimental::EndpointConfig {
168+
public:
169+
~DummyEndpointConfig() override = default;
170+
std::optional<int> GetInt(absl::string_view) const override {
171+
return std::nullopt;
172+
}
173+
std::optional<absl::string_view> GetString(absl::string_view) const override {
174+
return std::nullopt;
175+
}
176+
void* GetVoidPointer(absl::string_view) const override { return nullptr; }
177+
};
178+
164179
class DummyMetricServiceConnection
165180
: public monitoring_v3::MetricServiceConnection {
166181
public:
@@ -393,6 +408,57 @@ TEST(GrpcMetricsExporterTest, ValidateGrpcClientAttemptDuration) {
393408
}
394409
}
395410

411+
TEST(GrpcMetricsExporterTest, ValidatePluginConfigArguments) {
412+
Options options;
413+
options.set<AuthorityOption>("custom-bigtable-authority.googleapis.com");
414+
options.set<bigtable::AppProfileIdOption>("test-app-profile");
415+
options.set<bigtable::MetricsPeriodOption>(std::chrono::seconds(60));
416+
auto conn = std::make_shared<DummyMetricServiceConnection>();
417+
std::string const client_uid = "test-client-uid";
418+
419+
auto config = MakeGrpcMetricsPluginConfig(conn, options, client_uid);
420+
421+
EXPECT_THAT(config.meter_provider, NotNull());
422+
423+
EXPECT_THAT(
424+
config.enabled_metrics,
425+
ElementsAre("grpc.client.attempt.duration",
426+
"grpc.lb.rls.default_target_picks",
427+
"grpc.lb.rls.target_picks", "grpc.lb.rls.failed_picks",
428+
"grpc.xds_client.server_failure",
429+
"grpc.xds_client.resource_updates_invalid",
430+
"grpc.subchannel.disconnections",
431+
"grpc.subchannel.connection_attempts_succeeded",
432+
"grpc.subchannel.connection_attempts_failed",
433+
"grpc.subchannel.open_connections"));
434+
435+
EXPECT_THAT(
436+
config.disabled_metrics,
437+
ElementsAre("grpc.client.attempt.sent_total_compressed_message_size",
438+
"grpc.client.attempt.rcvd_total_compressed_message_size"));
439+
440+
ASSERT_TRUE(config.generic_method_filter);
441+
EXPECT_TRUE(
442+
config.generic_method_filter("google.bigtable.v2.Bigtable/ReadRows"));
443+
EXPECT_TRUE(
444+
config.generic_method_filter("google.bigtable.v2.Bigtable/MutateRow"));
445+
EXPECT_FALSE(
446+
config.generic_method_filter("google.storage.v2.Storage/ReadObject"));
447+
EXPECT_FALSE(
448+
config.generic_method_filter("google.spanner.v1.Spanner/ExecuteSql"));
449+
EXPECT_FALSE(config.generic_method_filter(""));
450+
451+
ASSERT_TRUE(config.channel_scope_filter);
452+
DummyEndpointConfig endpoint_config;
453+
grpc::OpenTelemetryPluginBuilder::ChannelScope matching_scope(
454+
"custom-target", "custom-bigtable-authority.googleapis.com",
455+
endpoint_config);
456+
grpc::OpenTelemetryPluginBuilder::ChannelScope non_matching_scope(
457+
"custom-target", "other-authority.googleapis.com", endpoint_config);
458+
EXPECT_TRUE(config.channel_scope_filter(matching_scope));
459+
EXPECT_FALSE(config.channel_scope_filter(non_matching_scope));
460+
}
461+
396462
} // namespace
397463
GOOGLE_CLOUD_CPP_INLINE_NAMESPACE_END
398464
} // namespace bigtable_internal

0 commit comments

Comments
 (0)