Skip to content

Commit 81c1d01

Browse files
authored
feat(storage): Link traces between Open and ReadRange traces. (#15236)
* Add check for writeHandle before reansforming write_object_spec to append_object_spec * Correct the formatting * rename the any variable to rpc_status_detail * Format write_connection_impl.cc file * feat(storage): Link traces between Open and ReadRange traces. * Remove unnecessary changes * formatted the files * Use ordered matcher instead of unordered matcher
1 parent 8727ff0 commit 81c1d01

File tree

2 files changed

+74
-1
lines changed

2 files changed

+74
-1
lines changed

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

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

1515
#include "google/cloud/storage/internal/async/object_descriptor_connection_tracing.h"
1616
#include "google/cloud/storage/async/reader_connection.h"
17+
#include "google/cloud/storage/internal/async/reader_connection_tracing.h"
1718
#include "google/cloud/internal/opentelemetry.h"
1819
#include "google/cloud/version.h"
1920
#ifdef GOOGLE_CLOUD_CPP_HAVE_OPENTELEMETRY
@@ -58,7 +59,7 @@ class AsyncObjectDescriptorConnectionTracing
5859
{{sc::kThreadId, internal::CurrentThreadId()},
5960
{"read-start", p.start},
6061
{"read-length", p.length}});
61-
return result;
62+
return MakeTracingReaderConnection(span_, std::move(result));
6263
}
6364

6465
private:

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

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,18 +34,41 @@ namespace {
3434
using ReadResponse =
3535
::google::cloud::storage_experimental::AsyncReaderConnection::ReadResponse;
3636
using ::google::cloud::storage_experimental::ObjectDescriptorConnection;
37+
using ::google::cloud::storage_experimental::ReadPayload;
3738
using ::google::cloud::storage_mocks::MockAsyncObjectDescriptorConnection;
3839
using ::google::cloud::storage_mocks::MockAsyncReaderConnection;
3940
using ::google::cloud::testing_util::EventNamed;
4041
using ::google::cloud::testing_util::InstallSpanCatcher;
4142
using ::google::cloud::testing_util::OTelAttribute;
43+
using ::google::cloud::testing_util::OTelContextCaptured;
44+
using ::google::cloud::testing_util::PromiseWithOTelContext;
4245
using ::google::cloud::testing_util::SpanEventAttributesAre;
4346
using ::google::cloud::testing_util::SpanHasInstrumentationScope;
4447
using ::google::cloud::testing_util::SpanKindIsClient;
4548
using ::google::cloud::testing_util::SpanNamed;
4649
using ::google::cloud::testing_util::SpanWithStatus;
50+
using ::google::cloud::testing_util::ThereIsAnActiveSpan;
4751
using ::testing::_;
4852

53+
// A helper to set expectations on a mock async reader. It captures the OTel
54+
// context and returns a future that can be controlled by the test.
55+
auto expect_context = [](auto& p) {
56+
return [&p] {
57+
EXPECT_TRUE(ThereIsAnActiveSpan());
58+
EXPECT_TRUE(OTelContextCaptured());
59+
return p.get_future();
60+
};
61+
};
62+
63+
// A helper to be used in a `.then()` clause. It verifies the OTel context
64+
// has been detached before the user receives the result.
65+
auto expect_no_context = [](auto f) {
66+
auto t = f.get();
67+
EXPECT_FALSE(ThereIsAnActiveSpan());
68+
EXPECT_FALSE(OTelContextCaptured());
69+
return t;
70+
};
71+
4972
TEST(ObjectDescriptorConnectionTracing, Read) {
5073
namespace sc = ::opentelemetry::trace::SemanticConventions;
5174
auto span_catcher = InstallSpanCatcher();
@@ -76,6 +99,55 @@ TEST(ObjectDescriptorConnectionTracing, Read) {
7699
OTelAttribute<std::string>(sc::kThreadId, _)))))));
77100
}
78101

102+
TEST(ObjectDescriptorConnectionTracing, ReadThenRead) {
103+
namespace sc = ::opentelemetry::trace::SemanticConventions;
104+
auto span_catcher = InstallSpanCatcher();
105+
106+
auto mock_connection =
107+
std::make_shared<MockAsyncObjectDescriptorConnection>();
108+
auto* mock_reader_ptr = new MockAsyncReaderConnection;
109+
PromiseWithOTelContext<ReadResponse> p;
110+
EXPECT_CALL(*mock_reader_ptr, Read).WillOnce(expect_context(p));
111+
112+
EXPECT_CALL(*mock_connection, Read)
113+
.WillOnce([&](ObjectDescriptorConnection::ReadParams) {
114+
return std::unique_ptr<storage_experimental::AsyncReaderConnection>(
115+
mock_reader_ptr);
116+
});
117+
118+
auto connection = MakeTracingObjectDescriptorConnection(
119+
internal::MakeSpan("test-span"), std::move(mock_connection));
120+
121+
auto reader = connection->Read({});
122+
auto f = reader->Read().then(expect_no_context);
123+
p.set_value(ReadPayload("test-payload").set_offset(123));
124+
(void)f.get();
125+
126+
connection.reset(); // End the span
127+
128+
auto spans = span_catcher->GetSpans();
129+
EXPECT_THAT(
130+
spans, ElementsAre(AllOf(
131+
SpanNamed("test-span"),
132+
SpanWithStatus(opentelemetry::trace::StatusCode::kOk),
133+
SpanHasInstrumentationScope(), SpanKindIsClient(),
134+
SpanEventsAre(
135+
AllOf(EventNamed("gl-cpp.open.read"),
136+
SpanEventAttributesAre(
137+
OTelAttribute<std::int64_t>("read-length", 0),
138+
OTelAttribute<std::int64_t>("read-start", 0),
139+
OTelAttribute<std::string>(sc::kThreadId, _))),
140+
AllOf(EventNamed("gl-cpp.read"),
141+
SpanEventAttributesAre(
142+
OTelAttribute<std::int64_t>(
143+
"message.starting_offset", 123),
144+
OTelAttribute<std::string>(sc::kThreadId, _),
145+
OTelAttribute<std::int64_t>("rpc.message.id", 1),
146+
// THIS WAS THE MISSING ATTRIBUTE:
147+
OTelAttribute<std::string>("rpc.message.type",
148+
"RECEIVED")))))));
149+
}
150+
79151
} // namespace
80152
GOOGLE_CLOUD_CPP_INLINE_NAMESPACE_END
81153
} // namespace storage_internal

0 commit comments

Comments
 (0)