0.4.0 • Published 6 years ago

perf-agent v0.4.0

Weekly downloads
6
License
MIT
Repository
github
Last release
6 years ago

Perf Agent

An agent designed to give insight into the performance of your node.js code.

Perf Agent uses async_hooks to observe the duration of each synchronous block of code. To gain further insight, Perf Agent allows for the collection of deep asynchronous stack traces.

When asynchronous stack traces are enabled, it is also possible to use the agent as an alternative to Error.captureStackTrace in order to see the full, asynchronous call stack leading up to an event.

Example

const agent = new PerfAgent({
    captureAsyncStackTraces: true,
    threshold: 100, // Trigger events if a block exceeds 100ms
});

agent.onBlocked(e => {
    // e.duration will be the number of nanoseconds elapsed in a synchronous block
    // e.stacks is an array of arrays of Frame objects
    // e.stacks[0][0] is the Frame that *triggered* the block that exceeded the threshold
    console.log(e.toString()); // Log the event which will include a deep stack trace
});
agent.start(); // The agent must be explicitly started

Here's what a deep stack trace might look like (from the tests). The lines beginning with an arrow represent distinct asynchronous contexts. Below you can see that two Promise resolution handlers were invoked on the same line and that the 2nd blocked for 101ms.

Slow synchronous block (101ms):
--> Promise.then (<anonymous>)
    it (/Users/ggoodman/Projects/experiments/perf-agent/test/stack_traces.js:46:52)
    Immediate.setImmediate [as _onImmediate] (/Users/ggoodman/Projects/experiments/perf-agent/node_modules/lab/lib/runner.js:597:31)
    runCallback (timers.js:810:20)
    tryOnImmediate (timers.js:768:5)
    processImmediate [as _immediateCallback] (timers.js:745:5)
--> Promise.then (<anonymous>)
    it (/Users/ggoodman/Projects/experiments/perf-agent/test/stack_traces.js:46:32)
    Immediate.setImmediate [as _onImmediate] (/Users/ggoodman/Projects/experiments/perf-agent/node_modules/lab/lib/runner.js:597:31)
    runCallback (timers.js:810:20)
    tryOnImmediate (timers.js:768:5)
    processImmediate [as _immediateCallback] (timers.js:745:5)

API

PerfAgent

const { PerfAgent } = require('perf-agent');

An instance of the perf agent.

new PerfAgent(options): create a new PerfAgent instance where options must be an object having:

  • captureAsyncStackTraces?: boolean whether asynchronous stack traces should be collected. There can be a major performance impact in collecting these.
  • threshold: number the threshold in milliseconds above which BlockedEvents will be triggered

.start(): start capturing async stack traces (if enabled) and observing for slow synchronous blocks.

.stop(): stop capturing async stack traces (if enabled) and observing for slow synchronous blocks.

.captureStackTrace(receiver, callsite): capture a stack trace (which may be augmented with asynchronous frames, if enabled), similar to Error.captureStackTrace.

.executeWithoutTracing(cb): execute the provided callback function such that it (and it's continuations) will not be traced.

.onBlocked(cb): register a callback that will be invoked when a synchronous block exceeds the configured threshold where:

  • cb: (event: BlockedEvent): void

Returns a Disposable whose .dispose() method can be invoked to unregister the callback.

.setUseAsyncStackTraces(enabled): toggle the collection of async stack traces where:

  • enabled: boolean whether async stack traces should be collected.

Note: when enabled, any pre-existing asynchronous contexts will have empty stacks. In other words, retroactive collection is not possible.

BlockedEvent

BlockedEvent represents the data collected about a slow synchronous block.

.duration: number: The number of nanoseconds elapsed while executing the block.

.stacks: Frame[][]: An array of stack traces where each element in the top-level array represents a synchronous block's stack trace.

Stacks and their elements are ordered such that the newest events are first.

You can think of each element in the top-level array as being a logical consequence of the previous element.

.toString(): Generate a string representation of the event.

Frame

Frame represents a function invocation in a stack trace. It is a simplified version of a NodeJS.CallSite object whose objective is to reduce the memory pressure associated with collecting many such objects.

.columnNumber: number

.fileName: string

.functionName: string

.isConstructor: readonly boolean

.isEval: readonly boolean

.isNative: readonly boolean

.isToplevel: readonly boolean

.lineNumber: number

.methodName: string

.typeName: string

0.4.0

6 years ago

0.3.1

6 years ago

0.3.0

6 years ago

0.2.0

6 years ago

0.1.0

6 years ago