Skip to content

Commit f4a44d8

Browse files
committed
feat(storage): Link traces between Open and ReadRange traces.
1 parent 6331c10 commit f4a44d8

3 files changed

Lines changed: 79 additions & 18 deletions

File tree

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

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
// limitations under the License.
1414

1515
#include "google/cloud/storage/internal/async/object_descriptor_connection_tracing.h"
16+
#include "google/cloud/storage/internal/async/reader_connection_tracing.h"
1617
#include "google/cloud/storage/async/reader_connection.h"
1718
#include "google/cloud/internal/opentelemetry.h"
1819
#include "google/cloud/version.h"
@@ -58,7 +59,9 @@ class AsyncObjectDescriptorConnectionTracing
5859
{{sc::kThreadId, internal::CurrentThreadId()},
5960
{"read-start", p.start},
6061
{"read-length", p.length}});
61-
return result;
62+
return MakeTracingReaderConnection(
63+
span_,
64+
std::move(result));
6265
}
6366

6467
private:

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

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,16 +36,39 @@ using ReadResponse =
3636
using ::google::cloud::storage_experimental::ObjectDescriptorConnection;
3737
using ::google::cloud::storage_mocks::MockAsyncObjectDescriptorConnection;
3838
using ::google::cloud::storage_mocks::MockAsyncReaderConnection;
39+
using ::google::cloud::storage_experimental::ReadPayload;
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::ThereIsAnActiveSpan;
45+
using ::google::cloud::testing_util::PromiseWithOTelContext;
4246
using ::google::cloud::testing_util::SpanEventAttributesAre;
4347
using ::google::cloud::testing_util::SpanHasInstrumentationScope;
4448
using ::google::cloud::testing_util::SpanKindIsClient;
4549
using ::google::cloud::testing_util::SpanNamed;
4650
using ::google::cloud::testing_util::SpanWithStatus;
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,56 @@ 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 = std::make_shared<MockAsyncObjectDescriptorConnection>();
107+
auto* mock_reader_ptr = new MockAsyncReaderConnection;
108+
PromiseWithOTelContext<ReadResponse> p;
109+
EXPECT_CALL(*mock_reader_ptr, Read).WillOnce(expect_context(p));
110+
111+
EXPECT_CALL(*mock_connection, Read)
112+
.WillOnce([&](ObjectDescriptorConnection::ReadParams) {
113+
return std::unique_ptr<storage_experimental::AsyncReaderConnection>(
114+
mock_reader_ptr);
115+
});
116+
117+
auto connection = MakeTracingObjectDescriptorConnection(
118+
internal::MakeSpan("test-span"), std::move(mock_connection));
119+
120+
auto reader = connection->Read({});
121+
auto f = reader->Read().then(expect_no_context);
122+
p.set_value(ReadPayload("test-payload").set_offset(123));
123+
(void)f.get();
124+
125+
connection.reset(); // End the span
126+
127+
auto spans = span_catcher->GetSpans();
128+
EXPECT_THAT(
129+
spans,
130+
ElementsAre(AllOf(
131+
SpanNamed("test-span"),
132+
SpanWithStatus(opentelemetry::trace::StatusCode::kOk),
133+
SpanHasInstrumentationScope(), SpanKindIsClient(),
134+
SpanHasEvents(
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(
141+
EventNamed("gl-cpp.read"),
142+
SpanEventAttributesAre(
143+
OTelAttribute<std::int64_t>("message.starting_offset",
144+
123),
145+
OTelAttribute<std::string>(sc::kThreadId, _),
146+
OTelAttribute<std::int64_t>("rpc.message.id", 1),
147+
// THIS WAS THE MISSING ATTRIBUTE:
148+
OTelAttribute<std::string>("rpc.message.type",
149+
"RECEIVED")))))));
150+
}
151+
79152
} // namespace
80153
GOOGLE_CLOUD_CPP_INLINE_NAMESPACE_END
81154
} // namespace storage_internal

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

Lines changed: 2 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -41,30 +41,15 @@ class ObjectDescriptorReaderTracing : public ObjectDescriptorReader {
4141
~ObjectDescriptorReaderTracing() override = default;
4242

4343
future<ObjectDescriptorReader::ReadResponse> Read() override {
44-
auto span = internal::MakeSpan("storage::AsyncConnection::ReadObjectRange");
45-
internal::OTelScope scope(span);
4644
return ObjectDescriptorReader::Read().then(
47-
[span = std::move(span),
48-
oc = opentelemetry::context::RuntimeContext::GetCurrent()](
45+
[](
4946
auto f) -> ReadResponse {
5047
auto result = f.get();
51-
internal::DetachOTelContext(oc);
48+
// internal::DetachOTelContext(oc);
5249
if (!absl::holds_alternative<Status>(result)) {
5350
auto const& payload =
5451
absl::get<storage_experimental::ReadPayload>(result);
5552

56-
span->AddEvent(
57-
"gl-cpp.read-range",
58-
{{/*sc::kRpcMessageType=*/"rpc.message.type", "RECEIVED"},
59-
{sc::kThreadId, internal::CurrentThreadId()},
60-
{"message.size", static_cast<std::uint32_t>(payload.size())}});
61-
} else {
62-
span->AddEvent(
63-
"gl-cpp.read-range",
64-
{{/*sc::kRpcMessageType=*/"rpc.message.type", "RECEIVED"},
65-
{sc::kThreadId, internal::CurrentThreadId()}});
66-
return internal::EndSpan(*span,
67-
absl::get<Status>(std::move(result)));
6853
}
6954
return result;
7055
});

0 commit comments

Comments
 (0)