@@ -47,16 +47,19 @@ server.register(compression, {
4747server . setErrorHandler ( ( error , request , reply ) => {
4848 const alreadySent = reply . sent || reply . raw . headersSent || reply . raw . writableEnded ;
4949 const errorCode = error . statusCode || 500 ;
50- const errorLog = {
51- reqId : request . id ,
52- correlationId : request . correlationId ,
53- url : request . url ,
54- method : request . method ,
55- statusCode : errorCode ,
56- error : error . message ,
57- stack : error . stack
58- } ;
59- request . log . error ( errorLog ) ;
50+ if ( error . stack ) {
51+ const wrappedError = new Error ( error . message ) ;
52+ wrappedError . stack = error . stack ;
53+ // important! the first parameter of log.error is the error object with an optional second parameter
54+ // for the message.
55+ request . log . error ( wrappedError , `Request error: ${ error . message } ` ) ;
56+ } else {
57+ // if the error is not an instance of Error, we should log it as a string. if first parameter is a string,
58+ // then args from the second parameter are ignored. so always only log:
59+ // one string parameter or (err,string) for request.log.error
60+ // for request.log.info, pino only supports a single string parameter. this is important for logs to work.
61+ request . log . error ( `Request error: ${ error . message } ` ) ;
62+ }
6063 if ( alreadySent ) {
6164 // the api already set the appropriate error message. we shouldnt do anything now.
6265 return ;
@@ -85,11 +88,20 @@ server.addHook('onRequest', (request, reply, done) => {
8588
8689 request . startTime = Date . now ( ) ;
8790 if ( request . headers [ 'content-length' ] ) {
91+ // for request.log.info, pino only supports a single string parameter or a serializable json
92+ // with a `message` attribute like below. this is important for logs to work. you can put in url and other
93+ // ewll known fields we support in our logging dashboard. you need not do this, only a string is needed and
94+ // in dashboard the request id is injected with the log line. use object instead of string only for
95+ // additional attributes like correlation id, url, size etc. these needs not be with every request as you
96+ // can search all these with the request id in the dashboard to get context, so plain strings are
97+ // recommended for logging info in most cases.
8898 request . log . info ( {
99+ message : 'Request size' ,
89100 reqId : request . id ,
101+ url : request . url ,
90102 correlationId : request . correlationId ,
91103 size : `${ request . headers [ 'content-length' ] } bytes`
92- } , 'Request size' ) ;
104+ } ) ;
93105 }
94106 done ( ) ;
95107} ) ;
@@ -109,31 +121,27 @@ server.addHook('onRequest', (request, reply, done) => {
109121 } ) ;
110122 if ( ! routeExists ) {
111123 request . log . error ( {
124+ message : 'Route not found' ,
112125 reqId : request . id ,
113126 correlationId : request . correlationId ,
114127 url : sanitizedUrl ,
115128 method : request . method ,
116129 ip : request . ips
117- } , "Route not found" ) ;
130+ } ) ;
118131 reply . code ( HTTP_STATUS_CODES . NOT_FOUND ) ;
119132 return reply . send ( { error : 'Not Found' } ) ;
120133 } else if ( ! isAuthenticated ( request ) ) {
121134 request . log . warn ( {
135+ message : 'Unauthorized access attempt' ,
122136 reqId : request . id ,
123137 correlationId : request . correlationId ,
124138 url : sanitizedUrl ,
125139 method : request . method ,
126140 ip : request . ips
127- } , "Unauthorized access attempt" ) ;
141+ } ) ;
128142 reply . code ( HTTP_STATUS_CODES . UNAUTHORIZED ) ;
129143 return reply . send ( { error : 'Unauthorized' } ) ;
130144 }
131- request . log . info ( {
132- reqId : request . id ,
133- correlationId : request . correlationId ,
134- url : sanitizedUrl ,
135- method : request . method
136- } , "Request authenticated" ) ;
137145 done ( ) ;
138146} ) ;
139147
@@ -153,13 +161,14 @@ server.addHook('onRequest', (request, reply, done) => {
153161server . addHook ( 'onResponse' , ( request , reply , done ) => {
154162 const duration = Date . now ( ) - request . startTime ;
155163 request . log . info ( {
164+ message : 'Request completed' ,
156165 reqId : request . id ,
157166 correlationId : request . correlationId ,
158167 url : request . url ,
159168 method : request . method ,
160169 statusCode : reply . statusCode ,
161170 duration : `${ duration } ms`
162- } , 'Request completed' ) ;
171+ } ) ;
163172 done ( ) ;
164173} ) ;
165174
@@ -264,9 +273,9 @@ export async function startServer() {
264273 port : configs . port ,
265274 host : configs . allowPublicAccess ? '0.0.0.0' : 'localhost'
266275 } ) ;
267- server . log . info ( { message : `Server started on port ${ configs . port } ` } ) ;
276+ server . log . info ( `Server started on port ${ configs . port } ` ) ;
268277 } catch ( err ) {
269- server . log . error ( { message : 'Error starting server' , error : err } ) ;
278+ server . log . error ( err , 'Error starting server' ) ;
270279 process . exit ( 1 ) ;
271280 }
272281}
@@ -278,41 +287,45 @@ export async function close() {
278287 server . log . info ( { message : 'Shutting down server...' } ) ;
279288 try {
280289 const shutdownTimeout = setTimeout ( ( ) => {
281- server . log . error ( { message : 'Forced shutdown after timeout' } ) ;
290+ server . log . error ( 'Forced shutdown after timeout' ) ;
282291 process . exit ( 1 ) ;
283292 } , CLEANUP_GRACE_TIME_5SEC ) ;
284293
285294 await server . close ( ) ;
286295 clearTimeout ( shutdownTimeout ) ;
287- server . log . info ( { message : 'Server shut down successfully' } ) ;
296+ server . log . info ( 'Server shut down successfully' ) ;
288297 } catch ( err ) {
289- server . log . error ( { message : 'Error during shutdown' , error : err } ) ;
298+ server . log . error ( err , 'Error during shutdown' ) ;
290299 process . exit ( 1 ) ;
291300 }
292301}
293302
294303// Handle process termination
295304process . on ( 'SIGTERM' , async ( ) => {
296- server . log . info ( { message : 'SIGTERM received' } ) ;
305+ server . log . info ( 'SIGTERM received' ) ;
297306 await close ( ) ;
298307 process . exit ( 0 ) ;
299308} ) ;
300309
301310process . on ( 'SIGINT' , async ( ) => {
302- server . log . info ( { message : 'SIGINT received' } ) ;
311+ server . log . info ( 'SIGINT received' ) ;
303312 await close ( ) ;
304313 process . exit ( 0 ) ;
305314} ) ;
306315
307316// Handle uncaught exceptions
308317process . on ( 'uncaughtException' , ( err ) => {
309- server . log . error ( { message : 'Uncaught Exception' , error : err } ) ;
318+ server . log . error ( err , 'Uncaught Exception' ) ;
310319 close ( ) . then ( ( ) => process . exit ( 1 ) ) ;
311320} ) ;
312321
313322// Handle unhandled promise rejections
314323process . on ( 'unhandledRejection' , ( reason , promise ) => {
315324 // non error rejections do not have a stack trace and hence cannot be located.
316- server . log . error ( { message : 'Unhandled Rejection at promise' , error : reason instanceof Error ? reason : { reason } , promise} ) ;
325+ if ( reason instanceof Error ) {
326+ server . log . error ( reason , 'Unhandled Rejection at promise' ) ;
327+ } else {
328+ server . log . error ( 'Unhandled Rejection at promise. reason:' + reason ) ;
329+ }
317330 close ( ) . then ( ( ) => process . exit ( 1 ) ) ;
318331} ) ;
0 commit comments