import { Request , RequestHandler } from 'express' ; import pino , { LoggerOptions } from 'pino' ; import pinoHTTP , { stdSerializers } from 'pino-http' ; import { getConfigFromEnv } from './utils/get-config-from-env' ; import { URL } from 'url' ; import env from './env' ; const pinoOptions = { level : env . LOG_LEVEL || 'info' , redact : { paths : [ 'req.headers.authorization' , `req.cookies.${ env . REFRESH_TOKEN_COOKIE_NAME }` ] , censor : '--redact--' , } , } ; if ( env . LOG_STYLE !== 'raw' ) { pinoOptions . prettyPrint = true ; pinoOptions . prettifier = require ( 'pino-colada' ) ; } const loggerEnvConfig = getConfigFromEnv ( 'LOGGER_' , 'LOGGER_HTTP' ) ; if ( loggerEnvConfig . levels ) { const customLogLevels = { } ; for ( const el of loggerEnvConfig . levels . split ( ',' ) ) { const key_val = el . split ( ':' ) ; customLogLevels [ key_val [ 0 ] . trim ( ) ] = key_val [ 1 ] . trim ( ) ; } pinoOptions . formatters = { level ( label , number ) { return { severity : customLogLevels [ label ] || 'info' , level : number , } ; } , } ; delete loggerEnvConfig . levels ; } const logger = pino ( Object . assign ( pinoOptions , loggerEnvConfig ) ) ; const httpLoggerEnvConfig = getConfigFromEnv ( 'LOGGER_HTTP' , [ 'LOGGER_HTTP_LOGGER' ] ) ; export const expressLogger = pinoHTTP ( { logger , ... httpLoggerEnvConfig , } , { serializers : { req ( request ) { const output = stdSerializers . req ( request ) ; output . url = redactQuery ( output . url ) ; return output ; } , } , } ) as RequestHandler ; export default logger ; function redactQuery ( originalPath ) { const url = new URL ( originalPath , 'http://example.com/' ) ; if ( url . searchParams . has ( 'access_token' ) ) { url . searchParams . set ( 'access_token' , '--redacted--' ) ; } return url . pathname + url . search ; }