Gcp Observability Logging: Add handling for adding entry as a json payload (#31723)

pull/31734/head
Yash Tibrewal 2 years ago committed by GitHub
parent 224c72b524
commit 15c4a98bc7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 2
      src/cpp/ext/filters/logging/BUILD
  2. 19
      src/cpp/ext/filters/logging/logging_sink.h
  3. 1
      src/cpp/ext/gcp/BUILD
  4. 141
      src/cpp/ext/gcp/observability_logging_sink.cc
  5. 4
      src/cpp/ext/gcp/observability_logging_sink.h
  6. 749
      test/cpp/ext/gcp/observability_logging_sink_test.cc

@ -35,7 +35,6 @@ grpc_cc_library(
],
external_deps = [
"absl/strings",
"absl/time",
],
language = "c++",
visibility = [
@ -44,5 +43,6 @@ grpc_cc_library(
],
deps = [
"//:gpr_platform",
"//src/core:time",
],
)

@ -27,7 +27,8 @@
#include <string>
#include "absl/strings/string_view.h"
#include "absl/time/time.h"
#include "src/core/lib/gprpp/time.h"
namespace grpc {
namespace internal {
@ -72,11 +73,11 @@ class LoggingSink {
struct Payload {
std::map<std::string, std::string> metadata;
absl::Duration duration;
uint32_t status_code;
grpc_core::Duration timeout;
uint32_t status_code = 0;
std::string status_message;
std::string status_details;
uint32_t message_length;
uint32_t message_length = 0;
std::string message;
};
@ -87,12 +88,12 @@ class LoggingSink {
uint32_t ip_port;
};
uint64_t call_id;
uint64_t sequence_id;
EventType type;
Logger logger;
uint64_t call_id = 0;
uint64_t sequence_id = 0;
EventType type = LoggingSink::Entry::EventType::kUnkown;
Logger logger = LoggingSink::Entry::Logger::kUnkown;
Payload payload;
bool payload_truncated;
bool payload_truncated = false;
Address peer;
std::string authority;
std::string service_name;

@ -101,6 +101,7 @@ grpc_cc_library(
],
external_deps = [
"absl/strings",
"absl/strings:str_format",
"absl/types:optional",
"googleapis_logging_grpc_service",
],

@ -25,6 +25,7 @@
#include <algorithm>
#include <utility>
#include "absl/strings/str_format.h"
#include "absl/types/optional.h"
#include "google/logging/v2/logging.grpc.pb.h"
@ -98,7 +99,133 @@ LoggingSink::Config ObservabilityLoggingSink::FindMatch(
return LoggingSink::Config(0, 0);
}
void ObservabilityLoggingSink::LogEntry(Entry /* entry */) {
namespace {
std::string EventTypeToString(LoggingSink::Entry::EventType type) {
switch (type) {
case LoggingSink::Entry::EventType::kClientHeader:
return "CLIENT_HEADER";
case LoggingSink::Entry::EventType::kServerHeader:
return "SERVER_HEADER";
case LoggingSink::Entry::EventType::kClientMessage:
return "CLIENT_MESSAGE";
case LoggingSink::Entry::EventType::kServerMessage:
return "SERVER_MESSAGE";
case LoggingSink::Entry::EventType::kClientHalfClose:
return "CLIENT_HALF_CLOSE";
case LoggingSink::Entry::EventType::kServerTrailer:
return "SERVER_TRAILER";
case LoggingSink::Entry::EventType::kCancel:
return "CANCEL";
case LoggingSink::Entry::EventType::kUnkown:
default:
return "EVENT_TYPE_UNKNOWN";
}
}
std::string LoggerToString(LoggingSink::Entry::Logger type) {
switch (type) {
case LoggingSink::Entry::Logger::kClient:
return "CLIENT";
case LoggingSink::Entry::Logger::kServer:
return "SERVER";
case LoggingSink::Entry::Logger::kUnkown:
default:
return "LOGGER_UNKNOWN";
}
}
void PayloadToJsonStructProto(LoggingSink::Entry::Payload payload,
::google::protobuf::Struct* payload_proto) {
grpc_core::Json::Object payload_json;
if (!payload.metadata.empty()) {
auto* metadata_proto =
(*payload_proto->mutable_fields())["metadata"].mutable_struct_value();
for (auto& metadata : payload.metadata) {
(*metadata_proto->mutable_fields())[metadata.first].set_string_value(
std::move(metadata.second));
}
}
if (payload.timeout != grpc_core::Duration::Zero()) {
(*payload_proto->mutable_fields())["timeout"].set_string_value(
payload.timeout.ToJsonString());
}
if (payload.status_code != 0) {
(*payload_proto->mutable_fields())["statusCode"].set_number_value(
payload.status_code);
}
if (!payload.status_message.empty()) {
(*payload_proto->mutable_fields())["statusMessage"].set_string_value(
std::move(payload.status_message));
}
if (!payload.status_details.empty()) {
(*payload_proto->mutable_fields())["statusDetails"].set_string_value(
std::move(payload.status_details));
}
if (payload.message_length != 0) {
(*payload_proto->mutable_fields())["messageLength"].set_number_value(
payload.message_length);
}
if (!payload.message.empty()) {
(*payload_proto->mutable_fields())["message"].set_string_value(
std::move(payload.message));
}
}
std::string AddressTypeToString(LoggingSink::Entry::Address::Type type) {
switch (type) {
case LoggingSink::Entry::Address::Type::kIpv4:
return "TYPE_IPV4";
case LoggingSink::Entry::Address::Type::kIpv6:
return "TYPE_IPV6";
case LoggingSink::Entry::Address::Type::kUnix:
return "TYPE_UNIX";
case LoggingSink::Entry::Address::Type::kUnknown:
default:
return "TYPE_UNKNOWN";
}
}
void PeerToJsonStructProto(LoggingSink::Entry::Address peer,
::google::protobuf::Struct* peer_json) {
(*peer_json->mutable_fields())["type"].set_string_value(
AddressTypeToString(peer.type));
(*peer_json->mutable_fields())["address"].set_string_value(
std::move(peer.address));
(*peer_json->mutable_fields())["ipPort"].set_number_value(peer.ip_port);
}
} // namespace
void EntryToJsonStructProto(LoggingSink::Entry entry,
::google::protobuf::Struct* json_payload) {
(*json_payload->mutable_fields())["callId"].set_string_value(
absl::StrCat(entry.call_id));
(*json_payload->mutable_fields())["sequenceId"].set_number_value(
entry.sequence_id);
(*json_payload->mutable_fields())["type"].set_string_value(
EventTypeToString(entry.type));
(*json_payload->mutable_fields())["logger"].set_string_value(
LoggerToString(entry.logger));
PayloadToJsonStructProto(
std::move(entry.payload),
(*json_payload->mutable_fields())["payload"].mutable_struct_value());
if (entry.payload_truncated) {
(*json_payload->mutable_fields())["payloadTruncated"].set_bool_value(
entry.payload_truncated);
}
PeerToJsonStructProto(
std::move(entry.peer),
(*json_payload->mutable_fields())["peer"].mutable_struct_value());
(*json_payload->mutable_fields())["authority"].set_string_value(
std::move(entry.authority));
(*json_payload->mutable_fields())["serviceName"].set_string_value(
std::move(entry.service_name));
(*json_payload->mutable_fields())["methodName"].set_string_value(
std::move(entry.method_name));
}
void ObservabilityLoggingSink::LogEntry(Entry entry) {
struct CallContext {
ClientContext context;
google::logging::v2::WriteLogEntriesRequest request;
@ -109,6 +236,18 @@ void ObservabilityLoggingSink::LogEntry(Entry /* entry */) {
// context, and actually use the entry.
CallContext* call = new CallContext;
call->context.set_authority(authority_);
call->request.set_log_name(
absl::StrFormat("projects/{%s}/logs/"
"microservices.googleapis.com%%2Fobservability%%2fgrpc",
project_id_));
auto* proto_entry = call->request.add_entries();
// Fill the current timestamp
gpr_timespec timespec =
grpc_core::Timestamp::Now().as_timespec(GPR_CLOCK_REALTIME);
proto_entry->mutable_timestamp()->set_seconds(timespec.tv_sec);
proto_entry->mutable_timestamp()->set_nanos(timespec.tv_nsec);
// TODO(yashykt): Check if we need to fill receive timestamp
EntryToJsonStructProto(std::move(entry), proto_entry->mutable_json_payload());
stub_->async()->WriteLogEntries(&(call->context), &(call->request),
&(call->response), [call](Status status) {
if (!status.ok()) {

@ -74,6 +74,10 @@ class ObservabilityLoggingSink : public LoggingSink {
std::string authority_;
};
// Exposed for just for testing purposes
void EntryToJsonStructProto(LoggingSink::Entry entry,
::google::protobuf::Struct* json_payload);
} // namespace internal
} // namespace grpc

@ -17,6 +17,7 @@
#include "src/cpp/ext/gcp/observability_logging_sink.h"
#include "gmock/gmock.h"
#include "google/protobuf/text_format.h"
#include "gtest/gtest.h"
#include "test/core/util/test_config.h"
@ -294,6 +295,754 @@ TEST(GcpObservabilityLoggingSinkTest, LoggingConfigServerMultipleEventEntries) {
EXPECT_EQ(sink.FindMatch(false, "foo/baz"), LoggingSink::Config(512, 2048));
}
TEST(EntryToJsonStructTest, ClientHeader) {
LoggingSink::Entry entry;
entry.call_id = 1234;
entry.sequence_id = 1;
entry.type = LoggingSink::Entry::EventType::kClientHeader;
entry.payload.metadata["key"] = "value";
entry.payload.timeout = grpc_core::Duration::Seconds(100);
entry.payload_truncated = true;
entry.peer.type = LoggingSink::Entry::Address::Type::kIpv4;
entry.peer.address = "127.0.0.1";
entry.peer.ip_port = 12345;
entry.authority = "authority";
entry.service_name = "service_name";
entry.method_name = "method_name";
google::protobuf::Struct proto;
EntryToJsonStructProto(std::move(entry), &proto);
std::string output;
::google::protobuf::TextFormat::PrintToString(proto, &output);
const char* pb_str =
"fields {\n"
" key: \"authority\"\n"
" value {\n"
" string_value: \"authority\"\n"
" }\n"
"}\n"
"fields {\n"
" key: \"callId\"\n"
" value {\n"
" string_value: \"1234\"\n"
" }\n"
"}\n"
"fields {\n"
" key: \"logger\"\n"
" value {\n"
" string_value: \"LOGGER_UNKNOWN\"\n"
" }\n"
"}\n"
"fields {\n"
" key: \"methodName\"\n"
" value {\n"
" string_value: \"method_name\"\n"
" }\n"
"}\n"
"fields {\n"
" key: \"payload\"\n"
" value {\n"
" struct_value {\n"
" fields {\n"
" key: \"metadata\"\n"
" value {\n"
" struct_value {\n"
" fields {\n"
" key: \"key\"\n"
" value {\n"
" string_value: \"value\"\n"
" }\n"
" }\n"
" }\n"
" }\n"
" }\n"
" fields {\n"
" key: \"timeout\"\n"
" value {\n"
" string_value: \"100.000000000s\"\n"
" }\n"
" }\n"
" }\n"
" }\n"
"}\n"
"fields {\n"
" key: \"payloadTruncated\"\n"
" value {\n"
" bool_value: true\n"
" }\n"
"}\n"
"fields {\n"
" key: \"peer\"\n"
" value {\n"
" struct_value {\n"
" fields {\n"
" key: \"address\"\n"
" value {\n"
" string_value: \"127.0.0.1\"\n"
" }\n"
" }\n"
" fields {\n"
" key: \"ipPort\"\n"
" value {\n"
" number_value: 12345\n"
" }\n"
" }\n"
" fields {\n"
" key: \"type\"\n"
" value {\n"
" string_value: \"TYPE_IPV4\"\n"
" }\n"
" }\n"
" }\n"
" }\n"
"}\n"
"fields {\n"
" key: \"sequenceId\"\n"
" value {\n"
" number_value: 1\n"
" }\n"
"}\n"
"fields {\n"
" key: \"serviceName\"\n"
" value {\n"
" string_value: \"service_name\"\n"
" }\n"
"}\n"
"fields {\n"
" key: \"type\"\n"
" value {\n"
" string_value: \"CLIENT_HEADER\"\n"
" }\n"
"}\n";
EXPECT_EQ(output, pb_str);
}
TEST(EntryToJsonStructTest, ServerHeader) {
LoggingSink::Entry entry;
entry.call_id = 1234;
entry.sequence_id = 2;
entry.type = LoggingSink::Entry::EventType::kServerHeader;
entry.logger = LoggingSink::Entry::Logger::kServer;
entry.payload.metadata["key"] = "value";
entry.peer.type = LoggingSink::Entry::Address::Type::kIpv4;
entry.peer.address = "127.0.0.1";
entry.peer.ip_port = 1234;
entry.authority = "authority";
entry.service_name = "service_name";
entry.method_name = "method_name";
google::protobuf::Struct proto;
EntryToJsonStructProto(std::move(entry), &proto);
std::string output;
::google::protobuf::TextFormat::PrintToString(proto, &output);
const char* pb_str =
"fields {\n"
" key: \"authority\"\n"
" value {\n"
" string_value: \"authority\"\n"
" }\n"
"}\n"
"fields {\n"
" key: \"callId\"\n"
" value {\n"
" string_value: \"1234\"\n"
" }\n"
"}\n"
"fields {\n"
" key: \"logger\"\n"
" value {\n"
" string_value: \"SERVER\"\n"
" }\n"
"}\n"
"fields {\n"
" key: \"methodName\"\n"
" value {\n"
" string_value: \"method_name\"\n"
" }\n"
"}\n"
"fields {\n"
" key: \"payload\"\n"
" value {\n"
" struct_value {\n"
" fields {\n"
" key: \"metadata\"\n"
" value {\n"
" struct_value {\n"
" fields {\n"
" key: \"key\"\n"
" value {\n"
" string_value: \"value\"\n"
" }\n"
" }\n"
" }\n"
" }\n"
" }\n"
" }\n"
" }\n"
"}\n"
"fields {\n"
" key: \"peer\"\n"
" value {\n"
" struct_value {\n"
" fields {\n"
" key: \"address\"\n"
" value {\n"
" string_value: \"127.0.0.1\"\n"
" }\n"
" }\n"
" fields {\n"
" key: \"ipPort\"\n"
" value {\n"
" number_value: 1234\n"
" }\n"
" }\n"
" fields {\n"
" key: \"type\"\n"
" value {\n"
" string_value: \"TYPE_IPV4\"\n"
" }\n"
" }\n"
" }\n"
" }\n"
"}\n"
"fields {\n"
" key: \"sequenceId\"\n"
" value {\n"
" number_value: 2\n"
" }\n"
"}\n"
"fields {\n"
" key: \"serviceName\"\n"
" value {\n"
" string_value: \"service_name\"\n"
" }\n"
"}\n"
"fields {\n"
" key: \"type\"\n"
" value {\n"
" string_value: \"SERVER_HEADER\"\n"
" }\n"
"}\n";
EXPECT_EQ(output, pb_str);
}
TEST(EntryToJsonStructTest, ClientMessage) {
LoggingSink::Entry entry;
entry.call_id = 1234;
entry.sequence_id = 3;
entry.type = LoggingSink::Entry::EventType::kClientMessage;
entry.logger = LoggingSink::Entry::Logger::kClient;
entry.payload.message = "hello";
entry.payload.message_length = 5;
entry.peer.type = LoggingSink::Entry::Address::Type::kIpv4;
entry.peer.address = "127.0.0.1";
entry.peer.ip_port = 1234;
entry.authority = "authority";
entry.service_name = "service_name";
entry.method_name = "method_name";
google::protobuf::Struct proto;
EntryToJsonStructProto(std::move(entry), &proto);
std::string output;
::google::protobuf::TextFormat::PrintToString(proto, &output);
const char* pb_str =
"fields {\n"
" key: \"authority\"\n"
" value {\n"
" string_value: \"authority\"\n"
" }\n"
"}\n"
"fields {\n"
" key: \"callId\"\n"
" value {\n"
" string_value: \"1234\"\n"
" }\n"
"}\n"
"fields {\n"
" key: \"logger\"\n"
" value {\n"
" string_value: \"CLIENT\"\n"
" }\n"
"}\n"
"fields {\n"
" key: \"methodName\"\n"
" value {\n"
" string_value: \"method_name\"\n"
" }\n"
"}\n"
"fields {\n"
" key: \"payload\"\n"
" value {\n"
" struct_value {\n"
" fields {\n"
" key: \"message\"\n"
" value {\n"
" string_value: \"hello\"\n"
" }\n"
" }\n"
" fields {\n"
" key: \"messageLength\"\n"
" value {\n"
" number_value: 5\n"
" }\n"
" }\n"
" }\n"
" }\n"
"}\n"
"fields {\n"
" key: \"peer\"\n"
" value {\n"
" struct_value {\n"
" fields {\n"
" key: \"address\"\n"
" value {\n"
" string_value: \"127.0.0.1\"\n"
" }\n"
" }\n"
" fields {\n"
" key: \"ipPort\"\n"
" value {\n"
" number_value: 1234\n"
" }\n"
" }\n"
" fields {\n"
" key: \"type\"\n"
" value {\n"
" string_value: \"TYPE_IPV4\"\n"
" }\n"
" }\n"
" }\n"
" }\n"
"}\n"
"fields {\n"
" key: \"sequenceId\"\n"
" value {\n"
" number_value: 3\n"
" }\n"
"}\n"
"fields {\n"
" key: \"serviceName\"\n"
" value {\n"
" string_value: \"service_name\"\n"
" }\n"
"}\n"
"fields {\n"
" key: \"type\"\n"
" value {\n"
" string_value: \"CLIENT_MESSAGE\"\n"
" }\n"
"}\n";
EXPECT_EQ(output, pb_str);
}
TEST(EntryToJsonStructTest, ServerMessage) {
LoggingSink::Entry entry;
entry.call_id = 1234;
entry.sequence_id = 4;
entry.type = LoggingSink::Entry::EventType::kServerMessage;
entry.logger = LoggingSink::Entry::Logger::kServer;
entry.payload.message = "world";
entry.payload.message_length = 5;
entry.peer.type = LoggingSink::Entry::Address::Type::kIpv4;
entry.peer.address = "127.0.0.1";
entry.peer.ip_port = 12345;
entry.authority = "authority";
entry.service_name = "service_name";
entry.method_name = "method_name";
google::protobuf::Struct proto;
EntryToJsonStructProto(std::move(entry), &proto);
std::string output;
::google::protobuf::TextFormat::PrintToString(proto, &output);
const char* pb_str =
"fields {\n"
" key: \"authority\"\n"
" value {\n"
" string_value: \"authority\"\n"
" }\n"
"}\n"
"fields {\n"
" key: \"callId\"\n"
" value {\n"
" string_value: \"1234\"\n"
" }\n"
"}\n"
"fields {\n"
" key: \"logger\"\n"
" value {\n"
" string_value: \"SERVER\"\n"
" }\n"
"}\n"
"fields {\n"
" key: \"methodName\"\n"
" value {\n"
" string_value: \"method_name\"\n"
" }\n"
"}\n"
"fields {\n"
" key: \"payload\"\n"
" value {\n"
" struct_value {\n"
" fields {\n"
" key: \"message\"\n"
" value {\n"
" string_value: \"world\"\n"
" }\n"
" }\n"
" fields {\n"
" key: \"messageLength\"\n"
" value {\n"
" number_value: 5\n"
" }\n"
" }\n"
" }\n"
" }\n"
"}\n"
"fields {\n"
" key: \"peer\"\n"
" value {\n"
" struct_value {\n"
" fields {\n"
" key: \"address\"\n"
" value {\n"
" string_value: \"127.0.0.1\"\n"
" }\n"
" }\n"
" fields {\n"
" key: \"ipPort\"\n"
" value {\n"
" number_value: 12345\n"
" }\n"
" }\n"
" fields {\n"
" key: \"type\"\n"
" value {\n"
" string_value: \"TYPE_IPV4\"\n"
" }\n"
" }\n"
" }\n"
" }\n"
"}\n"
"fields {\n"
" key: \"sequenceId\"\n"
" value {\n"
" number_value: 4\n"
" }\n"
"}\n"
"fields {\n"
" key: \"serviceName\"\n"
" value {\n"
" string_value: \"service_name\"\n"
" }\n"
"}\n"
"fields {\n"
" key: \"type\"\n"
" value {\n"
" string_value: \"SERVER_MESSAGE\"\n"
" }\n"
"}\n";
EXPECT_EQ(output, pb_str);
}
TEST(EntryToJsonStructTest, ClientHalfClose) {
LoggingSink::Entry entry;
entry.call_id = 1234;
entry.sequence_id = 5;
entry.type = LoggingSink::Entry::EventType::kClientHalfClose;
entry.logger = LoggingSink::Entry::Logger::kClient;
entry.peer.type = LoggingSink::Entry::Address::Type::kIpv4;
entry.peer.address = "127.0.0.1";
entry.peer.ip_port = 1234;
entry.authority = "authority";
entry.service_name = "service_name";
entry.method_name = "method_name";
google::protobuf::Struct proto;
EntryToJsonStructProto(std::move(entry), &proto);
std::string output;
::google::protobuf::TextFormat::PrintToString(proto, &output);
const char* pb_str =
"fields {\n"
" key: \"authority\"\n"
" value {\n"
" string_value: \"authority\"\n"
" }\n"
"}\n"
"fields {\n"
" key: \"callId\"\n"
" value {\n"
" string_value: \"1234\"\n"
" }\n"
"}\n"
"fields {\n"
" key: \"logger\"\n"
" value {\n"
" string_value: \"CLIENT\"\n"
" }\n"
"}\n"
"fields {\n"
" key: \"methodName\"\n"
" value {\n"
" string_value: \"method_name\"\n"
" }\n"
"}\n"
"fields {\n"
" key: \"payload\"\n"
" value {\n"
" struct_value {\n"
" }\n"
" }\n"
"}\n"
"fields {\n"
" key: \"peer\"\n"
" value {\n"
" struct_value {\n"
" fields {\n"
" key: \"address\"\n"
" value {\n"
" string_value: \"127.0.0.1\"\n"
" }\n"
" }\n"
" fields {\n"
" key: \"ipPort\"\n"
" value {\n"
" number_value: 1234\n"
" }\n"
" }\n"
" fields {\n"
" key: \"type\"\n"
" value {\n"
" string_value: \"TYPE_IPV4\"\n"
" }\n"
" }\n"
" }\n"
" }\n"
"}\n"
"fields {\n"
" key: \"sequenceId\"\n"
" value {\n"
" number_value: 5\n"
" }\n"
"}\n"
"fields {\n"
" key: \"serviceName\"\n"
" value {\n"
" string_value: \"service_name\"\n"
" }\n"
"}\n"
"fields {\n"
" key: \"type\"\n"
" value {\n"
" string_value: \"CLIENT_HALF_CLOSE\"\n"
" }\n"
"}\n";
EXPECT_EQ(output, pb_str);
}
TEST(EntryToJsonStructTest, ServerTrailer) {
LoggingSink::Entry entry;
entry.call_id = 1234;
entry.sequence_id = 6;
entry.type = LoggingSink::Entry::EventType::kServerTrailer;
entry.logger = LoggingSink::Entry::Logger::kServer;
entry.payload.metadata["key"] = "value";
entry.peer.type = LoggingSink::Entry::Address::Type::kIpv4;
entry.peer.address = "127.0.0.1";
entry.peer.ip_port = 1234;
entry.authority = "authority";
entry.service_name = "service_name";
entry.method_name = "method_name";
google::protobuf::Struct proto;
EntryToJsonStructProto(std::move(entry), &proto);
std::string output;
::google::protobuf::TextFormat::PrintToString(proto, &output);
const char* pb_str =
"fields {\n"
" key: \"authority\"\n"
" value {\n"
" string_value: \"authority\"\n"
" }\n"
"}\n"
"fields {\n"
" key: \"callId\"\n"
" value {\n"
" string_value: \"1234\"\n"
" }\n"
"}\n"
"fields {\n"
" key: \"logger\"\n"
" value {\n"
" string_value: \"SERVER\"\n"
" }\n"
"}\n"
"fields {\n"
" key: \"methodName\"\n"
" value {\n"
" string_value: \"method_name\"\n"
" }\n"
"}\n"
"fields {\n"
" key: \"payload\"\n"
" value {\n"
" struct_value {\n"
" fields {\n"
" key: \"metadata\"\n"
" value {\n"
" struct_value {\n"
" fields {\n"
" key: \"key\"\n"
" value {\n"
" string_value: \"value\"\n"
" }\n"
" }\n"
" }\n"
" }\n"
" }\n"
" }\n"
" }\n"
"}\n"
"fields {\n"
" key: \"peer\"\n"
" value {\n"
" struct_value {\n"
" fields {\n"
" key: \"address\"\n"
" value {\n"
" string_value: \"127.0.0.1\"\n"
" }\n"
" }\n"
" fields {\n"
" key: \"ipPort\"\n"
" value {\n"
" number_value: 1234\n"
" }\n"
" }\n"
" fields {\n"
" key: \"type\"\n"
" value {\n"
" string_value: \"TYPE_IPV4\"\n"
" }\n"
" }\n"
" }\n"
" }\n"
"}\n"
"fields {\n"
" key: \"sequenceId\"\n"
" value {\n"
" number_value: 6\n"
" }\n"
"}\n"
"fields {\n"
" key: \"serviceName\"\n"
" value {\n"
" string_value: \"service_name\"\n"
" }\n"
"}\n"
"fields {\n"
" key: \"type\"\n"
" value {\n"
" string_value: \"SERVER_TRAILER\"\n"
" }\n"
"}\n";
EXPECT_EQ(output, pb_str);
}
TEST(EntryToJsonStructTest, Cancel) {
LoggingSink::Entry entry;
entry.call_id = 1234;
entry.sequence_id = 7;
entry.type = LoggingSink::Entry::EventType::kCancel;
entry.logger = LoggingSink::Entry::Logger::kClient;
entry.peer.type = LoggingSink::Entry::Address::Type::kIpv4;
entry.peer.address = "127.0.0.1";
entry.peer.ip_port = 1234;
entry.authority = "authority";
entry.service_name = "service_name";
entry.method_name = "method_name";
google::protobuf::Struct proto;
EntryToJsonStructProto(std::move(entry), &proto);
std::string output;
::google::protobuf::TextFormat::PrintToString(proto, &output);
const char* pb_str =
"fields {\n"
" key: \"authority\"\n"
" value {\n"
" string_value: \"authority\"\n"
" }\n"
"}\n"
"fields {\n"
" key: \"callId\"\n"
" value {\n"
" string_value: \"1234\"\n"
" }\n"
"}\n"
"fields {\n"
" key: \"logger\"\n"
" value {\n"
" string_value: \"CLIENT\"\n"
" }\n"
"}\n"
"fields {\n"
" key: \"methodName\"\n"
" value {\n"
" string_value: \"method_name\"\n"
" }\n"
"}\n"
"fields {\n"
" key: \"payload\"\n"
" value {\n"
" struct_value {\n"
" }\n"
" }\n"
"}\n"
"fields {\n"
" key: \"peer\"\n"
" value {\n"
" struct_value {\n"
" fields {\n"
" key: \"address\"\n"
" value {\n"
" string_value: \"127.0.0.1\"\n"
" }\n"
" }\n"
" fields {\n"
" key: \"ipPort\"\n"
" value {\n"
" number_value: 1234\n"
" }\n"
" }\n"
" fields {\n"
" key: \"type\"\n"
" value {\n"
" string_value: \"TYPE_IPV4\"\n"
" }\n"
" }\n"
" }\n"
" }\n"
"}\n"
"fields {\n"
" key: \"sequenceId\"\n"
" value {\n"
" number_value: 7\n"
" }\n"
"}\n"
"fields {\n"
" key: \"serviceName\"\n"
" value {\n"
" string_value: \"service_name\"\n"
" }\n"
"}\n"
"fields {\n"
" key: \"type\"\n"
" value {\n"
" string_value: \"CANCEL\"\n"
" }\n"
"}\n";
EXPECT_EQ(output, pb_str);
}
} // namespace
} // namespace internal

Loading…
Cancel
Save