The C based gRPC (C++, Python, Ruby, Objective-C, PHP, C#) https://grpc.io/
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

640 lines
27 KiB

//
//
// Copyright 2023 gRPC authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
//
#include "src/cpp/ext/otel/otel_plugin.h"
#include "absl/functional/any_invocable.h"
#include "api/include/opentelemetry/metrics/provider.h"
#include "gmock/gmock.h"
#include "gtest/gtest.h"
#include "opentelemetry/sdk/metrics/meter_provider.h"
#include "opentelemetry/sdk/metrics/metric_reader.h"
#include <grpcpp/grpcpp.h>
#include "src/core/lib/channel/call_tracer.h"
#include "src/core/lib/config/core_configuration.h"
#include "test/core/util/test_config.h"
#include "test/cpp/end2end/test_service_impl.h"
#include "test/cpp/ext/otel/otel_test_library.h"
namespace grpc {
namespace testing {
namespace {
TEST(OTelPluginBuildTest, ApiDependency) {
opentelemetry::metrics::Provider::GetMeterProvider();
}
TEST(OTelPluginBuildTest, SdkDependency) {
opentelemetry::sdk::metrics::MeterProvider();
}
TEST_F(OTelPluginEnd2EndTest, ClientAttemptStarted) {
Init({grpc::internal::OTelClientAttemptStartedInstrumentName()});
SendRPC();
const char* kMetricName = "grpc.client.attempt.started";
auto data = ReadCurrentMetricsData(
[&](const absl::flat_hash_map<
std::string,
std::vector<opentelemetry::sdk::metrics::PointDataAttributes>>&
data) { return !data.contains(kMetricName); });
ASSERT_EQ(data[kMetricName].size(), 1);
auto point_data = absl::get_if<opentelemetry::sdk::metrics::SumPointData>(
&data[kMetricName][0].point_data);
ASSERT_NE(point_data, nullptr);
auto client_started_value = absl::get_if<int64_t>(&point_data->value_);
ASSERT_NE(client_started_value, nullptr);
EXPECT_EQ(*client_started_value, 1);
const auto& attributes = data[kMetricName][0].attributes.GetAttributes();
EXPECT_EQ(attributes.size(), 2);
const auto* method_value =
absl::get_if<std::string>(&attributes.at("grpc.method"));
ASSERT_NE(method_value, nullptr);
EXPECT_EQ(*method_value, kMethodName);
const auto* target_value =
absl::get_if<std::string>(&attributes.at("grpc.target"));
ASSERT_NE(target_value, nullptr);
EXPECT_EQ(*target_value, canonical_server_address_);
}
TEST_F(OTelPluginEnd2EndTest, ClientAttemptDuration) {
Init({grpc::internal::OTelClientAttemptDurationInstrumentName()});
SendRPC();
const char* kMetricName = "grpc.client.attempt.duration";
auto data = ReadCurrentMetricsData(
[&](const absl::flat_hash_map<
std::string,
std::vector<opentelemetry::sdk::metrics::PointDataAttributes>>&
data) { return !data.contains(kMetricName); });
ASSERT_EQ(data[kMetricName].size(), 1);
auto point_data =
absl::get_if<opentelemetry::sdk::metrics::HistogramPointData>(
&data[kMetricName][0].point_data);
ASSERT_NE(point_data, nullptr);
ASSERT_EQ(point_data->count_, 1);
const auto& attributes = data[kMetricName][0].attributes.GetAttributes();
EXPECT_EQ(attributes.size(), 3);
const auto* method_value =
absl::get_if<std::string>(&attributes.at("grpc.method"));
ASSERT_NE(method_value, nullptr);
EXPECT_EQ(*method_value, kMethodName);
const auto* target_value =
absl::get_if<std::string>(&attributes.at("grpc.target"));
ASSERT_NE(target_value, nullptr);
EXPECT_EQ(*target_value, canonical_server_address_);
const auto* status_value =
absl::get_if<std::string>(&attributes.at("grpc.status"));
ASSERT_NE(status_value, nullptr);
EXPECT_EQ(*status_value, "OK");
}
TEST_F(OTelPluginEnd2EndTest, ClientAttemptSentTotalCompressedMessageSize) {
Init({grpc::internal::
OTelClientAttemptSentTotalCompressedMessageSizeInstrumentName()});
SendRPC();
const char* kMetricName =
"grpc.client.attempt.sent_total_compressed_message_size";
auto data = ReadCurrentMetricsData(
[&](const absl::flat_hash_map<
std::string,
std::vector<opentelemetry::sdk::metrics::PointDataAttributes>>&
data) { return !data.contains(kMetricName); });
ASSERT_EQ(data[kMetricName].size(), 1);
auto point_data =
absl::get_if<opentelemetry::sdk::metrics::HistogramPointData>(
&data[kMetricName][0].point_data);
ASSERT_NE(point_data, nullptr);
ASSERT_EQ(point_data->count_, 1);
ASSERT_EQ(absl::get<int64_t>(point_data->max_), 5);
const auto& attributes = data[kMetricName][0].attributes.GetAttributes();
EXPECT_EQ(attributes.size(), 3);
const auto* method_value =
absl::get_if<std::string>(&attributes.at("grpc.method"));
ASSERT_NE(method_value, nullptr);
EXPECT_EQ(*method_value, kMethodName);
const auto* target_value =
absl::get_if<std::string>(&attributes.at("grpc.target"));
ASSERT_NE(target_value, nullptr);
EXPECT_EQ(*target_value, canonical_server_address_);
const auto* status_value =
absl::get_if<std::string>(&attributes.at("grpc.status"));
ASSERT_NE(status_value, nullptr);
EXPECT_EQ(*status_value, "OK");
}
TEST_F(OTelPluginEnd2EndTest, ClientAttemptRcvdTotalCompressedMessageSize) {
Init({grpc::internal::
OTelClientAttemptRcvdTotalCompressedMessageSizeInstrumentName()});
SendRPC();
const char* kMetricName =
"grpc.client.attempt.rcvd_total_compressed_message_size";
auto data = ReadCurrentMetricsData(
[&](const absl::flat_hash_map<
std::string,
std::vector<opentelemetry::sdk::metrics::PointDataAttributes>>&
data) { return !data.contains(kMetricName); });
ASSERT_EQ(data[kMetricName].size(), 1);
auto point_data =
absl::get_if<opentelemetry::sdk::metrics::HistogramPointData>(
&data[kMetricName][0].point_data);
ASSERT_NE(point_data, nullptr);
ASSERT_EQ(point_data->count_, 1);
ASSERT_EQ(absl::get<int64_t>(point_data->max_), 5);
const auto& attributes = data[kMetricName][0].attributes.GetAttributes();
EXPECT_EQ(attributes.size(), 3);
const auto* method_value =
absl::get_if<std::string>(&attributes.at("grpc.method"));
ASSERT_NE(method_value, nullptr);
EXPECT_EQ(*method_value, kMethodName);
const auto* target_value =
absl::get_if<std::string>(&attributes.at("grpc.target"));
ASSERT_NE(target_value, nullptr);
EXPECT_EQ(*target_value, canonical_server_address_);
const auto* status_value =
absl::get_if<std::string>(&attributes.at("grpc.status"));
ASSERT_NE(status_value, nullptr);
EXPECT_EQ(*status_value, "OK");
}
TEST_F(OTelPluginEnd2EndTest, ServerCallStarted) {
Init({grpc::internal::OTelServerCallStartedInstrumentName()});
SendRPC();
const char* kMetricName = "grpc.server.call.started";
auto data = ReadCurrentMetricsData(
[&](const absl::flat_hash_map<
std::string,
std::vector<opentelemetry::sdk::metrics::PointDataAttributes>>&
data) { return !data.contains(kMetricName); });
ASSERT_EQ(data[kMetricName].size(), 1);
auto point_data = absl::get_if<opentelemetry::sdk::metrics::SumPointData>(
&data[kMetricName][0].point_data);
ASSERT_NE(point_data, nullptr);
auto server_started_value = absl::get_if<int64_t>(&point_data->value_);
ASSERT_NE(server_started_value, nullptr);
ASSERT_EQ(*server_started_value, 1);
const auto& attributes = data[kMetricName][0].attributes.GetAttributes();
EXPECT_EQ(attributes.size(), 1);
const auto* method_value =
absl::get_if<std::string>(&attributes.at("grpc.method"));
ASSERT_NE(method_value, nullptr);
EXPECT_EQ(*method_value, kMethodName);
}
TEST_F(OTelPluginEnd2EndTest, ServerCallDuration) {
Init({grpc::internal::OTelServerCallDurationInstrumentName()});
SendRPC();
const char* kMetricName = "grpc.server.call.duration";
auto data = ReadCurrentMetricsData(
[&](const absl::flat_hash_map<
std::string,
std::vector<opentelemetry::sdk::metrics::PointDataAttributes>>&
data) { return !data.contains(kMetricName); });
ASSERT_EQ(data[kMetricName].size(), 1);
auto point_data =
absl::get_if<opentelemetry::sdk::metrics::HistogramPointData>(
&data[kMetricName][0].point_data);
ASSERT_NE(point_data, nullptr);
ASSERT_EQ(point_data->count_, 1);
const auto& attributes = data[kMetricName][0].attributes.GetAttributes();
EXPECT_EQ(attributes.size(), 2);
const auto* method_value =
absl::get_if<std::string>(&attributes.at("grpc.method"));
ASSERT_NE(method_value, nullptr);
EXPECT_EQ(*method_value, kMethodName);
const auto* status_value =
absl::get_if<std::string>(&attributes.at("grpc.status"));
ASSERT_NE(status_value, nullptr);
EXPECT_EQ(*status_value, "OK");
}
TEST_F(OTelPluginEnd2EndTest, ServerCallSentTotalCompressedMessageSize) {
Init({grpc::internal::
OTelServerCallSentTotalCompressedMessageSizeInstrumentName()});
SendRPC();
const char* kMetricName =
"grpc.server.call.sent_total_compressed_message_size";
auto data = ReadCurrentMetricsData(
[&](const absl::flat_hash_map<
std::string,
std::vector<opentelemetry::sdk::metrics::PointDataAttributes>>&
data) { return !data.contains(kMetricName); });
ASSERT_EQ(data[kMetricName].size(), 1);
auto point_data =
absl::get_if<opentelemetry::sdk::metrics::HistogramPointData>(
&data[kMetricName][0].point_data);
ASSERT_NE(point_data, nullptr);
EXPECT_EQ(point_data->count_, 1);
ASSERT_EQ(absl::get<int64_t>(point_data->max_), 5);
const auto& attributes = data[kMetricName][0].attributes.GetAttributes();
EXPECT_EQ(attributes.size(), 2);
const auto* method_value =
absl::get_if<std::string>(&attributes.at("grpc.method"));
ASSERT_NE(method_value, nullptr);
EXPECT_EQ(*method_value, kMethodName);
const auto* status_value =
absl::get_if<std::string>(&attributes.at("grpc.status"));
ASSERT_NE(status_value, nullptr);
EXPECT_EQ(*status_value, "OK");
}
TEST_F(OTelPluginEnd2EndTest, ServerCallRcvdTotalCompressedMessageSize) {
Init({grpc::internal::
OTelServerCallRcvdTotalCompressedMessageSizeInstrumentName()});
SendRPC();
const char* kMetricName =
"grpc.server.call.rcvd_total_compressed_message_size";
auto data = ReadCurrentMetricsData(
[&](const absl::flat_hash_map<
std::string,
std::vector<opentelemetry::sdk::metrics::PointDataAttributes>>&
data) { return !data.contains(kMetricName); });
ASSERT_EQ(data[kMetricName].size(), 1);
auto point_data =
absl::get_if<opentelemetry::sdk::metrics::HistogramPointData>(
&data[kMetricName][0].point_data);
ASSERT_NE(point_data, nullptr);
ASSERT_EQ(point_data->count_, 1);
ASSERT_EQ(absl::get<int64_t>(point_data->max_), 5);
const auto& attributes = data[kMetricName][0].attributes.GetAttributes();
EXPECT_EQ(attributes.size(), 2);
const auto* method_value =
absl::get_if<std::string>(&attributes.at("grpc.method"));
ASSERT_NE(method_value, nullptr);
EXPECT_EQ(*method_value, kMethodName);
const auto* status_value =
absl::get_if<std::string>(&attributes.at("grpc.status"));
ASSERT_NE(status_value, nullptr);
EXPECT_EQ(*status_value, "OK");
}
// Make sure that no meter provider results in normal operations.
TEST_F(OTelPluginEnd2EndTest, NoMeterProviderRegistered) {
Init({grpc::internal::OTelClientAttemptStartedInstrumentName()},
/*resource=*/opentelemetry::sdk::resource::Resource::Create({}),
/*labels_injector=*/nullptr,
/*test_no_meter_provider=*/true);
SendRPC();
}
// Test that a channel selector returning true records metrics on the channel.
TEST_F(OTelPluginEnd2EndTest, TargetSelectorReturnsTrue) {
Init({grpc::internal::OTelClientAttemptStartedInstrumentName()}, /*resource=*/
opentelemetry::sdk::resource::Resource::Create({}),
/*labels_injector=*/nullptr,
/*test_no_meter_provider=*/false,
/*target_selector=*/
[](absl::string_view /*target*/) { return true; });
SendRPC();
const char* kMetricName = "grpc.client.attempt.started";
auto data = ReadCurrentMetricsData(
[&](const absl::flat_hash_map<
std::string,
std::vector<opentelemetry::sdk::metrics::PointDataAttributes>>&
data) { return !data.contains(kMetricName); });
ASSERT_EQ(data[kMetricName].size(), 1);
auto point_data = absl::get_if<opentelemetry::sdk::metrics::SumPointData>(
&data[kMetricName][0].point_data);
ASSERT_NE(point_data, nullptr);
auto client_started_value = absl::get_if<int64_t>(&point_data->value_);
ASSERT_NE(client_started_value, nullptr);
EXPECT_EQ(*client_started_value, 1);
const auto& attributes = data[kMetricName][0].attributes.GetAttributes();
EXPECT_EQ(attributes.size(), 2);
const auto* method_value =
absl::get_if<std::string>(&attributes.at("grpc.method"));
ASSERT_NE(method_value, nullptr);
EXPECT_EQ(*method_value, kMethodName);
const auto* target_value =
absl::get_if<std::string>(&attributes.at("grpc.target"));
ASSERT_NE(target_value, nullptr);
EXPECT_EQ(*target_value, canonical_server_address_);
}
// Test that a target selector returning false does not record metrics on the
// channel.
TEST_F(OTelPluginEnd2EndTest, TargetSelectorReturnsFalse) {
Init({grpc::internal::OTelClientAttemptStartedInstrumentName()}, /*resource=*/
opentelemetry::sdk::resource::Resource::Create({}),
/*labels_injector=*/nullptr,
/*test_no_meter_provider=*/false,
/*target_selector=*/
[](absl::string_view /*target*/) { return false; });
SendRPC();
auto data = ReadCurrentMetricsData(
[&](const absl::flat_hash_map<
std::string,
std::vector<opentelemetry::sdk::metrics::PointDataAttributes>>&
/*data*/) { return false; });
ASSERT_TRUE(data.empty());
}
// Test that a target attribute filter returning true records metrics with the
// target as is on the channel.
TEST_F(OTelPluginEnd2EndTest, TargetAttributeFilterReturnsTrue) {
Init({grpc::internal::OTelClientAttemptStartedInstrumentName()}, /*resource=*/
opentelemetry::sdk::resource::Resource::Create({}),
/*labels_injector=*/nullptr,
/*test_no_meter_provider=*/false,
/*target_selector=*/absl::AnyInvocable<bool(absl::string_view) const>(),
/*target_attribute_filter=*/[](absl::string_view /*target*/) {
return true;
});
SendRPC();
const char* kMetricName = "grpc.client.attempt.started";
auto data = ReadCurrentMetricsData(
[&](const absl::flat_hash_map<
std::string,
std::vector<opentelemetry::sdk::metrics::PointDataAttributes>>&
data) { return !data.contains(kMetricName); });
ASSERT_EQ(data[kMetricName].size(), 1);
auto point_data = absl::get_if<opentelemetry::sdk::metrics::SumPointData>(
&data[kMetricName][0].point_data);
ASSERT_NE(point_data, nullptr);
auto client_started_value = absl::get_if<int64_t>(&point_data->value_);
ASSERT_NE(client_started_value, nullptr);
EXPECT_EQ(*client_started_value, 1);
const auto& attributes = data[kMetricName][0].attributes.GetAttributes();
EXPECT_EQ(attributes.size(), 2);
const auto* method_value =
absl::get_if<std::string>(&attributes.at("grpc.method"));
ASSERT_NE(method_value, nullptr);
EXPECT_EQ(*method_value, kMethodName);
const auto* target_value =
absl::get_if<std::string>(&attributes.at("grpc.target"));
ASSERT_NE(target_value, nullptr);
EXPECT_EQ(*target_value, canonical_server_address_);
}
// Test that a target attribute filter returning false records metrics with the
// target as "other".
TEST_F(OTelPluginEnd2EndTest, TargetAttributeFilterReturnsFalse) {
Init({grpc::internal::OTelClientAttemptStartedInstrumentName()}, /*resource=*/
opentelemetry::sdk::resource::Resource::Create({}),
/*labels_injector=*/nullptr,
/*test_no_meter_provider=*/false,
/*target_selector=*/absl::AnyInvocable<bool(absl::string_view) const>(),
/*target_attribute_filter=*/
[server_address = canonical_server_address_](
absl::string_view /*target*/) { return false; });
SendRPC();
const char* kMetricName = "grpc.client.attempt.started";
auto data = ReadCurrentMetricsData(
[&](const absl::flat_hash_map<
std::string,
std::vector<opentelemetry::sdk::metrics::PointDataAttributes>>&
/*data*/) { return false; });
ASSERT_EQ(data[kMetricName].size(), 1);
auto point_data = absl::get_if<opentelemetry::sdk::metrics::SumPointData>(
&data[kMetricName][0].point_data);
ASSERT_NE(point_data, nullptr);
auto client_started_value = absl::get_if<int64_t>(&point_data->value_);
ASSERT_NE(client_started_value, nullptr);
EXPECT_EQ(*client_started_value, 1);
const auto& attributes = data[kMetricName][0].attributes.GetAttributes();
EXPECT_EQ(attributes.size(), 2);
const auto* method_value =
absl::get_if<std::string>(&attributes.at("grpc.method"));
ASSERT_NE(method_value, nullptr);
EXPECT_EQ(*method_value, kMethodName);
const auto* target_value =
absl::get_if<std::string>(&attributes.at("grpc.target"));
ASSERT_NE(target_value, nullptr);
EXPECT_EQ(*target_value, "other");
}
// Test that generic method names are scrubbed properly on the client side.
TEST_F(OTelPluginEnd2EndTest, GenericClientRpc) {
Init({grpc::internal::OTelClientAttemptStartedInstrumentName()});
SendGenericRPC();
const char* kMetricName = "grpc.client.attempt.started";
auto data = ReadCurrentMetricsData(
[&](const absl::flat_hash_map<
std::string,
std::vector<opentelemetry::sdk::metrics::PointDataAttributes>>&
/*data*/) { return false; });
ASSERT_EQ(data[kMetricName].size(), 1);
auto point_data = absl::get_if<opentelemetry::sdk::metrics::SumPointData>(
&data[kMetricName][0].point_data);
ASSERT_NE(point_data, nullptr);
auto client_started_value = absl::get_if<int64_t>(&point_data->value_);
ASSERT_NE(client_started_value, nullptr);
EXPECT_EQ(*client_started_value, 1);
const auto& attributes = data[kMetricName][0].attributes.GetAttributes();
EXPECT_EQ(attributes.size(), 2);
const auto* method_value =
absl::get_if<std::string>(&attributes.at("grpc.method"));
ASSERT_NE(method_value, nullptr);
EXPECT_EQ(*method_value, "other");
const auto* target_value =
absl::get_if<std::string>(&attributes.at("grpc.target"));
ASSERT_NE(target_value, nullptr);
EXPECT_EQ(*target_value, canonical_server_address_);
}
// Test that generic method names are scrubbed properly on the client side if
// the method attribute filter is set and it returns false.
TEST_F(OTelPluginEnd2EndTest,
GenericClientRpcWithMethodAttributeFilterReturningFalse) {
Init({grpc::internal::OTelClientAttemptStartedInstrumentName()},
/*resource=*/opentelemetry::sdk::resource::Resource::Create({}),
/*labels_injector=*/nullptr,
/*test_no_meter_provider=*/false,
/*target_selector=*/absl::AnyInvocable<bool(absl::string_view) const>(),
/*target_attribute_filter=*/
absl::AnyInvocable<bool(absl::string_view) const>(),
/*generic_method_attribute_filter=*/
[](absl::string_view /*generic_method*/) { return false; });
SendGenericRPC();
const char* kMetricName = "grpc.client.attempt.started";
auto data = ReadCurrentMetricsData(
[&](const absl::flat_hash_map<
std::string,
std::vector<opentelemetry::sdk::metrics::PointDataAttributes>>&
/*data*/) { return false; });
ASSERT_EQ(data[kMetricName].size(), 1);
auto point_data = absl::get_if<opentelemetry::sdk::metrics::SumPointData>(
&data[kMetricName][0].point_data);
ASSERT_NE(point_data, nullptr);
auto client_started_value = absl::get_if<int64_t>(&point_data->value_);
ASSERT_NE(client_started_value, nullptr);
EXPECT_EQ(*client_started_value, 1);
const auto& attributes = data[kMetricName][0].attributes.GetAttributes();
EXPECT_EQ(attributes.size(), 2);
const auto* method_value =
absl::get_if<std::string>(&attributes.at("grpc.method"));
ASSERT_NE(method_value, nullptr);
EXPECT_EQ(*method_value, "other");
const auto* target_value =
absl::get_if<std::string>(&attributes.at("grpc.target"));
ASSERT_NE(target_value, nullptr);
EXPECT_EQ(*target_value, canonical_server_address_);
}
// Test that generic method names is not scrubbed on the client side if
// the method attribute filter is set and it returns true.
TEST_F(OTelPluginEnd2EndTest,
GenericClientRpcWithMethodAttributeFilterReturningTrue) {
Init({grpc::internal::OTelClientAttemptStartedInstrumentName()},
/*resource=*/opentelemetry::sdk::resource::Resource::Create({}),
/*labels_injector=*/nullptr,
/*test_no_meter_provider=*/false,
/*target_selector=*/absl::AnyInvocable<bool(absl::string_view) const>(),
/*target_attribute_filter=*/
absl::AnyInvocable<bool(absl::string_view) const>(),
/*generic_method_attribute_filter=*/
[](absl::string_view /*generic_method*/) { return true; });
SendGenericRPC();
const char* kMetricName = "grpc.client.attempt.started";
auto data = ReadCurrentMetricsData(
[&](const absl::flat_hash_map<
std::string,
std::vector<opentelemetry::sdk::metrics::PointDataAttributes>>&
/*data*/) { return false; });
ASSERT_EQ(data[kMetricName].size(), 1);
auto point_data = absl::get_if<opentelemetry::sdk::metrics::SumPointData>(
&data[kMetricName][0].point_data);
ASSERT_NE(point_data, nullptr);
auto client_started_value = absl::get_if<int64_t>(&point_data->value_);
ASSERT_NE(client_started_value, nullptr);
EXPECT_EQ(*client_started_value, 1);
const auto& attributes = data[kMetricName][0].attributes.GetAttributes();
EXPECT_EQ(attributes.size(), 2);
const auto* method_value =
absl::get_if<std::string>(&attributes.at("grpc.method"));
ASSERT_NE(method_value, nullptr);
EXPECT_EQ(*method_value, kGenericMethodName);
const auto* target_value =
absl::get_if<std::string>(&attributes.at("grpc.target"));
ASSERT_NE(target_value, nullptr);
EXPECT_EQ(*target_value, canonical_server_address_);
}
// Test that generic method names are scrubbed properly on the server side.
TEST_F(OTelPluginEnd2EndTest, GenericServerRpc) {
Init({grpc::internal::OTelServerCallDurationInstrumentName()});
SendGenericRPC();
const char* kMetricName = "grpc.server.call.duration";
auto data = ReadCurrentMetricsData(
[&](const absl::flat_hash_map<
std::string,
std::vector<opentelemetry::sdk::metrics::PointDataAttributes>>&
data) { return !data.contains(kMetricName); });
ASSERT_EQ(data[kMetricName].size(), 1);
auto point_data =
absl::get_if<opentelemetry::sdk::metrics::HistogramPointData>(
&data[kMetricName][0].point_data);
ASSERT_NE(point_data, nullptr);
ASSERT_EQ(point_data->count_, 1);
const auto& attributes = data[kMetricName][0].attributes.GetAttributes();
EXPECT_EQ(attributes.size(), 2);
const auto* method_value =
absl::get_if<std::string>(&attributes.at("grpc.method"));
ASSERT_NE(method_value, nullptr);
EXPECT_EQ(*method_value, "other");
const auto* status_value =
absl::get_if<std::string>(&attributes.at("grpc.status"));
ASSERT_NE(status_value, nullptr);
EXPECT_EQ(*status_value, "UNIMPLEMENTED");
}
// Test that generic method names are scrubbed properly on the server side if
// the method attribute filter is set and it returns false.
TEST_F(OTelPluginEnd2EndTest,
GenericServerRpcWithMethodAttributeFilterReturningFalse) {
Init({grpc::internal::OTelServerCallDurationInstrumentName()},
/*resource=*/opentelemetry::sdk::resource::Resource::Create({}),
/*labels_injector=*/nullptr,
/*test_no_meter_provider=*/false,
/*target_selector=*/absl::AnyInvocable<bool(absl::string_view) const>(),
/*target_attribute_filter=*/
absl::AnyInvocable<bool(absl::string_view) const>(),
/*generic_method_attribute_filter=*/
[](absl::string_view /*generic_method*/) { return false; });
SendGenericRPC();
const char* kMetricName = "grpc.server.call.duration";
auto data = ReadCurrentMetricsData(
[&](const absl::flat_hash_map<
std::string,
std::vector<opentelemetry::sdk::metrics::PointDataAttributes>>&
data) { return !data.contains(kMetricName); });
ASSERT_EQ(data[kMetricName].size(), 1);
auto point_data =
absl::get_if<opentelemetry::sdk::metrics::HistogramPointData>(
&data[kMetricName][0].point_data);
ASSERT_NE(point_data, nullptr);
ASSERT_EQ(point_data->count_, 1);
const auto& attributes = data[kMetricName][0].attributes.GetAttributes();
EXPECT_EQ(attributes.size(), 2);
const auto* method_value =
absl::get_if<std::string>(&attributes.at("grpc.method"));
ASSERT_NE(method_value, nullptr);
EXPECT_EQ(*method_value, "other");
const auto* status_value =
absl::get_if<std::string>(&attributes.at("grpc.status"));
ASSERT_NE(status_value, nullptr);
EXPECT_EQ(*status_value, "UNIMPLEMENTED");
}
// Test that generic method names are not scrubbed on the server side if
// the method attribute filter is set and it returns true.
TEST_F(OTelPluginEnd2EndTest,
GenericServerRpcWithMethodAttributeFilterReturningTrue) {
Init({grpc::internal::OTelServerCallDurationInstrumentName()},
/*resource=*/opentelemetry::sdk::resource::Resource::Create({}),
/*labels_injector=*/nullptr,
/*test_no_meter_provider=*/false,
/*target_selector=*/absl::AnyInvocable<bool(absl::string_view) const>(),
/*target_attribute_filter=*/
absl::AnyInvocable<bool(absl::string_view) const>(),
/*generic_method_attribute_filter=*/
[](absl::string_view /*generic_method*/) { return true; });
SendGenericRPC();
const char* kMetricName = "grpc.server.call.duration";
auto data = ReadCurrentMetricsData(
[&](const absl::flat_hash_map<
std::string,
std::vector<opentelemetry::sdk::metrics::PointDataAttributes>>&
data) { return !data.contains(kMetricName); });
ASSERT_EQ(data[kMetricName].size(), 1);
auto point_data =
absl::get_if<opentelemetry::sdk::metrics::HistogramPointData>(
&data[kMetricName][0].point_data);
ASSERT_NE(point_data, nullptr);
ASSERT_EQ(point_data->count_, 1);
const auto& attributes = data[kMetricName][0].attributes.GetAttributes();
EXPECT_EQ(attributes.size(), 2);
const auto* method_value =
absl::get_if<std::string>(&attributes.at("grpc.method"));
ASSERT_NE(method_value, nullptr);
EXPECT_EQ(*method_value, kGenericMethodName);
const auto* status_value =
absl::get_if<std::string>(&attributes.at("grpc.status"));
ASSERT_NE(status_value, nullptr);
EXPECT_EQ(*status_value, "UNIMPLEMENTED");
}
} // namespace
} // namespace testing
} // namespace grpc
int main(int argc, char** argv) {
grpc::testing::TestEnvironment env(&argc, argv);
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}