Skip to content

Instantly share code, notes, and snippets.

@transitive-bullshit
Last active July 9, 2024 04:09
Show Gist options
  • Select an option

  • Save transitive-bullshit/39a7edc77c422cbf8a18 to your computer and use it in GitHub Desktop.

Select an option

Save transitive-bullshit/39a7edc77c422cbf8a18 to your computer and use it in GitHub Desktop.
winston logger with filename:linenumber
// NOTE: this adds a filename and line number to winston's output
// Example output: 'info (routes/index.js:34) GET 200 /index'
var winston = require('winston')
var path = require('path')
var PROJECT_ROOT = path.join(__dirname, '..')
var logger = new winston.logger({ ... })
// this allows winston to handle output from express' morgan middleware
logger.stream = {
write: function (message) {
logger.info(message)
}
}
// A custom logger interface that wraps winston, making it easy to instrument
// code and still possible to replace winston in the future.
module.exports.debug = module.exports.log = function () {
logger.debug.apply(logger, formatLogArguments(arguments))
}
module.exports.info = function () {
logger.info.apply(logger, formatLogArguments(arguments))
}
module.exports.warn = function () {
logger.warn.apply(logger, formatLogArguments(arguments))
}
module.exports.error = function () {
logger.error.apply(logger, formatLogArguments(arguments))
}
module.exports.stream = logger.stream
/**
* Attempts to add file and line number info to the given log arguments.
*/
function formatLogArguments (args) {
args = Array.prototype.slice.call(args)
var stackInfo = getStackInfo(1)
if (stackInfo) {
// get file path relative to project root
var calleeStr = '(' + stackInfo.relativePath + ':' + stackInfo.line + ')'
if (typeof (args[0]) === 'string') {
args[0] = calleeStr + ' ' + args[0]
} else {
args.unshift(calleeStr)
}
}
return args
}
/**
* Parses and returns info about the call stack at the given index.
*/
function getStackInfo (stackIndex) {
// get call stack, and analyze it
// get all file, method, and line numbers
var stacklist = (new Error()).stack.split('\n').slice(3)
// stack trace format:
// http://code.google.com/p/v8/wiki/JavaScriptStackTraceApi
// do not remove the regex expresses to outside of this method (due to a BUG in node.js)
var stackReg = /at\s+(.*)\s+\((.*):(\d*):(\d*)\)/gi
var stackReg2 = /at\s+()(.*):(\d*):(\d*)/gi
var s = stacklist[stackIndex] || stacklist[0]
var sp = stackReg.exec(s) || stackReg2.exec(s)
if (sp && sp.length === 5) {
return {
method: sp[1],
relativePath: path.relative(PROJECT_ROOT, sp[2]),
line: sp[3],
pos: sp[4],
file: path.basename(sp[2]),
stack: stacklist.join('\n')
}
}
}
@zach-yu
Copy link
Copy Markdown

zach-yu commented Nov 27, 2015

thanks fisch. there is a little typo on line 8 "new winston.logger", logger should be capitalized

@znida
Copy link
Copy Markdown

znida commented Jun 27, 2016

Thanks Fisch. But somehow this code is not working for me and I'm getting this error. Can you help please?

"stack": [
    "RangeError: Maximum call stack size exceeded",
    "    at formatLogArguments (/opt/pg/bin/rest_gateway/pg_logging.js:90:32)",
    "    at module.exports.debug (/opt/pg/bin/rest_gateway/pg_logging.js:83:30)",
    "    at module.exports.debug (/opt/pg/bin/rest_gateway/pg_logging.js:83:16)",
    "    at module.exports.debug (/opt/pg/bin/rest_gateway/pg_logging.js:83:16)",
    "    at module.exports.debug (/opt/pg/bin/rest_gateway/pg_logging.js:83:16)",
    "    at module.exports.debug (/opt/pg/bin/rest_gateway/pg_logging.js:83:16)",
    "    at module.exports.debug (/opt/pg/bin/rest_gateway/pg_logging.js:83:16)",
    "    at module.exports.debug (/opt/pg/bin/rest_gateway/pg_logging.js:83:16)",
    "    at module.exports.debug (/opt/pg/bin/rest_gateway/pg_logging.js:83:16)",
    "    at module.exports.debug (/opt/pg/bin/rest_gateway/pg_logging.js:83:16)"
  ],
  "level": "error",
  "message": "uncaughtException: Maximum call stack size exceeded"
}

I get these error when I add this part of code:

module.exports.debug = module.exports.log = function () {
  logger.debug.apply(logger, formatLogArguments(arguments))
}

module.exports.info = function () {
  logger.info.apply(logger, formatLogArguments(arguments))
}

module.exports.warn = function () {
  logger.warn.apply(logger, formatLogArguments(arguments))
}

module.exports.error = function () {
  logger.error.apply(logger, formatLogArguments(arguments))
}


@madsri2
Copy link
Copy Markdown

madsri2 commented Dec 15, 2016

This was very helpful! Thanks. I restricted the stacktrace to 5 to prevent having to load the entire stack trace.

@akay-10
Copy link
Copy Markdown

akay-10 commented Feb 18, 2024

Is there a way, in which I can use EJS syntax for exporting the logger.* functions ?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment