Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
68 changes: 68 additions & 0 deletions google/cloud/storage/internal/async/open_object.cc
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,10 @@
#include "google/cloud/storage/internal/async/open_object.h"
#include "google/cloud/internal/make_status.h"
#include "absl/strings/str_cat.h"
#ifdef GOOGLE_CLOUD_CPP_STORAGE_WITH_OTEL_METRICS
#include "google/cloud/internal/opentelemetry.h"
#include <opentelemetry/metrics/provider.h>
#endif
#include <utility>

namespace google {
Expand All @@ -40,7 +44,39 @@ OpenObject::OpenObject(storage_internal::StorageStub& stub, CompletionQueue& cq,
stub, cq, std::move(context), std::move(options), request))),
initial_request_(std::move(request)) {}

#ifdef GOOGLE_CLOUD_CPP_STORAGE_WITH_OTEL_METRICS
struct StreamOpenMetrics {
opentelemetry::nostd::shared_ptr<opentelemetry::metrics::Histogram<double>>
stream_open_latency;
opentelemetry::nostd::shared_ptr<opentelemetry::metrics::Histogram<double>>
network_handshake;
opentelemetry::nostd::shared_ptr<opentelemetry::metrics::Histogram<double>>
server_metadata_latency;

static StreamOpenMetrics const& Instance() {
static auto const metrics = [] {
auto meter =
opentelemetry::metrics::Provider::GetMeterProvider()->GetMeter(
"storage", "v1");
return StreamOpenMetrics{
meter->CreateDoubleHistogram("gl-cpp.latency.stream_open",
"End-to-End Stream Open", "us"),
meter->CreateDoubleHistogram("gl-cpp.latency.network_handshake",
"Network Handshake", "us"),
meter->CreateDoubleHistogram("gl-cpp.latency.server_metadata",
"Server Metadata Latency", "us"),
};
}();
return metrics;
}
};
#endif

future<StatusOr<OpenStreamResult>> OpenObject::Call() {
#ifdef GOOGLE_CLOUD_CPP_STORAGE_WITH_OTEL_METRICS
t0_ = std::chrono::steady_clock::now();
span_ = opentelemetry::trace::Tracer::GetCurrentSpan();
#endif
Comment thread
kalragauri marked this conversation as resolved.
auto future = promise_.get_future();
rpc_->Start().then([w = WeakFromThis()](auto f) {
if (auto self = w.lock()) self->OnStart(f.get());
Expand All @@ -63,13 +99,19 @@ std::unique_ptr<OpenStream::StreamingRpc> OpenObject::CreateRpc(
}

void OpenObject::OnStart(bool ok) {
#ifdef GOOGLE_CLOUD_CPP_STORAGE_WITH_OTEL_METRICS
t1_ = std::chrono::steady_clock::now();
#endif
if (!ok) return DoFinish();
Comment thread
kalragauri marked this conversation as resolved.
rpc_->Write(initial_request_).then([w = WeakFromThis()](auto f) {
if (auto self = w.lock()) self->OnWrite(f.get());
});
}

void OpenObject::OnWrite(bool ok) {
#ifdef GOOGLE_CLOUD_CPP_STORAGE_WITH_OTEL_METRICS
t2_ = std::chrono::steady_clock::now();
#endif
if (!ok) return DoFinish();
Comment thread
kalragauri marked this conversation as resolved.
rpc_->Read().then([w = WeakFromThis()](auto f) {
if (auto self = w.lock()) self->OnRead(f.get());
Expand All @@ -78,6 +120,32 @@ void OpenObject::OnWrite(bool ok) {

void OpenObject::OnRead(
std::optional<google::storage::v2::BidiReadObjectResponse> response) {
#ifdef GOOGLE_CLOUD_CPP_STORAGE_WITH_OTEL_METRICS
auto t3 = std::chrono::steady_clock::now();
auto const& metrics = StreamOpenMetrics::Instance();

auto p1 = static_cast<double>(
std::chrono::duration_cast<std::chrono::microseconds>(t1_ - t0_).count());
auto p2 = static_cast<double>(
std::chrono::duration_cast<std::chrono::microseconds>(t3 - t2_).count());
auto p3 = static_cast<double>(
std::chrono::duration_cast<std::chrono::microseconds>(t3 - t0_).count());

auto bucket = initial_request_.read_object_spec().bucket();
metrics.network_handshake->Record(p1, {{"gcp.storage.bucket", bucket}},
opentelemetry::context::Context{});
metrics.server_metadata_latency->Record(p2, {{"gcp.storage.bucket", bucket}},
opentelemetry::context::Context{});
metrics.stream_open_latency->Record(p3, {{"gcp.storage.bucket", bucket}},
opentelemetry::context::Context{});

if (span_ && span_->GetContext().IsValid()) {
span_->AddEvent("gl-cpp.open.read",
{{"gl-cpp.latency.network_handshake", p1},
{"gl-cpp.latency.server_metadata", p2},
{"gl-cpp.latency.stream_open", p3}});
}
#endif
if (!response) return DoFinish();
promise_.set_value(OpenStreamResult{std::move(rpc_), std::move(*response)});
}
Expand Down
7 changes: 7 additions & 0 deletions google/cloud/storage/internal/async/open_object.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
#include "google/cloud/version.h"
#include "google/storage/v2/storage.pb.h"
#include <grpcpp/grpcpp.h>
#include <chrono>
#include <memory>
#include <string>

Expand Down Expand Up @@ -107,6 +108,12 @@ class OpenObject : public std::enable_shared_from_this<OpenObject> {
std::shared_ptr<OpenStream> rpc_;
promise<StatusOr<OpenStreamResult>> promise_;
google::storage::v2::BidiReadObjectRequest initial_request_;
#ifdef GOOGLE_CLOUD_CPP_STORAGE_WITH_OTEL_METRICS
std::chrono::steady_clock::time_point t0_;
std::chrono::steady_clock::time_point t1_;
std::chrono::steady_clock::time_point t2_;
opentelemetry::nostd::shared_ptr<opentelemetry::trace::Span> span_;
#endif
Comment thread
kalragauri marked this conversation as resolved.
};

GOOGLE_CLOUD_CPP_INLINE_NAMESPACE_END
Expand Down