Is it possible to use winston logging and debug module together? - node.js

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('*');

Related

The Bunyan log is not sent before process.exit

Today I ran into a problem in the #google-cloud/logging-bunyan extension for bunyan. The problem is that it is not able to send the log when there is an exit right after.
Example:
logger.fatal({
[LOGGING_TRACE_KEY]: e.stack
}, e.message)
process.exit(1)
Does anyone know what is going on here?
Please check if your plugin was properly installed.
I have found the following guide, Using Bunyan that may help you with your issue.
You will find this example at the end of this page:
'use strict';
// [START logging_bunyan_quickstart]
const bunyan = require('bunyan');
// Imports the Google Cloud client library for Bunyan
const {LoggingBunyan} = require('#google-cloud/logging-bunyan');
// Creates a Bunyan Stackdriver Logging client
const loggingBunyan = new LoggingBunyan();
// Create a Bunyan logger that streams to Stackdriver Logging
// Logs will be written to: "projects/YOUR_PROJECT_ID/logs/bunyan_log"
const logger = bunyan.createLogger({
// The JSON payload of the log as it appears in Stackdriver Logging
// will contain "name": "my-service"
name: 'my-service',
streams: [
// Log to the console at 'info' and above
{stream: process.stdout, level: 'info'},
// And log to Stackdriver Logging, logging at 'info' and above
loggingBunyan.stream('info'),
],
});
// Writes some log entries
logger.error('warp nacelles offline');
logger.info('shields at 99%');
// [END logging_bunyan_quickstart]
Also, please check this link as reference.
On the other hand, I recommend you to review the following guides on asking questions: How do I ask a good question? and How to create a Minimal, Complete, and Verifiable example in order to provide a better context on what you are doing and what you want to achieve.

Configure custom winston logging transport in sails

How can I configure winston in sails to use a mongodb transport?
This seems to be on the right track, but with a different transport.
https://groups.google.com/forum/#!topic/sailsjs/67u7SqzsNJQ
Here is my present config, modeled on that:
http://pastebin.com/SNJxBNak
Sails automatically runs any functions that a config file exports, right?
The function notify() doesn't seem to be running.
I am new to sails and hating it.
I was also facing the same issue and I tried extending this one Sailsjs - Custom Logging with Winston
After extending above link, the working solution:
Create a new js file inside a config folder(code inside of this will be executed automatically by sails) and add mongodb transports as below,
var winston = require('winston');
var MongoDB = require('winston-mongodb').MongoDB;
var customLogger = new(winston.Logger)({
transports: [
new(winston.transports.MongoDB)({
db: 'mongodb://localhost:27017/test',
collection: 'logs',
level: 'debug'
})
]
});
module.exports.logging = {
colors: false, // To get clean logs without prefixes or color codings
custom: customLogger
};
And use it anywhere like
sails.config.logging.custom.debug("winston mongodb transport logging");

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' });

Logging configuration in sailsjs

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 ?

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