So I am writing up Node.js Express.js API that utilizes winston for logging. I was hoping if I could achieve a log that looks like this:
[Timestamp] [label] [level]: message
So far I have been able to have the timestamp, level, and messsage. Can anyone help me with how I need to modify the code?
.utilslogger.js
const { createLogger, format, transports } = require('winston')
const config = require('../configs/app.conf')
const devFormat = format.printf(({ timestamp, level, message }) => `${timestamp} ${level}: ${message}`)
const prodFormat = format.printf(({ level, message }) => `${level}: ${message}`)
const logger = createLogger({
level: 'debug',
format: format.combine(
format.timestamp({ format: 'YYYY-MM-DD HH:mm:ss' }),
format.errors({ stack: true }),
format.splat(),
format.json()
),
transports: [
new transports.Console({
format: format.combine(
format.colorize(),
config.env === 'development' ? devFormat : prodFormat
)
}),
new transports.File({ filename: 'logs/error.log', level: 'error' }),
new transports.File({ filename: 'logs/combined.log' })
]
})
module.exports = logger
.index.js
const express = require('express')
const cors = require('cors')
const useragent = require('express-useragent')
const cookieParser = require('cookie-parser')
const app = express()
const logger = require('./utils/logger')
const errorHandler = require('./middlewares/ErrorHandler')
const config = require('./configs/app.conf')
const { connectDB } = require('./db/database')
app.use(cors({
origin: [
'http://localhost:5173',
'https://localhost:5173',
],
methods: 'GET,POST,DELETE,PUT,PATCH',
allowedHeaders: 'Content-Type,Accept,Authorization,x-requested-with',
credentials: true,
}))
app.use(express.json())
app.use(express.urlencoded({ extended: true }))
app.use(useragent.express())
app.use(cookieParser())
app.set('trust proxy', true)
app.use('/user', require('./routes/userRoutes'))
app.use(errorHandler)
const startServer = async () => {
try {
await connectDB()
app.listen(config.port, () => logger.info(`Server running in ${config.env} mode at port ${config.port}`))
}
catch (error) {
logger.error(error.message)
process.exit(1)
}
}
startServer()
.middlewaresErrorHandler.js
const logger = require('../utils/logger')
const errorHandler = (err, req, res) => {
const statusCode = res.statusCode || 500
logger.error(`[${statusCode}] ${err.message}`, {
method: req.method,
path: req.originalUrl,
ip: req.ip,
userAgent: req.headers['user-agent'],
stack: err.stack
})
res.status(statusCode).json({
title: getErrorTitle(statusCode),
message: err.message,
stackTrace: err.stack
})
}
const getErrorTitle = (statusCode) => {
const titles = {
400: "Bad Request",
401: "Unauthorized",
403: "Forbidden",
404: "Not Found",
405: "Method Not Allowed",
406: "Not Acceptable",
408: "Request Timeout",
409: "Conflict",
410: "Gone",
413: "Payload Too Large",
414: "URI Too Long",
415: "Unsupported Media Type",
422: "Unprocessable Entity",
429: "Too Many Requests",
500: "Internal Server Error",
502: "Bad Gateway",
503: "Service Unavailable",
504: "Gateway Timeout"
}
return titles[statusCode] || "Unexpected Error"
}
module.exports = errorHandler
.dbdatabase.js
const { MongoClient, ServerApiVersion } = require('mongodb')
const logger = require('../utils/logger')
const config = require('../configs/app.conf')
let client
const connectDB = async () => {
if (!client) {
try {
client = await MongoClient.connect(config.db_url, {
serverApi: {
version: ServerApiVersion.v1,
strict: true,
deprecationErrors: true
}
})
logger.info('Connected to MongoDB')
}
catch (error) {
throw new Error(error.message)
}
}
return client.db()
}
module.exports = { connectDB }
I was hoping to achieve like for example in the database, if I log the success message, I could somehow make it timestamp [MongoDB] info: Successfully connected to database when logged. Another would be in the index.js when it successfully starts the server, I want it to be timestamp [Server] info: success message. And if I did not indicate a label in the log, it will just default to ‘App’, such that: timestamp [App] info: message. Any ideas on how to achieve this?