@starbemtech/star-node-stack-helper
Version:
A helper library for Node.js applications that provides utilities for AWS Secrets Manager integration and Elasticsearch/OpenSearch logging with enterprise-grade features.
137 lines (124 loc) • 3.09 kB
text/typescript
import pino from 'pino'
import pinoHttp from 'pino-http'
import { PinoLoggerConfig } from './types'
const baseConfig = {
timestamp: pino.stdTimeFunctions.isoTime,
formatters: {
level: (label: string) => {
return { level: label }
},
log: (object: Record<string, unknown>) => {
return object
},
},
serializers: {
req: pino.stdSerializers.req,
res: pino.stdSerializers.res,
err: pino.stdSerializers.err,
},
}
const devConfig = {
...baseConfig,
transport: {
target: 'pino-pretty',
options: {
colorize: true,
levelFirst: true,
translateTime: 'SYS:standard',
ignore: 'pid,hostname',
messageFormat: '{msg} {req.method} {req.url} {res.statusCode}',
},
},
}
const prodConfig = {
...baseConfig,
redact: {
paths: [
'req.headers.authorization',
'req.headers.cookie',
'req.body.password',
'req.body.token',
'req.body.secret',
'res.headers["set-cookie"]',
],
remove: true,
},
}
export const createPinoLogger = (config: PinoLoggerConfig) => {
const loggerConfig =
config.environment === 'production'
? { ...prodConfig, name: config.serviceName, level: config.logLevel }
: { ...devConfig, name: config.serviceName, level: config.logLevel }
return pino(loggerConfig as pino.LoggerOptions)
}
const silentRoutes = [
'/healthz',
'/health',
'/ready',
'/live',
'/ping',
'/metrics',
'/favicon.ico',
'/robots.txt',
]
export const createHttpLogger = (logger: pino.Logger) => {
return pinoHttp({
logger,
customLogLevel: (req: any, res: any, err?: any) => {
if (err) return 'error'
if (silentRoutes.includes(req.url)) {
if (res.statusCode >= 400) return 'warn'
return 'silent'
}
if (res.statusCode >= 400 && res.statusCode < 500) {
return 'warn'
}
if (res.statusCode >= 500) {
return 'error'
}
return 'info'
},
customSuccessMessage: (req: any, res: any) => {
return `${req.method} ${req.url} - ${res.statusCode}`
},
customErrorMessage: (req: any, res: any, err?: any) => {
return `${req.method} ${req.url} - ${res.statusCode} - ${
err?.message || 'Unknown error'
}`
},
customAttributeKeys: {
req: 'request',
res: 'response',
err: 'error',
responseTime: 'responseTime',
},
})
}
export const logContext = {
request: (req: any, additionalData?: any) => ({
method: req.method,
url: req.url,
userAgent: req.get('User-Agent'),
ip: req.ip,
xForwardedFor: req.get('X-Forwarded-For'),
...additionalData,
}),
error: (error: any, context?: any) => ({
message: error.message,
stack: error.stack,
code: error.code,
...context,
}),
performance: (operation: string, duration: number, metadata?: any) => ({
operation,
duration,
unit: 'ms',
...metadata,
}),
proxy: (target: string, service: string, metadata?: any) => ({
target,
service,
type: 'proxy',
...metadata,
}),
}