npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

instrumitter

v1.1.0

Published

Instrument your node.js code and emit data about what's happening

Downloads

8

Readme

Instrumitter

Build Status Coverage Status

Instrumitter makes it dead simple to instrument function calls and emit information about those calls so you can get insight into what is happening in your node.js application.

npm install instrumitter

Example

var instrumitter = require('instrumitter');
var httpEvents = instrumitter('http').watch('get')

// now we can listen for any time require('http').get is called
// and get information about its return value and callback value

httpEvents
    .on('get:return', function(fn) {
        console.log('http.get was called with', fn.arguments)
        console.log('http.get returned', fn.return.value, 'in', fn.return.elapsed, 'ms');
    })
    .on('get:callback', function(fn) {
        console.log('http.get calledback ', fn.callback.value, 'in', fn.callback.elapsed, 'ms');
    });

Usage

Instrumitter exposes a single function with the following signature:

instrumitter(object)

object is an object that has a function as a property (or properties) that we want to listen to. If object is a string, it will be treated as a path to require a module.

Methods

Once you have an instrumitter, you can call methods on it:

watch

myInstrumitter.watch(method1, method2, method3, ..., methodN)

The method names passed to watch are properties of the object for which the instrumitter was created. You can pass any number of arguments to watch. The value * as an argument will watch all properties of the object that are functions. The value . as an argument will watch the object itself (assuming it is a function).

watch returns the instrumitter it was called on, so it can be easily used in an assignment statement when setting up the instrumitter:

var httpEvents = instrumitter('http').watch('get', 'post')

NOTE: to directly watch a function the instrumitter must be created by passing the path to a module that exports the function.

on & once

For the most part, these events follow the EventEmitter spec, but allow passing options and listening to an event actually triggers additional work to be done in order to emit that event. Most notably, the :callback event causes the last function argument to be wrapped so that we can get the data that is passed to it.

myInstrumitter.on(event[, options], handler)
  • event: the methodName/eventName combo to watch (ex. get:return to watch the return event of the get method)
  • options: an optional options object
  • handler: the function to handle the event

Events

Instrumitter supports four events: invoke, return, callback, and promise. The data object that is emitted for the invoke event will be the same data object that is passed to subsequent events, but each event will add its own data to the object.

:invoke

invoke is emitted at the time that the function is called. At this point the emitted data looks like this:

{
    this,               // context the function was run in
    arguments           // arguments passed to the function
}

NOTE: To get the best measure of how long a function call takes, we do not capture the start time until after all handlers for the invoke event have finished

:return

return is emitted directly following the completion of the function call.
A return object will be added to the emitted data:

{
    this,               // context the function was run in
    arguments,          // arguments passed to the function
    time,               // time the function was invoked
    return: {
        value,          // return value
        error,          // error, if one was thrown
        time,           // time return was called
        elapsed     // time since the invocation of the function
    }
}

:callback

callback will be emitted when the callback to a function is called and will contain the following data:

{
    this,               // context the function was run in
    arguments,          // arguments passed to the function
    time,               // time the function was invoked
    return: {
        value,          // return value
        error,          // error, if one was thrown
        time,           // time return was called
        elapsed     // time since the invocation of the function
    },
    callback: {
        this,           // the context the callback was run in
        arguments,      // all arguments passed to the callback
        error,          // the first argument passed to the callback
        value,          // the second argument passed to the callback
        time,           // the time the callback was called
        elapsed,    // time since the invocation of the original function
    }
}

:promise

promise will be emitted when the promise returned from the function is resolved and will contain the following data:

{
    this,               // context the function was run in
    arguments,          // arguments passed to the function
    time,               // time the function was invoked
    return: {
        value,          // return value
        error,          // error, if one was thrown
        time,           // time return was called
        elapsed     // time since the invocation of the function
    },
    promise: {
        value,          // the resolved value of the promise
        error,          // error, if one was thrown
        time,           // the time the promise was resolved
        elapsed,    // time since the invocation of the original function
    }
}

Options

Adding Stack Traces

Because adding stack traces introduces a bit more overhead they are disabled by default. You can turn them on when you listen to your instrumitter by adding stack:true to an options object:

var httpEvents = instrumitter('http').watch('get');
httpEvents.on('get:return', { stack:true }, function(fn) {
    console.log(fn.stack)
})
{
    // ...
    stack:[{
        name,   // name of the function in the stack
        file,   // file in which the function resides
        line,   // file line number
        char    // line character position
    }],
    // ...
}

More Examples

Capturing the methods of a class that is exported by a module:

var instrumitter = require('instrumitter');
var FooEvents = instrumitter(require('./Foo').prototype).watch('bar')

FooEvents.on('bar:return', function(fn) {
    console.log(fn.return.value)
})

Capturing a function exported by a module:

var instrumitter = require('instrumitter');
var doSomethingEvents = instrumitter('./doSomething').watch('.')

doSomethingEvents.on(':return', function(fn) {
    console.log(fn.return.value)
})