Logging: Fill status code, status message and status details (#32464)

<!--

If you know who should review your pull request, please assign it to
that
person, otherwise the pull request would get assigned randomly.

If your pull request is for a specific language, please add the
appropriate
lang label.

-->
pull/32467/head
Yash Tibrewal 2 years ago committed by GitHub
parent 1910986819
commit 7b79173991
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 1
      src/cpp/ext/filters/logging/BUILD
  2. 18
      src/cpp/ext/filters/logging/logging_filter.cc
  3. 125
      test/cpp/ext/filters/logging/logging_test.cc

@ -72,6 +72,7 @@ grpc_cc_library(
"//:gpr_platform",
"//:grpc_base",
"//:grpc_client_channel",
"//:grpc_public_hdrs",
"//:grpc_resolver",
"//:uri_parser",
"//src/core:arena",

@ -44,6 +44,7 @@
#include <grpc/grpc.h>
#include <grpc/slice.h>
#include <grpc/status.h>
#include <grpc/support/log.h>
#include "src/core/ext/filters/client_channel/client_channel.h"
@ -86,7 +87,7 @@ uint64_t GetCallId() {
class MetadataEncoder {
public:
MetadataEncoder(LoggingSink::Entry::Payload* payload,
absl::string_view* status_details_bin, uint64_t log_len)
std::string* status_details_bin, uint64_t log_len)
: payload_(payload),
status_details_bin_(status_details_bin),
log_len_(log_len) {}
@ -96,7 +97,7 @@ class MetadataEncoder {
auto key = key_slice.as_string_view();
auto value = value_slice.as_string_view();
if (status_details_bin_ != nullptr && key == "grpc-status-details-bin") {
*status_details_bin_ = value;
*status_details_bin_ = std::string(value);
return;
}
if (absl::ConsumePrefix(&key, "grpc-")) {
@ -121,11 +122,20 @@ class MetadataEncoder {
template <typename Which>
void Encode(Which, const typename Which::ValueType&) {}
void Encode(grpc_core::GrpcStatusMetadata, grpc_status_code status) {
payload_->status_code = status;
}
void Encode(grpc_core::GrpcMessageMetadata,
const grpc_core::Slice& status_message) {
payload_->status_message = std::string(status_message.as_string_view());
}
bool truncated() const { return truncated_; }
private:
LoggingSink::Entry::Payload* const payload_;
absl::string_view* const status_details_bin_;
std::string* const status_details_bin_;
uint64_t log_len_;
bool truncated_ = false;
};
@ -269,7 +279,7 @@ class CallData {
SetCommonEntryFields(&entry, is_client,
LoggingSink::Entry::EventType::kServerTrailer);
if (metadata != nullptr) {
MetadataEncoder encoder(&entry.payload, nullptr,
MetadataEncoder encoder(&entry.payload, &entry.payload.status_details,
config_.max_metadata_bytes());
metadata->Encode(&encoder);
entry.payload_truncated = encoder.truncated();

@ -19,6 +19,7 @@
#include <chrono>
#include <thread> // NOLINT
#include "absl/strings/escaping.h"
#include "absl/strings/str_cat.h"
#include "gmock/gmock.h"
#include "google/protobuf/text_format.h"
@ -677,6 +678,130 @@ TEST_F(LoggingTest, CancelledRpc) {
}
}
TEST_F(LoggingTest, ServerCancelsRpc) {
g_test_logging_sink->SetConfig(
grpc::internal::LoggingSink::Config(4096, 4096));
EchoRequest request;
request.set_message("foo");
auto* error = request.mutable_param()->mutable_expected_error();
error->set_code(25);
error->set_error_message("error message");
error->set_binary_error_details("binary error details");
EchoResponse response;
grpc::ClientContext context;
grpc::Status status = stub_->Echo(&context, request, &response);
EXPECT_EQ(status.error_code(), 25);
EXPECT_EQ(status.error_message(), "error message");
EXPECT_EQ(status.error_details(), "binary error details");
EXPECT_THAT(
g_test_logging_sink->entries(),
::testing::UnorderedElementsAre(
AllOf(Field(&LoggingSink::Entry::type,
Eq(LoggingSink::Entry::EventType::kClientHeader)),
Field(&LoggingSink::Entry::logger,
Eq(LoggingSink::Entry::Logger::kClient)),
Field(&LoggingSink::Entry::authority, Eq(server_address_)),
Field(&LoggingSink::Entry::service_name,
Eq("grpc.testing.EchoTestService")),
Field(&LoggingSink::Entry::method_name, Eq("Echo"))),
AllOf(Field(&LoggingSink::Entry::type,
Eq(LoggingSink::Entry::EventType::kClientMessage)),
Field(&LoggingSink::Entry::logger,
Eq(LoggingSink::Entry::Logger::kClient)),
Field(&LoggingSink::Entry::authority, Eq(server_address_)),
Field(&LoggingSink::Entry::service_name,
Eq("grpc.testing.EchoTestService")),
Field(&LoggingSink::Entry::method_name, Eq("Echo"))),
AllOf(Field(&LoggingSink::Entry::type,
Eq(LoggingSink::Entry::EventType::kClientHalfClose)),
Field(&LoggingSink::Entry::logger,
Eq(LoggingSink::Entry::Logger::kClient)),
Field(&LoggingSink::Entry::authority, Eq(server_address_)),
Field(&LoggingSink::Entry::service_name,
Eq("grpc.testing.EchoTestService")),
Field(&LoggingSink::Entry::method_name, Eq("Echo"))),
AllOf(Field(&LoggingSink::Entry::type,
Eq(LoggingSink::Entry::EventType::kServerHeader)),
Field(&LoggingSink::Entry::logger,
Eq(LoggingSink::Entry::Logger::kClient)),
Field(&LoggingSink::Entry::authority, Eq(server_address_)),
Field(&LoggingSink::Entry::service_name,
Eq("grpc.testing.EchoTestService")),
Field(&LoggingSink::Entry::method_name, Eq("Echo")),
Field(&LoggingSink::Entry::payload,
Field(&LoggingSink::Entry::Payload::metadata,
UnorderedElementsAre(Pair(
"server-header-key", "server-header-value"))))),
AllOf(
Field(&LoggingSink::Entry::type,
Eq(LoggingSink::Entry::EventType::kServerTrailer)),
Field(&LoggingSink::Entry::logger,
Eq(LoggingSink::Entry::Logger::kClient)),
Field(&LoggingSink::Entry::authority, Eq(server_address_)),
Field(&LoggingSink::Entry::service_name,
Eq("grpc.testing.EchoTestService")),
Field(&LoggingSink::Entry::method_name, Eq("Echo")),
Field(
&LoggingSink::Entry::payload,
AllOf(
Field(&LoggingSink::Entry::Payload::metadata,
UnorderedElementsAre(Pair("server-trailer-key",
"server-trailer-value"))),
Field(&LoggingSink::Entry::Payload::status_code, Eq(25)),
Field(&LoggingSink::Entry::Payload::status_message,
Eq("error message"))))),
AllOf(Field(&LoggingSink::Entry::type,
Eq(LoggingSink::Entry::EventType::kClientHeader)),
Field(&LoggingSink::Entry::logger,
Eq(LoggingSink::Entry::Logger::kServer)),
Field(&LoggingSink::Entry::authority, Eq(server_address_)),
Field(&LoggingSink::Entry::service_name,
Eq("grpc.testing.EchoTestService")),
Field(&LoggingSink::Entry::method_name, Eq("Echo"))),
AllOf(Field(&LoggingSink::Entry::type,
Eq(LoggingSink::Entry::EventType::kClientMessage)),
Field(&LoggingSink::Entry::logger,
Eq(LoggingSink::Entry::Logger::kServer)),
Field(&LoggingSink::Entry::authority, Eq(server_address_)),
Field(&LoggingSink::Entry::service_name,
Eq("grpc.testing.EchoTestService")),
Field(&LoggingSink::Entry::method_name, Eq("Echo"))),
AllOf(Field(&LoggingSink::Entry::type,
Eq(LoggingSink::Entry::EventType::kClientHalfClose)),
Field(&LoggingSink::Entry::logger,
Eq(LoggingSink::Entry::Logger::kServer)),
Field(&LoggingSink::Entry::authority, Eq(server_address_)),
Field(&LoggingSink::Entry::service_name,
Eq("grpc.testing.EchoTestService")),
Field(&LoggingSink::Entry::method_name, Eq("Echo"))),
AllOf(Field(&LoggingSink::Entry::type,
Eq(LoggingSink::Entry::EventType::kServerHeader)),
Field(&LoggingSink::Entry::logger,
Eq(LoggingSink::Entry::Logger::kServer)),
Field(&LoggingSink::Entry::authority, Eq(server_address_)),
Field(&LoggingSink::Entry::service_name,
Eq("grpc.testing.EchoTestService")),
Field(&LoggingSink::Entry::method_name, Eq("Echo"))),
AllOf(
Field(&LoggingSink::Entry::type,
Eq(LoggingSink::Entry::EventType::kServerTrailer)),
Field(&LoggingSink::Entry::logger,
Eq(LoggingSink::Entry::Logger::kServer)),
Field(&LoggingSink::Entry::authority, Eq(server_address_)),
Field(&LoggingSink::Entry::service_name,
Eq("grpc.testing.EchoTestService")),
Field(&LoggingSink::Entry::method_name, Eq("Echo")),
Field(&LoggingSink::Entry::payload,
AllOf(Field(&LoggingSink::Entry::Payload::metadata,
UnorderedElementsAre(Pair("server-trailer-key",
"server-trailer-"
"value"))),
Field(&LoggingSink::Entry::Payload::status_code,
Eq(25)),
Field(&LoggingSink::Entry::Payload::status_message,
Eq("error message")))))));
}
} // namespace
} // namespace testing
} // namespace grpc

Loading…
Cancel
Save