services: binlog status code, msg, details (#4551)

Log these additional bits of info in RPC binary logging
This commit is contained in:
zpencer 2018-07-17 11:29:45 -07:00 committed by GitHub
parent 146b6006b3
commit f013771bd1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 74 additions and 7 deletions

View File

@ -83,6 +83,14 @@ final class BinlogHelper {
private static final Logger logger = Logger.getLogger(BinlogHelper.class.getName()); private static final Logger logger = Logger.getLogger(BinlogHelper.class.getName());
private static final boolean SERVER = true; private static final boolean SERVER = true;
private static final boolean CLIENT = false; private static final boolean CLIENT = false;
// Normally 'grpc-' metadata keys are set from within gRPC, and applications are not allowed
// to set them. This key is a special well known key that set from the application layer, but
// represents a com.google.rpc.Status and is given special first class treatment.
// See StatusProto.java
static final Metadata.Key<byte[]> STATUS_DETAILS_KEY =
Metadata.Key.of(
"grpc-status-details-bin",
Metadata.BINARY_BYTE_MARSHALLER);
@VisibleForTesting @VisibleForTesting
static final SocketAddress DUMMY_SOCKET = new DummySocketAddress(); static final SocketAddress DUMMY_SOCKET = new DummySocketAddress();
@ -168,12 +176,23 @@ final class BinlogHelper {
} }
@Override @Override
void logTrailingMetadata(int seq, Metadata metadata, boolean isServer, CallId callId) { void logTrailingMetadata(
int seq, Status status, Metadata metadata, boolean isServer, CallId callId) {
GrpcLogEntry.Builder entryBuilder = GrpcLogEntry.newBuilder() GrpcLogEntry.Builder entryBuilder = GrpcLogEntry.newBuilder()
.setSequenceIdWithinCall(seq) .setSequenceIdWithinCall(seq)
.setType(isServer ? Type.SEND_TRAILING_METADATA : Type.RECV_TRAILING_METADATA) .setType(isServer ? Type.SEND_TRAILING_METADATA : Type.RECV_TRAILING_METADATA)
.setLogger(isServer ? GrpcLogEntry.Logger.SERVER : GrpcLogEntry.Logger.CLIENT) .setLogger(isServer ? GrpcLogEntry.Logger.SERVER : GrpcLogEntry.Logger.CLIENT)
.setCallId(callIdToProto(callId)); .setCallId(callIdToProto(callId))
.setStatusCode(status.getCode().value());
String statusDescription = status.getDescription();
if (statusDescription != null) {
entryBuilder.setStatusMessage(statusDescription);
}
byte[] statusDetailBytes = metadata.get(STATUS_DETAILS_KEY);
if (statusDetailBytes != null) {
entryBuilder.setStatusDetails(ByteString.copyFrom(statusDetailBytes));
}
addMetadataToProto(entryBuilder, metadata, maxHeaderBytes); addMetadataToProto(entryBuilder, metadata, maxHeaderBytes);
sink.write(entryBuilder.build()); sink.write(entryBuilder.build());
} }
@ -260,7 +279,8 @@ final class BinlogHelper {
* Logs the trailing metadata. This method logs the appropriate number of bytes * Logs the trailing metadata. This method logs the appropriate number of bytes
* as determined by the binary logging configuration. * as determined by the binary logging configuration.
*/ */
abstract void logTrailingMetadata(int seq, Metadata metadata, boolean isServer, CallId callId); abstract void logTrailingMetadata(
int seq, Status status, Metadata metadata, boolean isServer, CallId callId);
/** /**
* Logs the outbound message. This method logs the appropriate number of bytes from * Logs the outbound message. This method logs the appropriate number of bytes from
@ -359,7 +379,8 @@ final class BinlogHelper {
@Override @Override
public void onClose(Status status, Metadata trailers) { public void onClose(Status status, Metadata trailers) {
writer.logTrailingMetadata(seq.getAndIncrement(), trailers, CLIENT, callId); writer.logTrailingMetadata(
seq.getAndIncrement(), status, trailers, CLIENT, callId);
super.onClose(status, trailers); super.onClose(status, trailers);
} }
}; };
@ -425,7 +446,7 @@ final class BinlogHelper {
@Override @Override
public void close(Status status, Metadata trailers) { public void close(Status status, Metadata trailers) {
writer.logTrailingMetadata(seq.getAndIncrement(), trailers, SERVER, callId); writer.logTrailingMetadata(seq.getAndIncrement(), status, trailers, SERVER, callId);
super.close(status, trailers); super.close(status, trailers);
} }
}; };

View File

@ -19,6 +19,7 @@ package io.grpc.services;
import static com.google.common.truth.Truth.assertThat; import static com.google.common.truth.Truth.assertThat;
import static io.grpc.services.BinaryLogProvider.BYTEARRAY_MARSHALLER; import static io.grpc.services.BinaryLogProvider.BYTEARRAY_MARSHALLER;
import static io.grpc.services.BinlogHelper.DUMMY_SOCKET; import static io.grpc.services.BinlogHelper.DUMMY_SOCKET;
import static io.grpc.services.BinlogHelper.STATUS_DETAILS_KEY;
import static io.grpc.services.BinlogHelper.getPeerSocket; import static io.grpc.services.BinlogHelper.getPeerSocket;
import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNotNull;
@ -667,7 +668,7 @@ public final class BinlogHelperTest {
@Test @Test
public void logTrailingMetadata_server() throws Exception { public void logTrailingMetadata_server() throws Exception {
sinkWriterImpl.logTrailingMetadata(/*seq=*/ 1, nonEmptyMetadata, IS_SERVER, CALL_ID); sinkWriterImpl.logTrailingMetadata(/*seq=*/ 1, Status.OK, nonEmptyMetadata, IS_SERVER, CALL_ID);
verify(sink).write( verify(sink).write(
metadataToProtoTestHelper(nonEmptyMetadata, 10).toBuilder() metadataToProtoTestHelper(nonEmptyMetadata, 10).toBuilder()
.setSequenceIdWithinCall(1) .setSequenceIdWithinCall(1)
@ -675,11 +676,32 @@ public final class BinlogHelperTest {
.setLogger(GrpcLogEntry.Logger.SERVER) .setLogger(GrpcLogEntry.Logger.SERVER)
.setCallId(BinlogHelper.callIdToProto(CALL_ID)) .setCallId(BinlogHelper.callIdToProto(CALL_ID))
.build()); .build());
Metadata detailedStatus = new Metadata();
byte[] statusBytes = new byte[] {1, 2, 3, 4};
detailedStatus.merge(nonEmptyMetadata);
detailedStatus.put(STATUS_DETAILS_KEY, statusBytes);
sinkWriterImpl.logTrailingMetadata(
/*seq=*/ 1,
Status.INTERNAL.withDescription("description"),
detailedStatus,
IS_SERVER,
CALL_ID);
verify(sink).write(
metadataToProtoTestHelper(detailedStatus, 10).toBuilder()
.setSequenceIdWithinCall(1)
.setType(GrpcLogEntry.Type.SEND_TRAILING_METADATA)
.setLogger(GrpcLogEntry.Logger.SERVER)
.setCallId(BinlogHelper.callIdToProto(CALL_ID))
.setStatusCode(13)
.setStatusMessage("description")
.setStatusDetails(ByteString.copyFrom(statusBytes))
.build());
} }
@Test @Test
public void logTrailingMetadata_client() throws Exception { public void logTrailingMetadata_client() throws Exception {
sinkWriterImpl.logTrailingMetadata(/*seq=*/ 1, nonEmptyMetadata, IS_CLIENT, CALL_ID); sinkWriterImpl.logTrailingMetadata(/*seq=*/ 1, Status.OK, nonEmptyMetadata, IS_CLIENT, CALL_ID);
verify(sink).write( verify(sink).write(
metadataToProtoTestHelper(nonEmptyMetadata, 10).toBuilder() metadataToProtoTestHelper(nonEmptyMetadata, 10).toBuilder()
.setSequenceIdWithinCall(1) .setSequenceIdWithinCall(1)
@ -687,6 +709,28 @@ public final class BinlogHelperTest {
.setLogger(GrpcLogEntry.Logger.CLIENT) .setLogger(GrpcLogEntry.Logger.CLIENT)
.setCallId(BinlogHelper.callIdToProto(CALL_ID)) .setCallId(BinlogHelper.callIdToProto(CALL_ID))
.build()); .build());
Metadata detailedStatus = new Metadata();
byte[] statusBytes = new byte[] {1, 2, 3, 4};
detailedStatus.merge(nonEmptyMetadata);
detailedStatus.put(STATUS_DETAILS_KEY, statusBytes);
sinkWriterImpl.logTrailingMetadata(
/*seq=*/ 1,
Status.INTERNAL.withDescription("description"),
detailedStatus,
IS_CLIENT,
CALL_ID);
verify(sink).write(
metadataToProtoTestHelper(detailedStatus, 10).toBuilder()
.setSequenceIdWithinCall(1)
.setType(GrpcLogEntry.Type.RECV_TRAILING_METADATA)
.setLogger(GrpcLogEntry.Logger.CLIENT)
.setCallId(BinlogHelper.callIdToProto(CALL_ID))
.setStatusCode(13)
.setStatusMessage("description")
.setStatusDetails(ByteString.copyFrom(statusBytes))
.build());
} }
@Test @Test
@ -1022,6 +1066,7 @@ public final class BinlogHelperTest {
interceptedListener.get().onClose(status, trailers); interceptedListener.get().onClose(status, trailers);
verify(mockSinkWriter).logTrailingMetadata( verify(mockSinkWriter).logTrailingMetadata(
/*seq=*/ eq(5), /*seq=*/ eq(5),
same(status),
same(trailers), same(trailers),
eq(IS_CLIENT), eq(IS_CLIENT),
same(CALL_ID)); same(CALL_ID));
@ -1161,6 +1206,7 @@ public final class BinlogHelperTest {
interceptedCall.get().close(status, trailers); interceptedCall.get().close(status, trailers);
verify(mockSinkWriter).logTrailingMetadata( verify(mockSinkWriter).logTrailingMetadata(
/*seq=*/ eq(5), /*seq=*/ eq(5),
same(status),
same(trailers), same(trailers),
eq(IS_SERVER), eq(IS_SERVER),
same(CALL_ID)); same(CALL_ID));