I am able to log every request and error message into separate logfiles(request.log and uncaughtExceptions.log) but want to merge this two files into one file only called logs.log like
var logmsg = {
'Request IP',
'Method':req.method,
'URL':req.originalUrl,
'statusCode':res.statusCode,
'headers':req.headers,
'Time':new Date(),
'ErrorMessage':'Error Message if any with file name with line number and proper error message'
};
Working Code:
const express = require('express');
const winston = require('winston');
require('express-async-errors');
module.exports = function() {
winston.handleExceptions(
new winston.transports.File({ filename: 'uncaughtExceptions.log' }));
process.on('unhandledRejection', (ex) => {
throw ex;
});
winston.add(winston.transports.File, { filename: 'request.log' });
}
What I have Tried:
logging.js
const express = require('express');
const { createLogger, format, transports } = require('winston');
const { combine, timestamp, label, printf } = format;
const myFormat = printf(info => {
return (info.timestamp + " | " +
info.trace[0].file + ":" + info.trace[0].line + " | " +
info.message.split("\n")[0]);
});
module.exports = function() {
const logger = createLogger({
format: combine(timestamp(), myFormat)
});
logger.exceptions.handle(new transports.File({ filename: 'logs.log' }));
process.on('unhandledRejection', (reason, p) => {
throw p;
});
}
it displays strange error message, i have no idea how to resolve it.
Error message:
server.js
const express = require('express');
const winston = require("winston");
const app = express();
//to Log errors
require('./startup/logging')();
//routes will contains all the routes list
require('./startup/routes')(app);
//PORT
const port = process.env.PORT || 3000;
app.listen(port,() => winston.info(`Listening on port ${port}....`));
routes.js
const express = require('express');
const reqres = require('../middlewares/reqreslog');
module.exports = function(app){
//Every Request Response Logging Middleware
app.use(reqres);
app.get('/', async (req, res) => {
res.json("testing"+a);
});
});
reqreslog.js
var winston = require('winston');
module.exports = function(req, res, next) {
var logmsg = {
'Request IP':req.ip,
'Method':req.method,
'URL':req.originalUrl,
'statusCode':res.statusCode,
'headers':req.headers,
'Time':new Date(),
'ErrorMessage':'Display Error If Any for this request'
};
winston.log('info', logmsg);
next();
}
Winston logging works on the basis of log level info,debug,error etc.. If you want to log everything into the same log file you have to give level info.
const logger = winston.createLogger({
levels: winston.config.syslog.levels,
transports: [
new winston.transports.File({
filename: 'combined.log',
level: 'info'
})
]
});
process.on('unhandledRejection', (reason, p) => {
logger.error('exception occur');
throw reason;
});
Read more about log level in winstonjs - https://github.com/winstonjs/winston#using-logging-levels
Related
The directory path is path: '/mnt/c/Users/merir/Downloads/nerdr-backend/Users/merir/Downloads/nerdr-backend/controllers/resources/static/assets/uploads'. I console log the path, the folders exist, but I'm still getting this error.
Here is my router:
uploadRouter.get('/files', async (req, res) => {
const directoryPath = path.resolve(__dirname, "resources/static/assets/uploads/")
fs.readdir(directoryPath, function (err, files) {
console.log(files)
if (err) {
res.status(500).send({
message: "Unable to scan files!",
})
}
}
)
})
and here my app.js:
const config = require('./utils/config')
const express = require('express')
const app = express()
const cors = require('cors')
const mongoose = require('mongoose')
require('express-async-errors')
const swipesRouter = require('./controllers/swipes')
const usersRouter = require('./controllers/users')
const loginRouter = require('./controllers/login')
const uploadRouter = require('./controllers/file.controller')
mongoose.connect(config.MONGODB_URI)
.then(() => {
console.log('connected to MongoDB')
})
.catch((error) => {
console.log('error connection to MongoDB:', error.message)
})
app.use(cors())
app.use(express.static('build'))
app.use(express.json())
app.use('/api/swipes', swipesRouter)
app.use('/api/users', usersRouter)
app.use('/api/login', loginRouter)
app.use('/api/upload', uploadRouter)
module.exports = app
I'm following a tutorial at https://www.woolha.com/tutorials/node-js-google-cloud-pub-sub-basic-examples and having some difficulty..
I've the following code in server.js:-
const express = require('express');
const app = express();
const path = require('path');
const bodyParser = require('body-parser');
const dotenv = require('dotenv');
dotenv.config(); // Reads the .env file from the local folder.
// PubSub constant initialisation
const PubSub = require(`#google-cloud/pubsub`);
const pubsub = new PubSub();
const data = new Date().toString();
const dataBuffer = Buffer.from(data);
const topicName = 'sensehat-led-config';
app.use(bodyParser.urlencoded({ extended: true}));
// Tell the app to use the public folder.
app.use(express.static('public'));
app.get('/', (req,res) => {
res.send('Hello from App Engine!');
})
app.get('/submit', (req, res) => {
res.sendFile(path.join(__dirname, '/views/form.html'));
})
// Need to figure out how to get the css file to work in this. Can't be that hard.
app.get('/sensehat', (req, res) => {
res.sendFile(path.join(__dirname, '/views/sensehat.html'));
})
app.get('/sensehat-publish-message', (req, res) =>{
pubsub
.topic(topicName)
.publisher()
.publish(dataBuffer)
.then(messageId => {
console.log(`Message ${messageId} published`);
})
.catch(err => {
console.error('ERROR:', err);
});
})
app.post('/submit', (req, res) => {
console.log({
name: req.body.name,
message: req.body.message
});
res.send('Thanks for your message!');
})
// Listen to the App Engine-specified port, or 8080 otherwise
const PORT = process.env.PORT || 8080;
app.listen(PORT, () => {
console.log('Server listening on port ${PORT}...');
})
But when I run it I get a '500 Server Error', and looking at the Stackdriver logs I get the following error:-
TypeError: PubSub is not a constructor at Object.<anonymous>
I'm definitely a newbie at NodeJS and feeling my way around. After reading around I think the issue is coming from the
const PubSub = require(`#google-cloud/pubsub`);
const pubsub = new PubSub();
lines, but no idea how to rectify this.
You can try with latest versions of all libraries.
Dependencies in package.json
"dependencies": {
"#google-cloud/pubsub": "1.5.0",
"google-gax": "1.14.1",
"googleapis": "47.0.0"
}
Example code -
const {
PubSub
} = require('#google-cloud/pubsub');
const pubsub = new PubSub({
projectId: process.env.PROJECT_ID
});
module.exports = {
publishToTopic: function(topicName, data) {
return pubsub.topic(topicName).publish(Buffer.from(JSON.stringify(data)));
},
};
Calling file code
const PubSubPublish = require('path to your above file')
let publishResult = await PubSubPublish.publishToTopic(process.env.TOPIC_NAME, data)
Hope it helps!
You require the default export of #google-cloud/pubsub, but what look for is not in the default export.
Change the way you import PubSub to:
const {PubSub} = require(`#google-cloud/pubsub`);
Instead of:
const PubSub = require(`#google-cloud/pubsub`);
Basically i am trying to implement logger for the nodejs , using morgan and winston.
When i am trying to use morgan , throwing an error of stream.write is not a function.
Since i want get the file name , i am passing the module, from module object there is a property called filename.
Below is my code.
// Winston.js
const appRoot = require('app-root-path');
const { createLogger, format, transports } = require('winston');
const { combine, timestamp, label, printf } = format;
const path = require('path');
// Custom Format
const customFormat = printf(info => {
return `${new Date(info.timestamp)} || [${info.label}] || ${info.level}: ${info.message} `
})
// Return the last folder name in the path and the calling
// module's filename.
const getLabel = function (moduleDetails) {
if (Object.keys(moduleDetails).length > 0) {
let parts = moduleDetails.filename.split(path.sep)
return parts.pop();
}else{
return;
}
}
// define the custom settings for each transport (file, console)
var options = (moduleDetails) => ({
file: {
level: "info",
timestamp: new Date(),
filename: `${appRoot}/logs/app.log`,
handleExceptions: true,
json: true,
maxsize: 5242880,
maxFiles: 5,
colorize: false,
label: getLabel(moduleDetails)
},
console: {
level: "debug",
handleExceptions: true,
json: false,
colorize: true,
}
})
//instantiate a new Winston Logger with the settings defined above
let logger = function (moduleDetails) {
return createLogger({
format: combine(
label({label:getLabel(moduleDetails)}),
timestamp(),
customFormat
),
transports: [
new transports.File(options(moduleDetails).file)
],
exitOnError: false // do not exit on handled exceptions
})
}
// create a stream object with 'write' function that will be used by 'morgan'
// logger({})["stream"] = {
// write: function (message, encoding) {
// // use the 'info' log level so the output will be picked up by both transports
// // (file and console)
// logger().info(message)
// }
// }
// If we're not in production then log to the `console` with the format:
// `${info.timestamp} || [${info.label}] || ${info.level}: ${info.message}`
// like in the log file
if (process.env.NODE_ENV !== 'prod') {
logger({}).add(new transports.Console(options({}).console));
}
module.exports = logger
module.exports.stream = {
write: function (message, encoding) {
// use the 'info' log level so the output will be picked up by both transports
// (file and console)
logger().info(message)
}
}
// App.js
var createError = require('http-errors');
var express = require('express');
var path = require('path');
var cookieParser = require('cookie-parser');
var morgan = require('morgan');
var indexRouter = require('./routes/index');
var usersRouter = require('./routes/users');
var winston = require('./config/winston')(module);
var app = express();
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'jade');
app.use(morgan('combined', { "stream": winston.stream}));
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
app.use('/', indexRouter);
app.use('/users', usersRouter);
// catch 404 and forward to error handler
app.use(function(req, res, next) {
next(createError(404));
});
// error handler
app.use(function(err, req, res, next) {
// set locals, only providing error in development
res.locals.message = err.message;
res.locals.error = req.app.get('env') === 'development' ? err : {};
// add this line to include winston logging
winston.error(`${err.status || 500} || ${err.message} || ${req.originalUrl} || ${req.method} || ${req.ip}` )
// render the error page
res.status(err.status || 500);
res.render('error');
});
module.exports = app;
On App.js, try changing
app.use(morgan('combined', { "stream": winston.stream}));
to
app.use(morgan('combined', { "stream": winston.stream.write}));
This seems to work even though I don't know why.
I think you didn't export module correctly, should be:
var winston = require('./config/winston');
winston.logger(module);
instead:
var winston = require('./config/winston')(module);
i have written one middle-ware for handling uncaughtExceptions which is working fine but after that server will crashed.
how do i prevent to crash it?
server.js:
const express = require('express');
const winston = require("winston");
const app = express();
//Logging is responsible to log and display errors
require('./startup/logging')();
//routes will contains all the routes list
require('./startup/routes')(app);
//PORT
const port = process.env.PORT || 3000;
app.listen(port,() => winston.info(`Listening on port ${port}....`));
logging.js
const express = require('express');
const winston = require('winston');
// require('express-async-errors');
module.exports = function() {
winston.handleExceptions(
new winston.transports.File({ filename: 'uncaughtExceptions.log' })
);
process.on('unhandledRejection', (ex) => {
throw ex;
});
winston.add(winston.transports.File, { filename: 'error.log' });
}
If you do throw ex; The program will crash, Rather you should send the crash report and message to the respective reporting mechanism that you are using. Heres a small snippet
process.on('unhandledRejection', (reason, promise) => {
console.log('Unhandled Rejection at:', reason.stack || reason)
// Recommended: send the information to sentry.io
// or whatever crash reporting service you use
})
i have written one middle-ware for handling uncaughtExceptions which is working fine but after that server will crashed.
how do i prevent to crash it?
server.js:
const express = require('express');
const winston = require("winston");
const app = express();
//Logging is responsible to log and display errors
require('./startup/logging')();
//routes will contains all the routes list
require('./startup/routes')(app);
//PORT
const port = process.env.PORT || 3000;
app.listen(port,() => winston.info(`Listening on port ${port}....`));
logging.js
const express = require('express');
const winston = require('winston');
// require('express-async-errors');
module.exports = function() {
winston.handleExceptions(
new winston.transports.File({ filename: 'uncaughtExceptions.log' })
);
process.on('unhandledRejection', (ex) => {
throw ex;
});
winston.add(winston.transports.File, { filename: 'error.log' });
}
As the documentation states,
By default, winston will exit after logging an uncaughtException. If this is not the behavior you want, set exitOnError = false
const logger = winston.createLogger({ exitOnError: false });
//
// or, like this:
//
logger.exitOnError = false;
It is generally considered a bad practice to not exit after an exception because the consequences are unpredictable. If only some of the exceptions are known to be tolerable, they can be specifically handled with a predicate:
const ignoreWarnings = err => !(err instanceof WarningError);
const logger = winston.createLogger({ exitOnError: ignoreWarnings });