Intercept console.log messages with EventEmitter


#1

Hello everybody,
I’m working on some mechanism to collect all the console messages into a variable. This kind of behaviour should be limited to the lifespan of some function.

I’m using the EventEmitter to signal the beginning and the execution of the target function:

# in the function module/class
onWillComputeStuff: (callback) ->
  @emitter.on 'will-compute-stuff', callback

onDidComputeStuff: (callback) ->
  @emitter.on 'did-compute-stuff', callback

doYourThing: () ->
  @emitter.emit 'will-compute-stuff'
  # here I do all my awesome stuff
  console.log 'this should be catch!'
  @emitter.emit 'did-compute-stuff'

What I do when I use this module is:

startConsoleIntercept: () ->
  @oldConsole = console.log
  newConsole = (message) =>
    @capturedConsole += 'woow!'
  console.log = newConsole

stopConsoleIntercept: () ->
  console.log = @oldConsole

...

@subscriptions.add @emitterModule.onWillComputeStuff @startConsoleIntercept
@subscriptions.add @emitterModule.onDidComputeStuff @stopConsoleIntercept

Unfortunately, this code does not seem to work. The @capturedConsole variable is empty when my execution is done.

I also tried with some packages for stdout redirections, such as this one, but they just have the same behaviour.

Has anyone worked with console.log in Atom before?
Cheerio!


#2

There shouldn’t be anything wrong with console.log, but it is possible that newConsole captures the wrong this variable.
There is probably a @emitterModule.emitter.constructor.capturedConsole='undefinedwoow!' because callback functions run inside the Emitter's constructor.

Fix:

@subscriptions.add @emitterModule.onWillComputeStuff @startConsoleIntercept.bind(this)
@subscriptions.add @emitterModule.onDidComputeStuff @stopConsoleIntercept.bind(this)
# or
@subscriptions.add @emitterModule.onWillComputeStuff => @startConsoleIntercept()
@subscriptions.add @emitterModule.onDidComputeStuff => @stopConsoleIntercept()

#3

Thank you very much, I’ll give it a try but I think that’s the way to go.

Cheerio!