For every logger statement with any level, I need to display the file name from where the log statement executed, below is the illustration I given below:
Example :
Below is the line executed from JobWork.js
logger.info("getInCompleteJobs in job works");
Actual :
2012-11-05T06:07:19.158Z - info: getInCompleteJobs in job works
Required :
2012-11-05T06:07:19.158Z - info JobWork.js : getInCompleteJobs in job works
Without passing the fileName as a parameter from the log statement it should give the filename.
You can use the stack trace information attached to v8's Error
object to find out what file/line your code was called from. This approach works well, but it does not perform well; so if you use it during development, you will want to disable it when you go to production.
So you could do something like this:
var logger_info_old = logger.info;
logger.info = function(msg) {
var fileAndLine = traceCaller(1);
return logger_info_old.call(this, fileAndLine + ":" + msg);
}
/**
* examines the call stack and returns a string indicating
* the file and line number of the n'th previous ancestor call.
* this works in chrome, and should work in nodejs as well.
*
* @param n : int (default: n=1) - the number of calls to trace up the
* stack from the current call. `n=0` gives you your current file/line.
* `n=1` gives the file/line that called you.
*/
function traceCaller(n) {
if( isNaN(n) || n<0) n=1;
n+=1;
var s = (new Error()).stack
, a=s.indexOf('\n',5);
while(n--) {
a=s.indexOf('\n',a+1);
if( a<0 ) { a=s.lastIndexOf('\n',s.length); break;}
}
b=s.indexOf('\n',a+1); if( b<0 ) b=s.length;
a=Math.max(s.lastIndexOf(' ',b), s.lastIndexOf('/',b));
b=s.lastIndexOf(':',b);
s=s.substring(a+1,b);
return s;
}
Looks like you're using Winston here - I typically pass module
into my logger module and then set Winston's label
property to a parsed version of module.filename
. Something like:
logger.js:
var path = require('path');
// Return the last folder name in the path and the calling
// module's filename.
var getLabel = function(callingModule) {
var parts = callingModule.filename.split(path.sep);
return path.join(parts[parts.length - 2], parts.pop());
};
module.exports = function(callingModule) {
return new winston.Logger({
transports: [new winston.transports.Console({
label: getLabel(callingModule)
})]
});
};
Usage (assume module is controllers/users.js
):
var logger = require('./logger')(module);
logger.info('foo');
Result:
2014-11-25T15:31:12.186Z - info: [controllers/users.js] foo
Assuming each file is a separate node process, you could use something like process.argv[1].match(/[\w-]+\.js/gi)[0]
If you are looking for something that will work in modules this might work:
process.mainModule.filename.match(/[\w-]+\.js/gi)[0]