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
Related
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.
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.
I need a working example which post the logs on server using http transport. I'm able to use file transport and console transport to log message in file and on console. Same way I tried doing for http transport also, the source cod for winston clien looks something like this :
var winston = require('winston');
var logger = new (winston.Logger)({
transports: [
new (winston.transports.Console)(),
new (winston.transports.Http)({ host: 'localhost', port:8080 })
]
});
logger.log('info', 'Hello world');
While runnign this code I get error like :
D:\Balwant\Devlopment-Env\LoggingDemo\node_modules\winston\lib\winston\transports\http.js:52
req = (self.ssl ? https : http).request({
^
ReferenceError: self is not defined
at Http._request (D:\Balwant\Devlopment- Env\LoggingDemo\node_modules\winston\lib\winston\transports\http.js:52:10)
at Http.log (D:\Balwant\Devlopment-Env\LoggingDemo\node_modules\winston\lib\winston\transports\http.js:109:8)
at emit (D:\Balwant\Devlopment-Env\LoggingDemo\node_modules\winston\lib\winston\logger.js:175:17)
at D:\Balwant\Devlopment-Env\LoggingDemo\node_modules\winston\node_modules\async\lib\async.js:111:13
at Array.forEach (native)
at _each (D:\Balwant\Devlopment-Env\LoggingDemo\node_modules\winston\node_modules\async\lib\async.js:32:24)
at Object.async.each (D:\Balwant\Devlopment-Env\LoggingDemo\node_modules\winston\node_modules\async\lib\async.js:110:9)
at Logger.log (D:\Balwant\Devlopment-Env\LoggingDemo\node_modules\winston\lib\winston\logger.js:203:9)
at Object.<anonymous> (D:\Balwant\Devlopment-Env\LoggingDemo\logger.js:10:8)
at Module._compile (module.js:456:26)
Since I'm new to node.js, I've no idea how to deal with it. I tried googling for solution but could not get any.
Plese help me.
Thanks
First winston and winstond are different packages. You can check this blog post about the difference.
You might also need to whip-up your own HTTP transport for winston (if you really want to use winston). So it can work with your specific endpoint protocol.
You can create your custom winston transport as specified here. Then you can use something like request to send the log data to your HTTP endpoint.
Good luck.
Web Transport
I don't believe winston.transports.Http exists but I think you're looking for this:
new winston.transports.Webhook({ 'host': 'localhost', 'port': 8080, 'path': '/collectdata' })
As shown in this example.
Winstond
My mistake, it does have winston.transports.Http but you'll need winstond.
You can check this example to use winstond as a http daemon. Then send your Http logs to it.
So this:
new winston.transports.Http({ host: 'localhost', port: 8080})
Should be pointing to a winstond daemon like:
var winstond = require('winstond');
var http = winstond.http.createServer({
services: ['collect', 'query', 'stream'],
port: 8080
});
http.add(winstond.transports.Console, {});
http.listen();
var winston = require('winston');
var logger = new (winston.Logger)({
transports: [
new (winston.transports.Console)({ json: false, timestamp: true }),
new winston.transports.File({ filename: __dirname + '/debug.log', json: false })
],
exceptionHandlers: [
new (winston.transports.Console)({ json: false, timestamp: true }),
new winston.transports.File({ filename: __dirname + '/exceptions.log', json: false })
],
exitOnError: false
});
module.exports = logger;
add this line were ever u wanted to lg the error message
var logger = require('../../config/logger.js');
logger.info("the default logger with my tricked out transports is rockin this module");
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.
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');