diff --git a/components/data_server/request_handler/get_values_v2_handler.cc b/components/data_server/request_handler/get_values_v2_handler.cc index 1854a3f9..23ac9946 100644 --- a/components/data_server/request_handler/get_values_v2_handler.cc +++ b/components/data_server/request_handler/get_values_v2_handler.cc @@ -274,8 +274,9 @@ grpc::Status GetValuesV2Handler::GetValues( const V2EncoderDecoder& v2_codec) const { PS_VLOG(9) << "Update log context " << request.log_context() << ";" << request.consented_debug_config(); - request_context_factory.UpdateLogContext(request.log_context(), - request.consented_debug_config()); + request_context_factory.UpdateLogContext( + request.log_context(), request.consented_debug_config(), + [response]() { return response->mutable_debug_info(); }); if (request.partitions().empty()) { return grpc::Status(StatusCode::INTERNAL, "At least 1 partition is required"); diff --git a/components/data_server/request_handler/get_values_v2_handler_test.cc b/components/data_server/request_handler/get_values_v2_handler_test.cc index 6f3fa90a..7e9b88f0 100644 --- a/components/data_server/request_handler/get_values_v2_handler_test.cc +++ b/components/data_server/request_handler/get_values_v2_handler_test.cc @@ -409,6 +409,13 @@ INSTANTIATE_TEST_SUITE_P( .core_request_body = kv_server:: kConsentedV2RequestMultiplePartitionsWithLogContextInJson, .is_consented = true, + }, + TestingParameters{ + .protocol_type = ProtocolType::kObliviousHttp, + .content_type = kContentEncodingCborHeaderValue, + .core_request_body = kv_server:: + kConsentedV2RequestMultiPartWithDebugInfoResponseInJson, + .is_consented = true, })); TEST_P(GetValuesHandlerTest, Success) { diff --git a/components/util/request_context.cc b/components/util/request_context.cc index 6531b4fc..4616b334 100644 --- a/components/util/request_context.cc +++ b/components/util/request_context.cc @@ -38,9 +38,12 @@ RequestLogContext& RequestContext::GetRequestLogContext() const { void RequestContext::UpdateLogContext( const privacy_sandbox::server_common::LogContext& log_context, const privacy_sandbox::server_common::ConsentedDebugConfiguration& - consented_debug_config) { - request_log_context_ = - std::make_unique(log_context, consented_debug_config); + consented_debug_config, + std::optional< + absl::AnyInvocable> + debug_info_opt) { + request_log_context_ = std::make_unique( + log_context, consented_debug_config, std::move(debug_info_opt)); if (request_log_context_->GetRequestLoggingContext().is_consented()) { const std::string generation_id = request_log_context_->GetLogContext().generation_id().empty() @@ -71,11 +74,21 @@ RequestContext::GetPSLogContext() const { RequestLogContext::RequestLogContext( const privacy_sandbox::server_common::LogContext& log_context, const privacy_sandbox::server_common::ConsentedDebugConfiguration& - consented_debug_config) + consented_debug_config, + std::optional< + absl::AnyInvocable> + debug_info_opt) : log_context_(log_context), consented_debug_config_(consented_debug_config), request_logging_context_(GetContextMap(log_context), - consented_debug_config) {} + consented_debug_config) { + if (debug_info_opt.has_value()) { + request_logging_context_ = + privacy_sandbox::server_common::log::ContextImpl<>( + GetContextMap(log_context), consented_debug_config, + std::move(debug_info_opt.value())); + } +} privacy_sandbox::server_common::log::ContextImpl<>& RequestLogContext::GetRequestLoggingContext() { @@ -111,8 +124,12 @@ const RequestContext& RequestContextFactory::Get() const { void RequestContextFactory::UpdateLogContext( const privacy_sandbox::server_common::LogContext& log_context, const privacy_sandbox::server_common::ConsentedDebugConfiguration& - consented_debug_config) { - request_context_->UpdateLogContext(log_context, consented_debug_config); + consented_debug_config, + std::optional< + absl::AnyInvocable> + debug_info_opt) { + request_context_->UpdateLogContext(log_context, consented_debug_config, + std::move(debug_info_opt)); } } // namespace kv_server diff --git a/components/util/request_context.h b/components/util/request_context.h index 07fc8c80..835aaf48 100644 --- a/components/util/request_context.h +++ b/components/util/request_context.h @@ -18,6 +18,7 @@ #define COMPONENTS_UTIL_REQUEST_CONTEXT_H_ #include +#include #include #include @@ -33,7 +34,10 @@ class RequestLogContext { explicit RequestLogContext( const privacy_sandbox::server_common::LogContext& log_context, const privacy_sandbox::server_common::ConsentedDebugConfiguration& - consented_debug_config); + consented_debug_config, + std::optional< + absl::AnyInvocable> + debug_info_opt = std::nullopt); privacy_sandbox::server_common::log::ContextImpl<>& GetRequestLoggingContext(); @@ -79,7 +83,10 @@ class RequestContext { void UpdateLogContext( const privacy_sandbox::server_common::LogContext& log_context, const privacy_sandbox::server_common::ConsentedDebugConfiguration& - consented_debug_config); + consented_debug_config, + std::optional< + absl::AnyInvocable> + debug_info_opt = std::nullopt); UdfRequestMetricsContext& GetUdfRequestMetricsContext() const; InternalLookupMetricsContext& GetInternalLookupMetricsContext() const; RequestLogContext& GetRequestLogContext() const; @@ -128,7 +135,10 @@ class RequestContextFactory { void UpdateLogContext( const privacy_sandbox::server_common::LogContext& log_context, const privacy_sandbox::server_common::ConsentedDebugConfiguration& - consented_debug_config); + consented_debug_config, + std::optional< + absl::AnyInvocable> + debug_info_opt = std::nullopt); // Not movable and copyable to prevent making unnecessary // copies of underlying shared_ptr of request context, and moving of // shared ownership of request context diff --git a/public/query/v2/get_values_v2.proto b/public/query/v2/get_values_v2.proto index 70090b4a..a6de26da 100644 --- a/public/query/v2/get_values_v2.proto +++ b/public/query/v2/get_values_v2.proto @@ -132,4 +132,8 @@ message GetValuesResponse { // Note that single partition responses in cbor are not currently supported. ResponsePartition single_partition = 1; repeated CompressionGroup compression_groups = 2; + // Debug logs to send back to upstream servers (only in non_prod) + // The server name in the debug info will be set by the upstream servers after + // they get response from KV server + privacy_sandbox.server_common.DebugInfo debug_info = 3; } diff --git a/public/test_util/request_example.h b/public/test_util/request_example.h index 9194b0ab..7d4509ac 100644 --- a/public/test_util/request_example.h +++ b/public/test_util/request_example.h @@ -318,6 +318,73 @@ constexpr std::string_view } })"; +// Consented V2 request example with multiple partitions with log context and +// debug info response flag +constexpr std::string_view + kConsentedV2RequestMultiPartWithDebugInfoResponseInJson = + R"( + { + "metadata": { + "hostname": "example.com" + }, + "partitions": [ + { + "id": 0, + "compressionGroupId": 0, + "arguments": [ + { + "tags": [ + "structured", + "groupNames" + ], + "data": [ + "hello" + ] + } + ] + }, + { + "id": 1, + "compressionGroupId": 1, + "arguments": [ + { + "tags": [ + "custom", + "keys" + ], + "data": [ + "key1" + ] + } + ] + }, + { + "id": 2, + "compressionGroupId": 0, + "arguments": [ + { + "tags": [ + "custom", + "keys" + ], + "data": [ + "key2" + ] + } + ] + } + ], + "consented_debug_config": { + "is_consented": true, + "token": "debug_token", + "is_debug_info_in_response": true + }, + "log_context": { + "generation_id": "client_UUID", + "adtech_debug_id": "adtech_debug_test" + } + })"; + // Example consented debug token used in the unit tests constexpr std::string_view kExampleConsentedDebugToken = "debug_token";