diff --git a/api/wasm/cpp/proxy_wasm_api.h b/api/wasm/cpp/proxy_wasm_api.h index f82a747d26d8..e8604d6cd1e3 100644 --- a/api/wasm/cpp/proxy_wasm_api.h +++ b/api/wasm/cpp/proxy_wasm_api.h @@ -355,7 +355,9 @@ class RootContext : public ContextBase { const std::string root_id_; std::unordered_map http_calls_; std::unordered_map simple_grpc_calls_; + std::unique_ptr cur_grpc_call_; std::unordered_map> grpc_calls_; + std::unique_ptr cur_grpc_stream_; std::unordered_map> grpc_streams_; }; @@ -1234,19 +1236,16 @@ inline void GrpcStreamHandlerBase::send(StringView message, bool end_of_stream) } } -inline void RootContext::onGrpcCreateInitialMetadata(uint32_t token) { +inline void RootContext::onGrpcCreateInitialMetadata(uint32_t) { { - auto it = grpc_calls_.find(token); - if (it != grpc_calls_.end()) { - it->second->onCreateInitialMetadata(); + if (cur_grpc_call_ != nullptr) { + cur_grpc_call_->onCreateInitialMetadata(); return; } } { - auto it = grpc_streams_.find(token); - if (it != grpc_streams_.end()) { - it->second->onCreateInitialMetadata(); - return; + if (cur_grpc_stream_ != nullptr) { + cur_grpc_stream_->onCreateInitialMetadata(); } } } @@ -1345,26 +1344,32 @@ inline bool RootContext::grpcCallHandler(StringView service, StringView service_ const google::protobuf::MessageLite& request, uint32_t timeout_milliseconds, std::unique_ptr handler) { + cur_grpc_call_ = std::move(handler); auto token = grpcCall(service, service_name, method_name, request, timeout_milliseconds); if (token) { - handler->token_ = token; - handler->context_ = this; - grpc_calls_[token] = std::move(handler); + cur_grpc_call_->token_ = token; + cur_grpc_call_->context_ = this; + grpc_calls_[token] = std::move(cur_grpc_call_); + cur_grpc_call_ = nullptr; return true; } + cur_grpc_call_ = nullptr; return false; } inline bool RootContext::grpcStreamHandler(StringView service, StringView service_name, StringView method_name, std::unique_ptr handler) { + cur_grpc_stream_ = std::move(handler); auto token = grpcStream(service, service_name, method_name); if (token) { - handler->token_ = token; - handler->context_ = this; - grpc_streams_[token] = std::move(handler); + cur_grpc_stream_->token_ = token; + cur_grpc_stream_->context_ = this; + grpc_streams_[token] = std::move(cur_grpc_stream_); + cur_grpc_stream_ = nullptr; return true; } + cur_grpc_stream_ = nullptr; return false; } diff --git a/source/extensions/tracers/opencensus/opencensus_tracer_impl.cc b/source/extensions/tracers/opencensus/opencensus_tracer_impl.cc index b604b9f457a0..d11144334cc7 100644 --- a/source/extensions/tracers/opencensus/opencensus_tracer_impl.cc +++ b/source/extensions/tracers/opencensus/opencensus_tracer_impl.cc @@ -232,6 +232,39 @@ Tracing::SpanPtr Span::spawnChild(const Tracing::Config& /*config*/, const std:: void Span::setSampled(bool sampled) { span_.AddAnnotation("setSampled", {{"sampled", sampled}}); } +class GoogleUserProjHeaderInterceptor : public grpc::experimental::Interceptor { +public: + GoogleUserProjHeaderInterceptor(const std::string& project_id) : project_id_(project_id) {} + + virtual void Intercept(grpc::experimental::InterceptorBatchMethods* methods) { + if (methods->QueryInterceptionHookPoint( + grpc::experimental::InterceptionHookPoints::PRE_SEND_INITIAL_METADATA)) { + auto* metadata_map = methods->GetSendInitialMetadata(); + if (metadata_map != nullptr) { + metadata_map->insert(std::make_pair("x-goog-user-project", project_id_)); + } + } + methods->Proceed(); + } + +private: + const std::string& project_id_; +}; + +class GoogleUserProjHeaderInterceptorFactory + : public grpc::experimental::ClientInterceptorFactoryInterface { +public: + GoogleUserProjHeaderInterceptorFactory(const std::string& project_id) : project_id_(project_id) {} + + virtual grpc::experimental::Interceptor* + CreateClientInterceptor(grpc::experimental::ClientRpcInfo*) override { + return new GoogleUserProjHeaderInterceptor(project_id_); + } + +private: + std::string project_id_; +}; + } // namespace Driver::Driver(const envoy::config::trace::v2::OpenCensusConfig& oc_config, @@ -250,8 +283,22 @@ Driver::Driver(const envoy::config::trace::v2::OpenCensusConfig& oc_config, sts_port = port_iter->second.string_value(); } if (oc_config.stackdriver_exporter_enabled()) { + // Try get GCP project ID from node metadata. + std::string project_id; + auto platform_md_iter = node_metadata.fields().find("PLATFORM_METADATA"); + if (platform_md_iter != node_metadata.fields().end()) { + auto platform_md = platform_md_iter->second.struct_value(); + auto proj_id_iter = platform_md.fields().find("gcp_project"); + if (proj_id_iter != platform_md.fields().end()) { + project_id = proj_id_iter->second.string_value(); + } + } ::opencensus::exporters::trace::StackdriverOptions opts; - opts.project_id = oc_config.stackdriver_project_id(); + if (!oc_config.stackdriver_project_id().empty()) { + opts.project_id = oc_config.stackdriver_project_id(); + } else if (!project_id.empty()) { + opts.project_id = project_id; + } if (!oc_config.stackdriver_address().empty()) { auto channel = grpc::CreateChannel(oc_config.stackdriver_address(), grpc::InsecureChannelCredentials()); @@ -267,9 +314,14 @@ Driver::Driver(const envoy::config::trace::v2::OpenCensusConfig& oc_config, ssl_creds_options.pem_root_certs = api.fileSystem().fileReadToEnd("/etc/ssl/certs/ca-certificates.crt"); auto channel_creds = grpc::SslCredentials(ssl_creds_options); - auto channel = - ::grpc::CreateChannel("cloudtrace.googleapis.com", - grpc::CompositeChannelCredentials(channel_creds, call_creds)); + // Create an custom channel which includes an interceptor that inject user project header. + grpc::ChannelArguments args; + std::vector> creators; + creators.push_back(std::unique_ptr( + new GoogleUserProjHeaderInterceptorFactory(project_id))); + auto channel = ::grpc::experimental::CreateCustomChannelWithInterceptors( + "cloudtrace.googleapis.com", grpc::CompositeChannelCredentials(channel_creds, call_creds), + args, std::move(creators)); opts.trace_service_stub = ::google::devtools::cloudtrace::v2::TraceService::NewStub(channel); } ::opencensus::exporters::trace::StackdriverExporter::Register(std::move(opts));