Skip to content

Instantly share code, notes, and snippets.

@xeoncross
Last active April 21, 2024 00:26
Show Gist options
  • Star 32 You must be signed in to star a gist
  • Fork 9 You must be signed in to fork a gist
  • Save xeoncross/b8a735626559059353f21a000f7faa4b to your computer and use it in GitHub Desktop.
Save xeoncross/b8a735626559059353f21a000f7faa4b to your computer and use it in GitHub Desktop.
Expressjs Server Monitoring with Winston + Morgan
const { createLogger, format, transports } = require("winston");
// https://github.com/winstonjs/winston#logging
// { error: 0, warn: 1, info: 2, verbose: 3, debug: 4, silly: 5 }
const level = process.env.LOG_LEVEL || "debug";
function formatParams(info) {
const { timestamp, level, message, ...args } = info;
const ts = timestamp.slice(0, 19).replace("T", " ");
return `${ts} ${level}: ${message} ${Object.keys(args).length
? JSON.stringify(args, "", "")
: ""}`;
}
// https://github.com/winstonjs/winston/issues/1135
const developmentFormat = format.combine(
format.colorize(),
format.timestamp(),
format.align(),
format.printf(formatParams)
);
const productionFormat = format.combine(
format.timestamp(),
format.align(),
format.printf(formatParams)
);
let logger;
if (process.env.NODE_ENV !== "production") {
logger = createLogger({
level: level,
format: developmentFormat,
transports: [new transports.Console()]
});
} else {
logger = createLogger({
level: level,
format: productionFormat,
transports: [
new transports.File({ filename: "error.log", level: "error" }),
new transports.File({ filename: "combined.log" })
]
});
}
module.exports = logger;
{
"name": "expressjslogging",
"license": "MIT",
"dependencies": {
"express": "^4.16.2",
"morgan": "^1.9.0",
"winston": "^3.0.0-rc1"
}
}
const express = require("express");
const logger = require("./logger");
const morgan = require("morgan");
const PORT = 3000;
const app = express();
const morganFormat = process.env.NODE_ENV !== "production" ? "dev" : "combined";
app.use(
morgan(morganFormat, {
skip: function(req, res) {
return res.statusCode < 400;
},
stream: process.stderr
})
);
app.use(
morgan(morganFormat, {
skip: function(req, res) {
return res.statusCode >= 400;
},
stream: process.stdout
})
);
app.get("/", function(req, res) {
logger.debug("Debug statement");
logger.info("Info statement");
res.send(req.method + ' ' + req.originalURL);
});
app.get("/error", function(req, res) {
throw new Error('Problem Here!');
});
// All errors are sent back as JSON
app.use((err, req, res, next) => {
// Fallback to default node handler
if (res.headersSent) {
next(err);
return;
}
logger.error(err.message, {url: req.originalUrl});
res.status(500);
res.json({ error: err.message });
});
// Start server
app.listen(PORT, function() {
logger.info("Example app listening on port " + PORT);
logger.debug("More detailed log", {PORT});
});
@xeoncross
Copy link
Author

@oleksandr-danylchenko
Copy link

Thank you! This helped me a lot!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment