Set default winston logger for all modules - node.js

I am trying to setup winston to work in all my modules in the same fashion as in here:
using winston in several modules
But I am running in problems.
I have setup a logger.js file to configure the console logger:
var winston = require('winston');
var logger = new (winston.Logger)({
transports: [
new (winston.transports.Console)({
timestamp: true,
level: 'verbose',
colorize: true
})
]
});
module.exports = logger;
I then require that logger in my main app.js file:
var logger = require('./logger.js');
logger.info('Starting server'); // this console log looks great, just as I configured
However when I try an require winston in al other modules I lose the config I setup for winston in the logger.js
Other Module:
var logger = require('winston');
logger.info('in another module'); // this is back to winstons default console transport
According to the link I referenced above I should be able to require winston in all other modules and the transports I defined/configured should still be the same. Only thing I can think is that this is not true for the Console transport. If not what gives? How do I configure the Console transport once and then use winston in all other modules?

For your current solution to work, you have to make sure you have one version of winston. You shouldn't have it installed once under your main app and another time under your other module. Then in here you are creating a new instance of logger and not using the default.
You should instead of above do this:
var winston = require('winston');
winston.remove(winston.transports.Console);
winston.add(winston.transports.Console, {
timestamp: true,
level: 'verbose',
colorize: true
});
I think this should work. If that didn't work, you can try one of these methods:
Get them to use your ./logger module instead. This works great in internal modules that are part of the app codebase.
Or make your other module configurable. Do something like require('other-module').logger = require('./logger'); or require('other-module').setLogger(require('./logger'));. You can check this question if you want to know more about this method.

Related

How to store nodejs server runtime error logs in file winston nodejs

I am new to winston and trying to store nodejs server logs into file.
const {
createLogger,
transports,
format
} = require('winston');
const logger = createLogger({
transports: [
new transports.File({
filename : 'info.log',
level: 'info',
format: format.combine(format.timestamp(), format.json())
})
]
})
module.exports = logger;
And I can store log in the file using logger.log('info',"Inside /login")
How can I store the nodejs server logs which are generated automatically run time when error happens.
For example this log which I can see in console when the mySQL db connection was closed and these logs were generated by nodejs server.

Loggly Subdomain is required

I'm trying to implement to my NodeJs API a logging system using:
Loggly
Winston
Morgan
When I run my server I got the error:
Error: Loggly Subdomain is required
But the subdomain is defined as follows
What I was trying to do to put the Loggly config inside of a module:
module.exports = {
loggly: {
token: process.env.LOG_TOKEN,
subdomain: process.env.SUBDOMAIN,
tags: ["Winston-NodeJS"],
json: true
}
};
Using also the ENV which are defined and contains the right info.
Then I created a new file called logger.js
// Requiring libs Loggly & Winston
const Loggly = require("winston-loggly-bulk").Loggly;
const winston = require("winston");
// Loggly config
const config = require("../config/config");
// Creating the logging
const logger = winston.createLogger({
transports: [
new Loggly(config.loggly), ==> Here the error occur!
new winston.transports.Console({ level: "info" })
]
});
// Logging stream
logger.stream = {
write: (info) => {
logger.info(info);
}
};
module.exports = logger;
In this script, the error occurs when I call new Loggly(...) seems cannot read my SUBDOMAIN and I cannot understand a different way of doing as it is the first time I'm trying this implementation.
Put this line require("dotenv").config(); on line 1 in server.js.

Winston is not writing logs for my Heroku MERN app although it works fine locally

I have a MERN app -- React frontend, Express/Mongoose backend -- that works fine locally. I deployed the backend to Heroku, the frontend to Surge and Winston no longer functions correctly.
That is: it is not writing the log files at all, although it does so perfectly locally (localhost).
The Node version on Heroku is 8.11.4, whereas locally (MacOS) it's 10.8.0. And Heroku is being called through https rather than my localhost, which is running http. Those are the only differences I see.
I tried specifying __dirname, tried remove a folder reference (that is, putting the files inside a directory logs, but no log files are being written anywhere.
My logger module is the following
const {createLogger, format, transports} = require('winston');
const {combine, timestamp, align, colorize, printf} = format;
const path = require('path')
const myFormat = printf(info => {
return `${info.timestamp} [${info.level}: ${info.message}]`;
});
const logger = createLogger({
level: 'debug',
format: combine(
colorize(),
timestamp(),
align(),
myFormat
),
transports: [
new transports.File({maxsize: 500000, filename: path.join(__dirname,'logs/error.log'), level: 'error'}),
new transports.File({maxsize: 500000, filename: path.join(__dirname,'logs/combined.log')})
]
})
module.exports = logger
Again, the frustrating thing is it all works perfectly locally. Thanks for any help in tracking this down!
Heroku hasn't local storage. Use mail transport to get errors from a server. Or You can use Heroku services for monitoring your app. Like: Addons-Loggers
const logger = winston.createLogger({
transports: [
...
// Add following code for getting logs in console as well
new winston.transports.Console(),
]
});

Show uncaught exception in console when using winston (node.js)

Here's the code I'm working with:
var winston = require('winston');
winston.add(winston.transports.File, { filename: 'test.log', handleExceptions: true, humanReadableUnhandledException: true });
throw "test";
In test.log, winston does log the error properly.
But I'd also like it to show the error in the console as well like it normally does.
Is this possible?
Add Console transport to winston, along with existing File transport:
winston.add(winston.transports.Console, options)
https://github.com/winstonjs/winston/blob/master/docs/transports.md#console-transport

Where is nodejs log file?

I can't find a place where nodejs log file is stored.
Because in my node server I have "Segmentation fault", I want to look at log file for additional info...
There is no log file. Each node.js "app" is a separate entity. By default it will log errors to STDERR and output to STDOUT. You can change that when you run it from your shell to log to a file instead.
node my_app.js > my_app_log.log 2> my_app_err.log
Alternatively (recommended), you can add logging inside your application either manually or with one of the many log libraries:
winston
log4js
...
forever might be of interest to you. It will run your .js-File 24/7 with logging options. Here are two snippets from the help text:
[Long Running Process]
The forever process will continue to run outputting log messages to the console.
ex. forever -o out.log -e err.log my-script.js
and
[Daemon]
The forever process will run as a daemon which will make the target process start
in the background. This is extremely useful for remote starting simple node.js scripts
without using nohup. It is recommended to run start with -o -l, & -e.
ex. forever start -l forever.log -o out.log -e err.log my-daemon.js
forever stop my-daemon.js
If you use docker in your dev you can do this in another shell:
docker attach running_node_app_container_name
That will show you STDOUT and STDERR.
For nodejs log file you can use winston and morgan and in place of your console.log() statement user winston.log() or other winston methods to log.
For working with winston and morgan you need to install them using npm. Example:
npm i -S winston
npm i -S morgan
Then create a folder in your project with name winston and then create a config.js in that folder and copy this code given below.
const appRoot = require('app-root-path');
const winston = require('winston');
// define the custom settings for each transport (file, console)
const options = {
file: {
level: 'info',
filename: `${appRoot}/logs/app.log`,
handleExceptions: true,
json: true,
maxsize: 5242880, // 5MB
maxFiles: 5,
colorize: false,
},
console: {
level: 'debug',
handleExceptions: true,
json: false,
colorize: true,
},
};
// instantiate a new Winston Logger with the settings defined above
let logger;
if (process.env.logging === 'off') {
logger = winston.createLogger({
transports: [
new winston.transports.File(options.file),
],
exitOnError: false, // do not exit on handled exceptions
});
} else {
logger = winston.createLogger({
transports: [
new winston.transports.File(options.file),
new winston.transports.Console(options.console),
],
exitOnError: false, // do not exit on handled exceptions
});
}
// create a stream object with a 'write' function that will be used by `morgan`
logger.stream = {
write(message) {
logger.info(message);
},
};
module.exports = logger;
After copying the above code make make a folder with name logs parallel to winston or wherever you want and create a file app.log in that logs folder. Go back to config.js and set the path in the 5th line "filename: ${appRoot}/logs/app.log,
" to the respective app.log created by you.
After this go to your index.js and include the following code in it.
const morgan = require('morgan');
const winston = require('./winston/config');
const express = require('express');
const app = express();
app.use(morgan('combined', { stream: winston.stream }));
winston.info('You have successfully started working with winston and morgan');

Resources