@@ -26,6 +26,7 @@ import parse from 'co-body';
2626import dotenv from 'dotenv' ;
2727import path from 'path' ;
2828import { Logger } from 'pino' ;
29+ import { formatRequestIdMessage } from '../formatters' ;
2930
3031import {
3132 ParseError ,
@@ -42,6 +43,13 @@ import { JsonRpcError } from '@hashgraph/json-rpc-relay';
4243const hasOwnProperty = ( obj , prop ) => Object . prototype . hasOwnProperty . call ( obj , prop ) ;
4344dotenv . config ( { path : path . resolve ( __dirname , '../../../../../.env' ) } ) ;
4445
46+ const INTERNAL_ERROR = "INTERNAL ERROR" ;
47+ const INVALID_PARAMS_ERROR = "INVALID PARAMS ERROR" ;
48+ const INVALID_REQUEST = "INVALID REQUEST" ;
49+ const IP_RATE_LIMIT_EXCEEDED = "IP RATE LIMIT EXCEEDED" ;
50+ const JSON_RPC_ERROR = "JSON RPC ERROR"
51+ const METHOD_NOT_FOUND = "METHOD NOT FOUND" ;
52+
4553export default class KoaJsonRpc {
4654 private registry : any ;
4755 private registryTotal : any ;
@@ -52,6 +60,8 @@ export default class KoaJsonRpc {
5260 private rateLimit : RateLimit ;
5361 private koaApp : Koa < Koa . DefaultState , Koa . DefaultContext > ;
5462 private requestId : string ;
63+ private logger : Logger ;
64+ private startTimestamp ! : number ;
5565
5666 constructor ( logger : Logger , register : Registry , opts ?) {
5767 this . koaApp = new Koa ( ) ;
@@ -64,6 +74,7 @@ export default class KoaJsonRpc {
6474 if ( opts ) {
6575 this . limit = opts . limit || this . limit ;
6676 }
77+ this . logger = logger ;
6778 this . rateLimit = new RateLimit ( logger . child ( { name : 'ip-rate-limit' } ) , register , this . duration ) ;
6879 }
6980
@@ -78,8 +89,12 @@ export default class KoaJsonRpc {
7889
7990 rpcApp ( ) {
8091 return async ( ctx , next ) => {
81- let body , result ;
92+ this . startTimestamp = ctx . state . start ;
93+ let body , ms , result ;
8294
95+ this . requestId = ctx . state . reqId ;
96+ const requestIdPrefix = formatRequestIdMessage ( this . requestId ) ;
97+
8398 if ( this . token ) {
8499 const headerToken = ctx . get ( 'authorization' ) . split ( ' ' ) . pop ( ) ;
85100 if ( headerToken !== this . token ) {
@@ -96,6 +111,9 @@ export default class KoaJsonRpc {
96111 return ;
97112 }
98113
114+ const methodName = body . method ;
115+ const messagePrefix = `${ requestIdPrefix } [POST] ${ methodName } :` ;
116+
99117 if (
100118 body . jsonrpc !== '2.0' ||
101119 ! hasOwnProperty ( body , 'method' ) ||
@@ -104,21 +122,26 @@ export default class KoaJsonRpc {
104122 ) {
105123 ctx . body = jsonResp ( body . id || null , new InvalidRequest ( ) , undefined ) ;
106124 ctx . status = 400 ;
125+ ms = Date . now ( ) - this . startTimestamp ;
126+ this . logger . error ( `${ messagePrefix } ${ ctx . status } (${ INVALID_REQUEST } ) ${ ms } ms` ) ;
107127 return ;
108128 }
109129
110130 if ( ! this . registry [ body . method ] ) {
111131 ctx . body = jsonResp ( body . id , new MethodNotFound ( ) , undefined ) ;
112132 ctx . status = 400 ;
133+ ms = Date . now ( ) - this . startTimestamp ;
134+ this . logger . error ( `${ messagePrefix } ${ ctx . status } (${ METHOD_NOT_FOUND } ) ${ ms } ms` ) ;
113135 return ;
114136 }
115137
116- this . requestId = ctx . state . reqId ;
117- const methodName = body . method ;
138+
118139 const methodTotalLimit = this . registryTotal [ methodName ] ;
119140 if ( this . rateLimit . shouldRateLimit ( ctx . ip , methodName , methodTotalLimit , this . requestId ) ) {
120141 ctx . body = jsonResp ( body . id , new IPRateLimitExceeded ( methodName ) , undefined ) ;
121142 ctx . status = 409 ;
143+ ms = Date . now ( ) - this . startTimestamp ;
144+ this . logger . warn ( `${ messagePrefix } ${ ctx . status } (${ IP_RATE_LIMIT_EXCEEDED } ) ${ ms } ms` ) ;
122145 return ;
123146 }
124147
@@ -128,16 +151,22 @@ export default class KoaJsonRpc {
128151 if ( e instanceof InvalidParamsError ) {
129152 ctx . body = jsonResp ( body . id , new InvalidParamsError ( e . message ) , undefined ) ;
130153 ctx . status = 400 ;
154+ ms = Date . now ( ) - this . startTimestamp ;
155+ this . logger . error ( `${ messagePrefix } ${ ctx . status } (${ INVALID_PARAMS_ERROR } ) ${ ms } ms` ) ;
131156 return ;
132157 }
133158 ctx . body = jsonResp ( body . id , new InternalError ( e . message ) , undefined ) ;
134159 ctx . status = 500 ;
160+ ms = Date . now ( ) - this . startTimestamp ;
161+ this . logger . error ( `${ messagePrefix } ${ ctx . status } (${ INTERNAL_ERROR } ) ${ ms } ms` ) ;
135162 return ;
136163 }
137164
138165 ctx . body = jsonResp ( body . id , null , result ) ;
139166 if ( result instanceof JsonRpcError ) {
140167 ctx . status = ( result . code == - 32603 ) ? 500 : 400 ;
168+ ms = Date . now ( ) - this . startTimestamp ;
169+ this . logger . error ( `${ messagePrefix } ${ ctx . status } (${ result . code } ) (${ JSON_RPC_ERROR } ) ${ ms } ms` ) ;
141170 }
142171 } ;
143172 }
@@ -149,4 +178,8 @@ export default class KoaJsonRpc {
149178 getRequestId ( ) : string {
150179 return this . requestId ;
151180 }
181+
182+ getStartTimestamp ( ) : number {
183+ return this . startTimestamp ;
184+ }
152185}
0 commit comments