Skip to content

Instantly share code, notes, and snippets.

@ludwig
Forked from transitive-bullshit/logger.js
Created August 25, 2016 10:10
Show Gist options
  • Select an option

  • Save ludwig/b47b5de4a4c53235825af3b4cef4869a to your computer and use it in GitHub Desktop.

Select an option

Save ludwig/b47b5de4a4c53235825af3b4cef4869a to your computer and use it in GitHub Desktop.

Revisions

  1. @transitive-bullshit transitive-bullshit revised this gist Oct 11, 2015. 1 changed file with 3 additions and 0 deletions.
    3 changes: 3 additions & 0 deletions logger.js
    Original file line number Diff line number Diff line change
    @@ -1,3 +1,6 @@
    // 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, '..')
  2. @transitive-bullshit transitive-bullshit created this gist Oct 11, 2015.
    84 changes: 84 additions & 0 deletions logger.js
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,84 @@
    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')
    }
    }
    }