Skip to content

Instantly share code, notes, and snippets.

@huafu
Created October 21, 2014 15:46
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save huafu/21e32cb673ee0d073573 to your computer and use it in GitHub Desktop.
Save huafu/21e32cb673ee0d073573 to your computer and use it in GitHub Desktop.
Very simple logger to instrument objects and methods
logger =
_anonymousIndex: 0
guessMethodName: (method) ->
unless (res = (->).toString.call(method).match(/function([^\(]*)/)[1].replace(/(^\s+|\s+)$/g, ''))
res = logger.autoNamespace()
res
autoNamespace: ->
"[anonymous##{ ++logger._anonymousIndex }]"
instrumentMethod: (method, name = logger.guessMethodName(method)) ->
name = name.replace /\.prototype\./g, '#'
console.log "[logger] instrumenting method #{ name }..."
newMethod = ->
isNew = @constructor is newMethod
arrow = if isNew then '== new ==' else '== ( ) =='
console.log "[logger] =#{ arrow }> entering #{ name }"
try
res = method.apply @, arguments
catch err
console.warn "[logger] !! #{ name } threw #{ err }"
err.captureStackTrace()
throw err
console.log "[logger] <#{ arrow }= exiting #{ name }"
res
newMethod.prototype = method.prototype
for own k, v of method
newMethod[k] = v
newMethod
instrumentObject: (object, namespace = logger.autoNamespace()) ->
for own k, v of object when typeof v is 'function'
object[k] = @instrumentMethod v, "#{ namespace }.#{ k }"
@
module.exports = logger
@huafu
Copy link
Author

huafu commented Oct 21, 2014

I was having hard time finding where was happening a silent error in some async workflow so I wrote this, maybe it could be useful for someone else so here it is.

The goal is to instrument existing classes, objects and methods so that it logs when it enter the method, exit it and when an error is triggered by it:

// require('coffee-script/register');
var logger = require('/path/to/logger');

logger.instrumentObject(PassportConnection.prototype, 'PassportConnection.prototype');

second argument is strongly recommended to have easy reading output.

then you get something like that in the console:

[logger] === ( ) ==> entering PassportConnection#parseQuery
[logger] <== ( ) === exiting PassportConnection#parseQuery
[logger] === ( ) ==> entering PassportConnection#lookupPassportRecord
[logger] <== ( ) === exiting PassportConnection#lookupPassportRecord
[logger] === ( ) ==> entering PassportConnection#createUserRecord
[logger] <== ( ) === exiting PassportConnection#createUserRecord
...

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