@@ -10,6 +10,7 @@ import { ConfigurationSchema } from '../config/schema.js';
1010import { getNodeEnv } from '../env.js' ;
1111
1212const LOG_PREFS = Symbol ( 'Logging information' ) ;
13+ const LOGGED_SEMAPHORE = Symbol ( 'Logged semaphore' ) ;
1314
1415interface LogPrefs {
1516 start : [ number , number ] ;
@@ -57,9 +58,13 @@ function finishLog<SLocals extends AnyServiceLocals = ServiceLocals<Configuratio
5758 app : ServiceExpress < SLocals > ,
5859 error : Error | undefined ,
5960 req : Request ,
60- res : Response ,
61+ res : Response & { [ LOGGED_SEMAPHORE ] ?: boolean } ,
6162 histogram : Histogram ,
6263) {
64+ if ( res [ LOGGED_SEMAPHORE ] ) {
65+ return ;
66+ }
67+
6368 const prefs = ( res . locals as WithLogPrefs ) [ LOG_PREFS ] ;
6469 if ( prefs . logged ) {
6570 // This happens when error handler runs, but onEnd hasn't fired yet. We only log the first one.
@@ -71,9 +76,22 @@ function finishLog<SLocals extends AnyServiceLocals = ServiceLocals<Configuratio
7176
7277 const dur = hrdur [ 0 ] + hrdur [ 1 ] / 1000000000 ;
7378 const [ url , preInfo ] = getBasicInfo ( req ) ;
79+
80+ let responseType : string = 'finished' ;
81+
82+ // ts warning is known and incorrect—`aborted` is a subset of `destroyed`
83+ if ( req . aborted ) {
84+ responseType = 'aborted' ;
85+ } else if ( req . destroyed ) {
86+ responseType = 'destroyed' ;
87+ } else if ( error ) {
88+ responseType = 'errored' ;
89+ }
90+
7491 const endLog : Record < string , string | string [ ] | number | undefined > = {
7592 ...preInfo ,
7693 t : 'req' ,
94+ r : responseType ,
7795 s : ( error as ErrorWithStatus ) ?. status || res . statusCode || 0 ,
7896 dur,
7997 } ;
@@ -124,6 +142,8 @@ function finishLog<SLocals extends AnyServiceLocals = ServiceLocals<Configuratio
124142 } else {
125143 logger . info ( endLog , msg ) ;
126144 }
145+
146+ res [ LOGGED_SEMAPHORE ] = true ;
127147}
128148
129149export function loggerMiddleware <
@@ -180,8 +200,10 @@ export function loggerMiddleware<
180200 logger . info ( preLog , msg ) ;
181201 }
182202
183- const logWriter = ( ) => finishLog ( app , undefined , req , res , histogram ) ;
203+ const logWriter = ( err ?: Error ) => finishLog ( app , err , req , res , histogram ) ;
184204 res . on ( 'finish' , logWriter ) ;
205+ res . on ( 'close' , logWriter ) ;
206+ res . on ( 'error' , logWriter ) ;
185207 next ( ) ;
186208 } ;
187209}
0 commit comments