diff --git a/packages/grpc-js/src/server-call.ts b/packages/grpc-js/src/server-call.ts index fc456fda..d5e5f822 100644 --- a/packages/grpc-js/src/server-call.ts +++ b/packages/grpc-js/src/server-call.ts @@ -20,12 +20,24 @@ import * as http2 from 'http2'; import { Duplex, Readable, Writable } from 'stream'; import { StatusObject } from './call-stream'; -import { Status, DEFAULT_MAX_SEND_MESSAGE_LENGTH, DEFAULT_MAX_RECEIVE_MESSAGE_LENGTH } from './constants'; +import { + Status, + DEFAULT_MAX_SEND_MESSAGE_LENGTH, + DEFAULT_MAX_RECEIVE_MESSAGE_LENGTH, + LogVerbosity, +} from './constants'; import { Deserialize, Serialize } from './make-client'; import { Metadata } from './metadata'; import { StreamDecoder } from './stream-decoder'; import { ObjectReadable, ObjectWritable } from './object-stream'; import { ChannelOptions } from './channel-options'; +import * as logging from './logging'; + +const TRACER_NAME = 'server_call'; + +function trace(text: string): void { + logging.trace(LogVerbosity.DEBUG, TRACER_NAME, text); +} interface DeadlineUnitIndexSignature { [name: string]: number; @@ -63,7 +75,7 @@ export type ServerErrorResponse = ServerStatusResponse & Error; export type ServerSurfaceCall = { cancelled: boolean; - readonly metadata: Metadata + readonly metadata: Metadata; getPeer(): string; sendMetadata(responseMetadata: Metadata): void; } & EventEmitter; @@ -294,6 +306,7 @@ export interface UnaryHandler { serialize: Serialize; deserialize: Deserialize; type: HandlerType; + path: string; } export interface ClientStreamingHandler { @@ -301,6 +314,7 @@ export interface ClientStreamingHandler { serialize: Serialize; deserialize: Deserialize; type: HandlerType; + path: string; } export interface ServerStreamingHandler { @@ -308,6 +322,7 @@ export interface ServerStreamingHandler { serialize: Serialize; deserialize: Deserialize; type: HandlerType; + path: string; } export interface BidiStreamingHandler { @@ -315,6 +330,7 @@ export interface BidiStreamingHandler { serialize: Serialize; deserialize: Deserialize; type: HandlerType; + path: string; } export type Handler = @@ -447,10 +463,13 @@ export class Http2ServerCallStream< stream.once('end', async () => { try { const requestBytes = Buffer.concat(chunks, totalLength); - if (this.maxReceiveMessageSize !== -1 && requestBytes.length > this.maxReceiveMessageSize) { + if ( + this.maxReceiveMessageSize !== -1 && + requestBytes.length > this.maxReceiveMessageSize + ) { this.sendError({ code: Status.RESOURCE_EXHAUSTED, - details: `Received message larger than max (${requestBytes.length} vs. ${this.maxReceiveMessageSize})` + details: `Received message larger than max (${requestBytes.length} vs. ${this.maxReceiveMessageSize})`, }); resolve(); } @@ -521,6 +540,15 @@ export class Http2ServerCallStream< return; } + trace( + 'Request to method ' + + this.handler?.path + + ' ended with status code: ' + + Status[statusObj.code] + + ' details: ' + + statusObj.details + ); + clearTimeout(this.deadline); if (!this.wantTrailers) { @@ -574,10 +602,13 @@ export class Http2ServerCallStream< return; } - if (this.maxSendMessageSize !== -1 && chunk.length > this.maxSendMessageSize) { + if ( + this.maxSendMessageSize !== -1 && + chunk.length > this.maxSendMessageSize + ) { this.sendError({ - code: Status.RESOURCE_EXHAUSTED, - details: `Sent message larger than max (${chunk.length} vs. ${this.maxSendMessageSize})` + code: Status.RESOURCE_EXHAUSTED, + details: `Sent message larger than max (${chunk.length} vs. ${this.maxSendMessageSize})`, }); return; } @@ -608,10 +639,13 @@ export class Http2ServerCallStream< const messages = decoder.write(data); for (const message of messages) { - if (this.maxReceiveMessageSize !== -1 && message.length > this.maxReceiveMessageSize) { + if ( + this.maxReceiveMessageSize !== -1 && + message.length > this.maxReceiveMessageSize + ) { this.sendError({ code: Status.RESOURCE_EXHAUSTED, - details: `Received message larger than max (${message.length} vs. ${this.maxReceiveMessageSize})` + details: `Received message larger than max (${message.length} vs. ${this.maxReceiveMessageSize})`, }); return; } diff --git a/packages/grpc-js/src/server.ts b/packages/grpc-js/src/server.ts index c8b8f2b2..a6edee3b 100644 --- a/packages/grpc-js/src/server.ts +++ b/packages/grpc-js/src/server.ts @@ -45,15 +45,26 @@ import { } from './server-call'; import { ServerCredentials } from './server-credentials'; import { ChannelOptions } from './channel-options'; -import { createResolver, ResolverListener, mapUriDefaultScheme } from './resolver'; -import { log } from './logging'; +import { + createResolver, + ResolverListener, + mapUriDefaultScheme, +} from './resolver'; +import * as logging from './logging'; import { SubchannelAddress, TcpSubchannelAddress, isTcpSubchannelAddress, + subchannelAddressToString, } from './subchannel'; import { parseUri } from './uri-parser'; +const TRACER_NAME = 'server'; + +function trace(text: string): void { + logging.trace(LogVerbosity.DEBUG, TRACER_NAME, text); +} + interface BindResult { port: number; count: number; @@ -269,6 +280,7 @@ export class Server { } return Promise.all( addressList.map((address) => { + trace('Attempting to bind ' + subchannelAddressToString(address)); let addr: SubchannelAddress; if (isTcpSubchannelAddress(address)) { addr = { @@ -288,6 +300,7 @@ export class Server { http2Server.once('error', onError); http2Server.listen(addr, () => { + trace('Successfully bound ' + subchannelAddressToString(address)); this.http2ServerList.push(http2Server); const boundAddress = http2Server.address()!; if (typeof boundAddress === 'string') { @@ -378,11 +391,11 @@ export class Server { (bindResult) => { if (bindResult.count === 0) { const errorString = `No address added out of total ${addressList.length} resolved`; - log(LogVerbosity.ERROR, errorString); + logging.log(LogVerbosity.ERROR, errorString); callback(new Error(errorString), 0); } else { if (bindResult.count < addressList.length) { - log( + logging.log( LogVerbosity.INFO, `WARNING Only ${bindResult.count} addresses added out of total ${addressList.length} resolved` ); @@ -392,7 +405,7 @@ export class Server { }, (error) => { const errorString = `No address added out of total ${addressList.length} resolved`; - log(LogVerbosity.ERROR, errorString); + logging.log(LogVerbosity.ERROR, errorString); callback(new Error(errorString), 0); } ); @@ -444,6 +457,7 @@ export class Server { serialize, deserialize, type, + path: name, } as UntypedHandler); return true; } @@ -528,9 +542,20 @@ export class Server { try { const path = headers[http2.constants.HTTP2_HEADER_PATH] as string; + trace( + 'Received call to method ' + + path + + ' at address ' + + http2Server.address()?.toString() + ); const handler = this.handlers.get(path); if (handler === undefined) { + trace( + 'No handler registered for method ' + + path + + '. Sending UNIMPLEMENTED status.' + ); throw getUnimplementedStatusResponse(path); }