qapinterface
Version:
Comprehensive API utilities for Node.js applications including authentication, security, request processing, and response handling with zero external dependencies
106 lines (94 loc) • 2.26 kB
JavaScript
/**
* Logger Creator
* Single Responsibility: Create logger instances ONLY
*/
const pino = require('pino');
const fs = require('fs');
const path = require('path');
const {
LOG_LEVELS,
NODE_ENV,
CLOUDWATCH_LOG_GROUP,
CLOUDWATCH_LOG_STREAM,
AWS_REGION,
AWS_ACCESS_KEY_ID,
AWS_SECRET_ACCESS_KEY
} = require('../../config/localVars');
// Singleton logger instance
let logger = null;
/**
* Creates and returns a singleton logger instance.
* @param {object} [options] - Pino logger options.
* @returns {pino.Logger} - A Pino logger instance.
*/
async function createLogger(options = {}) {
if (logger) {
return logger;
}
const {
logFilePath = './logs/app.log',
level = LOG_LEVELS.INFO,
prettyPrint = NODE_ENV !== 'production',
} = options;
const logDir = path.dirname(logFilePath);
try {
await fs.promises.access(logDir);
} catch (err) {
if (err.code === 'ENOENT') {
await fs.promises.mkdir(logDir, { recursive: true });
} else {
throw err;
}
}
// Build transport targets array
const targets = [
{
target: 'pino-roll',
options: {
file: logFilePath,
frequency: 'daily',
size: '10m',
mkdir: true,
},
level: level,
}
];
// Add pretty print in non-production
if (prettyPrint) {
targets.push({
target: 'pino-pretty',
options: {
colorize: true,
translateTime: 'SYS:standard',
ignore: 'pid,hostname',
},
level: level,
});
}
// Add CloudWatch in production
if (NODE_ENV === 'production') {
targets.push({
target: 'pino-cloudwatch',
options: {
group: CLOUDWATCH_LOG_GROUP || 'qapi-logs',
stream: CLOUDWATCH_LOG_STREAM || 'app',
aws_region: AWS_REGION || 'us-west-2',
aws_access_key_id: AWS_ACCESS_KEY_ID,
aws_secret_access_key: AWS_SECRET_ACCESS_KEY,
},
level: level,
});
}
const transport = pino.transport({ targets });
logger = pino(transport);
// Add graceful shutdown hooks
process.on('beforeExit', () => logger.flush());
process.on('SIGINT', () => {
logger.flush();
process.exit(0);
});
return logger;
}
module.exports = {
createLogger
};