Logging configuration in sailsjs - node.js

I've started to use sailsjs not long ago and really love it ! (I'm a previous rails lover).
Anyway, I do not find the documentation on how to configure the logger transport (I'd like my log to be written in a file within the logs folder, and also to remove the console transport).
Usually, when using winston I use something like:
// Add transport file
winston.add(winston.transports.File, {
filename: some_filename
});
// Handle exceptions
winston.handleExceptions(new winston.transports.File({
filename: another_filename
}));
As sails already wraps Winston, I'm not sure how to do it in a clean way. Any idea or pointer towards an example ?

Related

Is it possible to use winston logging and debug module together?

I use winston logging because I use its features like different logging levels, multiple transports, etc.
But I also like debug's namespace feature. Besides, express already uses it. So is it possible to use them together, e.g. to let winston logging have namespace?
After using several different loggers I gain more insight about nodejs loggers, now I believe they are not supposed to be used together b/c they are designed for different purposes. On the other hand, morgan and winston can be used together, e.g. Node.js - logging / Use morgan and winston, morgan and debug can be used together too, Nodejs - How to use morgan with debug
But first of all, to quote from Logging in Node.js done right
Setting up proper logging in Node.js applications can be bit
overwhelming at first due to the plethora of modules available through
NPM.
That was indeed my situation when I had morgan, winston, debug together. But then I realized they are for different purposes with overlaps. So I use debugjs when I really debug an issue instead of using console.log(some said debugjs is not a logger). After I am done with it I turn that debug off.
Morgan is to log express HTTP request specifically. Better to use it in dev/prod env for different purposes.
Using different log levels for Winston in dev/prod env is probably a common practice. I can also use express-winston to log HTTP request instead of using morgan.
Winston uses a different log level to turn off some log, unlike debugjs to use namespace to turn log off so I don't think they can work together.
--- update 2021 ---
Since I first answered my own question in 2018, I was asked several times about the log level related question. I found an issue opened against debugjs confirmed what I said about debug, to quote the answer from its current maintainer
Debug isn't a general purpose logging library, it's meant to
conditionally turn on debug logs. There is no concept of log levels.
Instead, break up your namespaces into different components and enable
the ones you care about
It can be useful to start passing debug(...) calls into winston. You can override the debug.log function to achieve that.
const logger = require('./v1/lib/logger'); //my winston logger
const util = require('util');
const debug = require('debug');
//for testing and dev use the regular debug (optional)
if (process.env.NODE_ENV === 'production') {
debug.log = (...args) => logger.info(util.format(...args))
}
module.exports = debug;
When dealing with debug and winston, you may also want to override formatArgs function, since debug.log is receiving already colored arguments (depending on enviroment) and it may have unexpected results in some cases (e.g. setting env vs module loading order).
import debug from "debug";
import util from "util";
import winston from "winston";
// create winston logger
const logger = new winston.Logger({ /*...*/ });
// keep original arguments
debug.formatArgs = (args) => { /* do nothing */ };
// override logging (keep function to use `this`)
debug.log = function(...args) {
// log to winston
logger.log("info", {
// `this` is bound to debug instance
namespace: this.namespace,
// format as in `console.log`
message: util.format(...args),
// add message time
timestamp: new Date().toISOString(),
// optionally log also diff time
diff: '+' + debug.humanize(this.diff),
});
};
// enable all debug
debug.enable('*');

Transport Settings in Socket.IO 1.4.x

I have been tinkering with deployd on Heroku using this gist as a starting point:
https://gist.github.com/facultymatt/5373247
Line 20 of that server.js tries to set transports for socket.io like so:
server.sockets.manager.settings.transports = ["xhr-polling"];
But encounters this error:
Cannot read property 'settings' of undefined.
From research so far it seems this approach is deprecated in socket.io 1.4.5. However, if that's so I am not clear on how I should address this setting.
My question is similar to this one. But differs in that I seek to change the settings once socket.io is already constructed by and attached to an instance of deployd.
Set it on creation:
var server = deployd({
socketIo: {
options: { transports : ['xhr-polling'] }
}
});
Or if you can't do that, change it runtime (this is a hack):
server.sockets.server.eio.transports = ['xhr-polling'];
(This is still supported for backwards compatibility:)
server.sockets.server.set('transports', ['xhr-polling']);

No entries in log file when using logging library

I do not know exactly if this is a issue resolving around forever or the libraries I tried but maybe someone can help here.
I was using console.log() through my application (express) to write logs. Now I've switched to a more feature packed logging library, namely Winston.js. Configured winston like this:
var winston = require('winston');
winston.remove(winston.transports.Console);
winston.add(winston.transports.Console, {timestamp: true});
and replaced my console.log() entries with winston.info/winston.error, you name it. After I launched my app with node app.js everything went as expected. So I tried to run it with forever, since in production I run it that way.
Now I encountered the problem that the whole log file from forever, using just forever start app.js, was empty. Not a single log entry was there.
I replaced winston with log4js, but the log file remained empty when launching it with forever.
Is there anything I am missing right now and if so where is the problem?
Sincerly,
cschaeffler
It looks like you simply kept the Console transport without adding a transport for a file, e.g.,
winston.add(winston.transports.File, { filename: 'somefile.log' });

Viewing node console log remotely

I have been building my first node app. In testing on my mac, I was able to view the console log output using terminal.
I'm now moving the app to a server but I still want to get a live dump of the console log. Yes, I can get this by SSH'ing into the server - start the app then watch the output. But, say my SSH connection to the server gets disconnected. After re-connecting to the server, how do I go about viewing the terminal output of that process?
One solution I came across was http://console.re - this looks ideal, however it comes with warnings not to use in a production environment. Coupled with the fact that it's public, I'm hesitant to use it.
Does anyone know of an alternative solution similar to console.re?
Thanks
You could try using a custom function that writes the output to a log file, as well as printing it on screen.
Something like this: (note that this won't accept multiple arguments)
var fs = require('fs');
module.exports = function(text) {
fs.writeFile('console.log', text, {
flag: 'a' // append
}, function(){}); // ignore the response
console.log(text);
};
Perhaps screen, tmux, or similar software might work for you.

How do I log Socket.io through Winston?

I would like to use Winston as logger for Socket.io. I have seen this issue where it says:
var io = require('socket.io').listen(8080);
io.set('logger', { debug: <log function>, info: … , error: .., warn: .. })
Unfortunately, it is not described what the log function should look like.
Some playing around and a look into the Socket.io logger documentation told me that there is no fixed set of parameters: There are log messages with one, two and three parameters. Perhaps there are even more, I don't know.
I think that this is definitely not a good practice to have an undefined number of parameters, especially if this is your interface to external components.
Anyway ... does anybody have some experience with this? Can anyone point out what to watch out for?
This seems to work fine for me
var io = require('socket.io').listen(server, {
logger: {
debug: winston.debug,
info: winston.info,
error: winston.error,
warn: winston.warn
}
});
As a bonus, by setting the logger in the same call as .listen(), you catch all the log output from Socket.IO. Note that you should be able to just pass winston instead of that object, but it isn't working for me, so that's why I've posted this solution instead.
Since socket.io v1.0 logger parameter does not longer work.
They switched to debug
You may refer to this issue on how to setup Winston with socket.io
You can simply plug in the winston instance as the logger object:
var winston = require('winston');
io.set('logger', winston);

Resources