Content-Length: 1096590 | pFad | http://github.com/googleapis/google-cloud-cpp/commit/b0c1884cc281d1cc2f65bc8c494327fcc4e9190b

8F feat(ACv2): implement tracing decorator for ObjectDescriptorConnectio… · googleapis/google-cloud-cpp@b0c1884 · GitHub
Skip to content

Commit b0c1884

Browse files
bajajneha27ddelgrosso1
authored andcommitted
feat(ACv2): implement tracing decorator for ObjectDescriptorConnection (#46)
1 parent a31cedd commit b0c1884

8 files changed

+296
-2
lines changed

google/cloud/storage/google_cloud_cpp_storage_grpc.bzl

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ google_cloud_cpp_storage_grpc_hdrs = [
4242
"internal/async/default_options.h",
4343
"internal/async/handle_redirect_error.h",
4444
"internal/async/insert_object.h",
45+
"internal/async/object_descriptor_connection_tracing.h",
4546
"internal/async/object_descriptor_impl.h",
4647
"internal/async/object_descriptor_reader.h",
4748
"internal/async/open_object.h",
@@ -115,6 +116,7 @@ google_cloud_cpp_storage_grpc_srcs = [
115116
"internal/async/default_options.cc",
116117
"internal/async/handle_redirect_error.cc",
117118
"internal/async/insert_object.cc",
119+
"internal/async/object_descriptor_connection_tracing.cc",
118120
"internal/async/object_descriptor_impl.cc",
119121
"internal/async/object_descriptor_reader.cc",
120122
"internal/async/open_object.cc",

google/cloud/storage/google_cloud_cpp_storage_grpc.cmake

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,8 @@ add_library(
109109
internal/async/handle_redirect_error.h
110110
internal/async/insert_object.cc
111111
internal/async/insert_object.h
112+
internal/async/object_descriptor_connection_tracing.cc
113+
internal/async/object_descriptor_connection_tracing.h
112114
internal/async/object_descriptor_impl.cc
113115
internal/async/object_descriptor_impl.h
114116
internal/async/object_descriptor_reader.cc
@@ -430,6 +432,7 @@ set(storage_client_grpc_unit_tests
430432
internal/async/connection_tracing_test.cc
431433
internal/async/default_options_test.cc
432434
internal/async/insert_object_test.cc
435+
internal/async/object_descriptor_connection_tracing_test.cc
433436
internal/async/object_descriptor_impl_test.cc
434437
internal/async/object_descriptor_reader_test.cc
435438
internal/async/open_object_test.cc

google/cloud/storage/internal/async/connection_tracing.cc

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414

1515
#include "google/cloud/storage/internal/async/connection_tracing.h"
1616
#include "google/cloud/storage/async/writer_connection.h"
17+
#include "google/cloud/storage/internal/async/object_descriptor_connection_tracing.h"
1718
#include "google/cloud/storage/internal/async/reader_connection_tracing.h"
1819
#include "google/cloud/storage/internal/async/rewriter_connection_tracing.h"
1920
#include "google/cloud/storage/internal/async/writer_connection_tracing.h"
@@ -49,10 +50,21 @@ class AsyncConnectionTracing : public storage_experimental::AsyncConnection {
4950
future<StatusOr<
5051
std::shared_ptr<storage_experimental::ObjectDescriptorConnection>>>
5152
Open(OpenParams p) override {
52-
// TODO(#18) - decorate the ObjectDescriptor.
5353
auto span = internal::MakeSpan("storage::AsyncConnection::Open");
5454
internal::OTelScope scope(span);
55-
return internal::EndSpan(std::move(span), impl_->Open(std::move(p)));
55+
return impl_->Open(std::move(p))
56+
.then([oc = opentelemetry::context::RuntimeContext::GetCurrent(),
57+
span = std::move(span)](auto f)
58+
-> StatusOr<std::shared_ptr<
59+
storage_experimental::ObjectDescriptorConnection>> {
60+
auto result = f.get();
61+
internal::DetachOTelContext(oc);
62+
if (!result) {
63+
return internal::EndSpan(*span, std::move(result).status());
64+
}
65+
return MakeTracingObjectDescriptorConnection(std::move(span),
66+
*std::move(result));
67+
});
5668
}
5769

5870
future<StatusOr<std::unique_ptr<storage_experimental::AsyncReaderConnection>>>

google/cloud/storage/internal/async/connection_tracing_test.cc

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,10 @@
1515
#ifdef GOOGLE_CLOUD_CPP_HAVE_OPENTELEMETRY
1616

1717
#include "google/cloud/storage/internal/async/connection_tracing.h"
18+
#include "google/cloud/storage/async/object_descriptor_connection.h"
1819
#include "google/cloud/storage/async/reader_connection.h"
1920
#include "google/cloud/storage/mocks/mock_async_connection.h"
21+
#include "google/cloud/storage/mocks/mock_async_object_descriptor_connection.h"
2022
#include "google/cloud/storage/mocks/mock_async_reader_connection.h"
2123
#include "google/cloud/storage/mocks/mock_async_rewriter_connection.h"
2224
#include "google/cloud/storage/mocks/mock_async_writer_connection.h"
@@ -34,7 +36,9 @@ namespace {
3436

3537
using ::google::cloud::storage::testing::canonical_errors::PermanentError;
3638
using ::google::cloud::storage_experimental::AsyncConnection;
39+
using ::google::cloud::storage_experimental::ObjectDescriptorConnection;
3740
using ::google::cloud::storage_mocks::MockAsyncConnection;
41+
using ::google::cloud::storage_mocks::MockAsyncObjectDescriptorConnection;
3842
using ::google::cloud::storage_mocks::MockAsyncReaderConnection;
3943
using ::google::cloud::storage_mocks::MockAsyncRewriterConnection;
4044
using ::google::cloud::storage_mocks::MockAsyncWriterConnection;
@@ -544,6 +548,63 @@ TEST(ConnectionTracing, RewriteObject) {
544548
SpanHasEvents(EventNamed("gl-cpp.storage.rewrite.iterate")))));
545549
}
546550

551+
TEST(ConnectionTracing, OpenError) {
552+
auto span_catcher = InstallSpanCatcher();
553+
PromiseWithOTelContext<StatusOr<
554+
std::shared_ptr<storage_experimental::ObjectDescriptorConnection>>>
555+
p;
556+
557+
auto mock = std::make_unique<MockAsyncConnection>();
558+
EXPECT_CALL(*mock, options).WillOnce(Return(TracingEnabled()));
559+
EXPECT_CALL(*mock, Open).WillOnce(expect_context(p));
560+
auto actual = MakeTracingAsyncConnection(std::move(mock));
561+
auto result =
562+
actual->Open(AsyncConnection::OpenParams{}).then(expect_no_context);
563+
564+
p.set_value(
565+
StatusOr<
566+
std::shared_ptr<storage_experimental::ObjectDescriptorConnection>>(
567+
PermanentError()));
568+
EXPECT_THAT(result.get(), StatusIs(PermanentError().code()));
569+
570+
auto spans = span_catcher->GetSpans();
571+
EXPECT_THAT(
572+
spans, ElementsAre(
573+
AllOf(SpanNamed("storage::AsyncConnection::Open"),
574+
SpanWithStatus(opentelemetry::trace::StatusCode::kError),
575+
SpanHasInstrumentationScope(), SpanKindIsClient())));
576+
}
577+
578+
TEST(ConnectionTracing, OpenSuccess) {
579+
auto span_catcher = InstallSpanCatcher();
580+
PromiseWithOTelContext<StatusOr<
581+
std::shared_ptr<storage_experimental::ObjectDescriptorConnection>>>
582+
p;
583+
auto mock = std::make_unique<MockAsyncConnection>();
584+
EXPECT_CALL(*mock, options).WillOnce(Return(TracingEnabled()));
585+
EXPECT_CALL(*mock, Open).WillOnce(expect_context(p));
586+
587+
auto actual = MakeTracingAsyncConnection(std::move(mock));
588+
auto f = actual->Open(AsyncConnection::OpenParams{}).then(expect_no_context);
589+
590+
auto mock_descriptor =
591+
std::make_shared<MockAsyncObjectDescriptorConnection>();
592+
p.set_value(
593+
StatusOr<
594+
std::shared_ptr<storage_experimental::ObjectDescriptorConnection>>(
595+
std::move(mock_descriptor)));
596+
auto result = f.get();
597+
ASSERT_STATUS_OK(result);
598+
auto descriptor = *std::move(result);
599+
descriptor.reset();
600+
601+
auto spans = span_catcher->GetSpans();
602+
EXPECT_THAT(spans, ElementsAre(AllOf(
603+
SpanNamed("storage::AsyncConnection::Open"),
604+
SpanWithStatus(opentelemetry::trace::StatusCode::kOk),
605+
SpanHasInstrumentationScope(), SpanKindIsClient())));
606+
}
607+
547608
} // namespace
548609
GOOGLE_CLOUD_CPP_INLINE_NAMESPACE_END
549610
} // namespace storage_internal
Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
// Copyright 2024 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+
#include "google/cloud/storage/internal/async/object_descriptor_connection_tracing.h"
16+
#include "google/cloud/storage/async/reader_connection.h"
17+
#include "google/cloud/internal/opentelemetry.h"
18+
#include "google/cloud/version.h"
19+
#include <opentelemetry/trace/semantic_conventions.h>
20+
#include <memory>
21+
22+
namespace google {
23+
namespace cloud {
24+
namespace storage_internal {
25+
GOOGLE_CLOUD_CPP_INLINE_NAMESPACE_BEGIN
26+
27+
#ifdef GOOGLE_CLOUD_CPP_HAVE_OPENTELEMETRY
28+
29+
namespace {
30+
31+
namespace sc = ::opentelemetry::trace::SemanticConventions;
32+
33+
class AsyncObjectDescriptorConnectionTracing
34+
: public storage_experimental::ObjectDescriptorConnection {
35+
public:
36+
explicit AsyncObjectDescriptorConnectionTracing(
37+
opentelemetry::nostd::shared_ptr<opentelemetry::trace::Span> span,
38+
std::shared_ptr<storage_experimental::ObjectDescriptorConnection> impl)
39+
: span_(std::move(span)), impl_(std::move(impl)) {}
40+
41+
~AsyncObjectDescriptorConnectionTracing() override {
42+
internal::EndSpan(*span_);
43+
}
44+
45+
absl::optional<google::storage::v2::Object> metadata() const override {
46+
return impl_->metadata();
47+
}
48+
49+
std::unique_ptr<storage_experimental::AsyncReaderConnection> Read(
50+
ReadParams p) override {
51+
internal::OTelScope scope(span_);
52+
auto result = impl_->Read(p);
53+
// #TODO(#62) - decorate the Read operation.
54+
span_->AddEvent("gl-cpp.open.read",
55+
{{sc::kThreadId, internal::CurrentThreadId()},
56+
{"read-start", p.start},
57+
{"read-limit", p.limit}});
58+
return result;
59+
}
60+
61+
private:
62+
opentelemetry::nostd::shared_ptr<opentelemetry::trace::Span> span_;
63+
std::shared_ptr<storage_experimental::ObjectDescriptorConnection> impl_;
64+
};
65+
66+
} // namespace
67+
68+
std::shared_ptr<storage_experimental::ObjectDescriptorConnection>
69+
MakeTracingObjectDescriptorConnection(
70+
opentelemetry::nostd::shared_ptr<opentelemetry::trace::Span> span,
71+
std::shared_ptr<storage_experimental::ObjectDescriptorConnection> impl) {
72+
return std::make_unique<AsyncObjectDescriptorConnectionTracing>(
73+
std::move(span), std::move(impl));
74+
}
75+
76+
#else
77+
78+
std::shared_ptr<storage_experimental::ObjectDescriptorConnection>
79+
MakeTracingObjectDescriptorConnection(
80+
opentelemetry::nostd::shared_ptr<opentelemetry::trace::Span> span,
81+
std::shared_ptr<storage_experimental::ObjectDescriptorConnection> impl) {
82+
return impl;
83+
}
84+
85+
#endif // GOOGLE_CLOUD_CPP_HAVE_OPENTELEMETRY
86+
87+
GOOGLE_CLOUD_CPP_INLINE_NAMESPACE_END
88+
} // namespace storage_internal
89+
} // namespace cloud
90+
} // namespace google
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
// Copyright 2024 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+
#ifndef GOOGLE_CLOUD_CPP_GOOGLE_CLOUD_STORAGE_INTERNAL_ASYNC_OBJECT_DESCRIPTOR_CONNECTION_TRACING_H
16+
#define GOOGLE_CLOUD_CPP_GOOGLE_CLOUD_STORAGE_INTERNAL_ASYNC_OBJECT_DESCRIPTOR_CONNECTION_TRACING_H
17+
18+
#include "google/cloud/storage/async/object_descriptor_connection.h"
19+
#include "google/cloud/internal/opentelemetry.h"
20+
21+
namespace google {
22+
namespace cloud {
23+
namespace storage_internal {
24+
GOOGLE_CLOUD_CPP_INLINE_NAMESPACE_BEGIN
25+
26+
std::shared_ptr<storage_experimental::ObjectDescriptorConnection>
27+
MakeTracingObjectDescriptorConnection(
28+
opentelemetry::nostd::shared_ptr<opentelemetry::trace::Span> span,
29+
std::shared_ptr<storage_experimental::ObjectDescriptorConnection> impl);
30+
31+
GOOGLE_CLOUD_CPP_INLINE_NAMESPACE_END
32+
} // namespace storage_internal
33+
} // namespace cloud
34+
} // namespace google
35+
36+
#endif // GOOGLE_CLOUD_CPP_GOOGLE_CLOUD_STORAGE_INTERNAL_ASYNC_OBJECT_DESCRIPTOR_CONNECTION_TRACING_H
Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
// Copyright 2024 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_HAVE_OPENTELEMETRY
16+
17+
#include "google/cloud/storage/internal/async/object_descriptor_connection_tracing.h"
18+
#include "google/cloud/storage/async/object_descriptor_connection.h"
19+
#include "google/cloud/storage/mocks/mock_async_object_descriptor_connection.h"
20+
#include "google/cloud/storage/mocks/mock_async_reader_connection.h"
21+
#include "google/cloud/opentelemetry_options.h"
22+
#include "google/cloud/options.h"
23+
#include "google/cloud/testing_util/opentelemetry_matchers.h"
24+
#include <gmock/gmock-matchers.h>
25+
#include <gmock/gmock.h>
26+
#include <opentelemetry/trace/semantic_conventions.h>
27+
28+
namespace google {
29+
namespace cloud {
30+
namespace storage_internal {
31+
GOOGLE_CLOUD_CPP_INLINE_NAMESPACE_BEGIN
32+
namespace {
33+
34+
using ReadResponse =
35+
::google::cloud::storage_experimental::AsyncReaderConnection::ReadResponse;
36+
using ::google::cloud::storage_experimental::ObjectDescriptorConnection;
37+
using ::google::cloud::storage_mocks::MockAsyncObjectDescriptorConnection;
38+
using ::google::cloud::storage_mocks::MockAsyncReaderConnection;
39+
using ::google::cloud::testing_util::EventNamed;
40+
using ::google::cloud::testing_util::InstallSpanCatcher;
41+
using ::google::cloud::testing_util::OTelAttribute;
42+
using ::google::cloud::testing_util::OTelContextCaptured;
43+
using ::google::cloud::testing_util::PromiseWithOTelContext;
44+
using ::google::cloud::testing_util::SpanEventAttributesAre;
45+
using ::google::cloud::testing_util::SpanHasInstrumentationScope;
46+
using ::google::cloud::testing_util::SpanKindIsClient;
47+
using ::google::cloud::testing_util::SpanNamed;
48+
using ::google::cloud::testing_util::SpanWithStatus;
49+
using ::google::cloud::testing_util::ThereIsAnActiveSpan;
50+
using ::testing::_;
51+
using ::testing::Return;
52+
53+
TEST(ObjectDescriptorConnectionTracing, Read) {
54+
namespace sc = ::opentelemetry::trace::SemanticConventions;
55+
auto span_catcher = InstallSpanCatcher();
56+
57+
auto mock = std::make_unique<MockAsyncObjectDescriptorConnection>();
58+
EXPECT_CALL(*mock, Read)
59+
.WillOnce([](ObjectDescriptorConnection::ReadParams p) {
60+
EXPECT_EQ(p.start, 100);
61+
EXPECT_EQ(p.limit, 200);
62+
return std::make_unique<MockAsyncReaderConnection>();
63+
});
64+
auto actual = MakeTracingObjectDescriptorConnection(
65+
internal::MakeSpan("test-span-name"), std::move(mock));
66+
auto f1 = actual->Read(ObjectDescriptorConnection::ReadParams{100, 200});
67+
68+
actual.reset();
69+
auto spans = span_catcher->GetSpans();
70+
EXPECT_THAT(spans,
71+
ElementsAre(AllOf(
72+
SpanNamed("test-span-name"),
73+
SpanWithStatus(opentelemetry::trace::StatusCode::kOk),
74+
SpanHasInstrumentationScope(), SpanKindIsClient(),
75+
SpanHasEvents(AllOf(
76+
EventNamed("gl-cpp.open.read"),
77+
SpanEventAttributesAre(
78+
OTelAttribute<std::int64_t>("read-limit", 200),
79+
OTelAttribute<std::int64_t>("read-start", 100),
80+
OTelAttribute<std::string>(sc::kThreadId, _)))))));
81+
}
82+
83+
} // namespace
84+
GOOGLE_CLOUD_CPP_INLINE_NAMESPACE_END
85+
} // namespace storage_internal
86+
} // namespace cloud
87+
} // namespace google
88+
89+
#endif // GOOGLE_CLOUD_CPP_HAVE_OPENTELEMETRY

google/cloud/storage/storage_client_grpc_unit_tests.bzl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ storage_client_grpc_unit_tests = [
3838
"internal/async/connection_tracing_test.cc",
3939
"internal/async/default_options_test.cc",
4040
"internal/async/insert_object_test.cc",
41+
"internal/async/object_descriptor_connection_tracing_test.cc",
4142
"internal/async/object_descriptor_impl_test.cc",
4243
"internal/async/object_descriptor_reader_test.cc",
4344
"internal/async/open_object_test.cc",

0 commit comments

Comments
 (0)








ApplySandwichStrip

pFad - (p)hone/(F)rame/(a)nonymizer/(d)eclutterfier!      Saves Data!


--- a PPN by Garber Painting Akron. With Image Size Reduction included!

Fetched URL: http://github.com/googleapis/google-cloud-cpp/commit/b0c1884cc281d1cc2f65bc8c494327fcc4e9190b

Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy