Skip to content

Instantly share code, notes, and snippets.

@tjanczuk
Last active September 14, 2015 18:01
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 tjanczuk/0a26aa60a43b6ed2d32f to your computer and use it in GitHub Desktop.
Save tjanczuk/0a26aa60a43b6ed2d32f to your computer and use it in GitHub Desktop.
Per-request webtask logs

How to capture per-request webtask logs

Suppose the user has authored the following Node.js function. You want to execute it in webtasks while capturing the output generated by console.log calls within that function:

function (param, callback) {
  console.log('In my custom function. Parameter is:', param);
  callback(null, { hello: 'world' });
}

The code you need to send for execution to webtasks must wrap this user supplied code in the following way:

var util = require('util');

module.exports = function (ctx, cb) {
  
  // Intercept implementation of `console.log` so that it is within the scope 
  // of the user function invocation below.
  
  var console = {
      log: function () {
          console._stdout.push(util.format.apply(global, arguments));
          global.console.log.apply(global, arguments);
      },
      _stdout: []
  };

  for (var i in global.console)
      if (!console[i])
          console[i] = global.console[i];
  
   // Initialize param to whatever input you need to pass to the custom 
   // function, possibly based on the value of `ctx`.
   
  var param = {};
  
  // Call the user supplied function. The newly created console will be 
  // in its scope. In addition, intercept the callback to post-process 
  // results and capture logs.
  
  (
    // This is the code of user supplied function, embedded verbatim
    function (param, callback) {
      console.log('In my custom function. Parameter is:', param);
      callback(null, { hello: 'world' });
    }
  )(param, function (error, data) {
    var ret = {
        stdout: console._stdout
    };
    if (error) {
        ret.error = error.message || error.toString();
    }
    else {
      ret.data = data;
    }
    cb(null, ret);
  });
}

Given this wrapper above, every time the custom function completes by calling its callback (regardless if with error or a response value), the webtaks code will return a JSON object formatted as follows:

// In case of a successful completion:

{ 
  stdout: [], // array of strings representing `console.log` calls
  data: ... // whatever JSON-serializable entity custom code passed 
            // as the second parameter to the callback
}

// In case of completion with an error (error passed to callback function):

{
  stdout: [], // array of strings representing `console.log` calls
  error: 'some string' // the error
}

The wrapper preamble that formats input parameters to the custom function as well as the callback wrapper may of course be fine-tuned to pass in and respond with a different result, but this snippet hopefully illustares the core idea.

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