Skip to content

Commit 25fb431

Browse files
authored
impl(bigtable): add and test some metric utility functions (#15299)
1 parent 172b94b commit 25fb431

File tree

5 files changed

+108
-2
lines changed

5 files changed

+108
-2
lines changed

google/cloud/bigtable/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -454,6 +454,7 @@ if (BUILD_TESTING)
454454
internal/legacy_bulk_mutator_test.cc
455455
internal/legacy_row_reader_test.cc
456456
internal/logging_data_client_test.cc
457+
internal/metrics_test.cc
457458
internal/mutate_rows_limiter_test.cc
458459
internal/operation_context_test.cc
459460
internal/prefix_range_end_test.cc

google/cloud/bigtable/bigtable_client_unit_tests.bzl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ bigtable_client_unit_tests = [
5959
"internal/legacy_bulk_mutator_test.cc",
6060
"internal/legacy_row_reader_test.cc",
6161
"internal/logging_data_client_test.cc",
62+
"internal/metrics_test.cc",
6263
"internal/mutate_rows_limiter_test.cc",
6364
"internal/operation_context_test.cc",
6465
"internal/prefix_range_end_test.cc",

google/cloud/bigtable/internal/metrics.cc

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ namespace cloud {
2222
namespace bigtable_internal {
2323
GOOGLE_CLOUD_CPP_INLINE_NAMESPACE_BEGIN
2424

25-
LabelMap IntoMap(ResourceLabels const& r, DataLabels const& d) {
25+
LabelMap IntoLabelMap(ResourceLabels const& r, DataLabels const& d) {
2626
return {
2727
{"project_id", r.project_id},
2828
{"instance", r.instance},
@@ -38,6 +38,20 @@ LabelMap IntoMap(ResourceLabels const& r, DataLabels const& d) {
3838
};
3939
}
4040

41+
absl::optional<google::bigtable::v2::ResponseParams>
42+
GetResponseParamsFromTrailingMetadata(
43+
grpc::ClientContext const& client_context) {
44+
auto metadata = client_context.GetServerTrailingMetadata();
45+
auto iter = metadata.find("x-goog-ext-425905942-bin");
46+
if (iter == metadata.end()) return absl::nullopt;
47+
google::bigtable::v2::ResponseParams p;
48+
// The value for this key should always be the same in a response, so we
49+
// return the first value we find.
50+
std::string value{iter->second.data(), iter->second.size()};
51+
if (p.ParseFromString(value)) return p;
52+
return absl::nullopt;
53+
}
54+
4155
Metric::~Metric() = default;
4256

4357
GOOGLE_CLOUD_CPP_INLINE_NAMESPACE_END

google/cloud/bigtable/internal/metrics.h

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
#include "google/cloud/bigtable/internal/operation_context.h"
2121
#include "google/cloud/bigtable/version.h"
2222
#include "google/cloud/status.h"
23+
#include <google/bigtable/v2/response_params.pb.h>
2324
#include <grpcpp/grpcpp.h>
2425
#include <opentelemetry/context/context.h>
2526
#include <memory>
@@ -49,7 +50,11 @@ struct DataLabels {
4950
};
5051

5152
using LabelMap = std::unordered_map<std::string, std::string>;
52-
LabelMap IntoMap(ResourceLabels const& r, DataLabels const& d);
53+
LabelMap IntoLabelMap(ResourceLabels const& r, DataLabels const& d);
54+
55+
absl::optional<google::bigtable::v2::ResponseParams>
56+
GetResponseParamsFromTrailingMetadata(
57+
grpc::ClientContext const& client_context);
5358

5459
struct PreCallParams {
5560
OperationContext::Clock::time_point attempt_start;
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
// Copyright 2025 Google LLC
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// https://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
#ifdef GOOGLE_CLOUD_CPP_BIGTABLE_WITH_OTEL_METRICS
16+
17+
#include "google/cloud/bigtable/internal/metrics.h"
18+
#include "google/cloud/bigtable/version.h"
19+
#include "google/cloud/testing_util/validate_metadata.h"
20+
#include <gmock/gmock.h>
21+
22+
namespace google {
23+
namespace cloud {
24+
namespace bigtable_internal {
25+
GOOGLE_CLOUD_CPP_INLINE_NAMESPACE_BEGIN
26+
namespace {
27+
28+
using ::google::cloud::testing_util::SetServerMetadata;
29+
30+
using ::testing::Eq;
31+
using ::testing::Pair;
32+
using ::testing::UnorderedElementsAre;
33+
34+
TEST(LabelMap, IntoLabelMap) {
35+
ResourceLabels r{"my-project", "my-instance", "my-table", "my-cluster",
36+
"my-zone"};
37+
DataLabels d{"my-method", "my-streaming", "my-client-name",
38+
"my-client-uid", "my-app-profile", "my-status"};
39+
40+
auto label_map = IntoLabelMap(r, d);
41+
42+
EXPECT_THAT(
43+
label_map,
44+
UnorderedElementsAre(
45+
Pair("project_id", "my-project"), Pair("instance", "my-instance"),
46+
Pair("table", "my-table"), Pair("cluster", "my-cluster"),
47+
Pair("zone", "my-zone"), Pair("method", "my-method"),
48+
Pair("streaming", "my-streaming"),
49+
Pair("client_name", "my-client-name"),
50+
Pair("client_uid", "my-client-uid"),
51+
Pair("app_profile", "my-app-profile"), Pair("status", "my-status")));
52+
}
53+
54+
TEST(GetResponseParamsFromMetadata, NonEmptyHeader) {
55+
google::bigtable::v2::ResponseParams expected_response_params;
56+
expected_response_params.set_cluster_id("my-cluster");
57+
expected_response_params.set_zone_id("my-zone");
58+
grpc::ClientContext client_context;
59+
RpcMetadata server_metadata;
60+
server_metadata.trailers.emplace(
61+
"x-goog-ext-425905942-bin", expected_response_params.SerializeAsString());
62+
SetServerMetadata(client_context, server_metadata);
63+
64+
auto result = GetResponseParamsFromTrailingMetadata(client_context);
65+
ASSERT_TRUE(result);
66+
EXPECT_THAT(result->cluster_id(), Eq("my-cluster"));
67+
EXPECT_THAT(result->zone_id(), Eq("my-zone"));
68+
}
69+
70+
TEST(GetResponseParamsFromMetadata, EmptyHeader) {
71+
grpc::ClientContext client_context;
72+
RpcMetadata server_metadata;
73+
SetServerMetadata(client_context, server_metadata);
74+
75+
auto result = GetResponseParamsFromTrailingMetadata(client_context);
76+
EXPECT_FALSE(result);
77+
}
78+
79+
} // namespace
80+
GOOGLE_CLOUD_CPP_INLINE_NAMESPACE_END
81+
} // namespace bigtable_internal
82+
} // namespace cloud
83+
} // namespace google
84+
85+
#endif // GOOGLE_CLOUD_CPP_BIGTABLE_WITH_OTEL_METRICS

0 commit comments

Comments
 (0)