toolbag
is a collection of tooling intended to be preloaded in a Node application. The tooling (heapdumps, CPU profiling, runtime metrics reporting, etc.) runs within an application's Node process. By utilizing preloading, toolbag
does not require any modifications to existing application code. For example, if you normally start your application with the command node app.js
, then your command would become:
node -r toolbag app.js
toolbag
exposes two interfaces. The first is the reporting interface, which is used to send runtime data to zero or more destinations. Analytics, logging, and similar types of systems represent the intended use cases of the reporting interface.
The second interface is the command interface. This interface allows a Node process to define commands which can be remotely invoked by a command server. This interface is intended to take heapdumps, collect CPU profiles, send signals to a running process, etc.
toolbag
doesn't provide much functionality out of the box. However, it supports a plugin system for adding features. All reporters and command interface implementations are written as plugins. This allows toolbag
to remain extremely simple, yet flexible enough to work with a variety of systems. For example, a WebSocket- or IPC-based command interface can be mixed and matched with HTTP or UDP reporters, without requiring any changes to toolbag
itself.
toolbag
is configured via a JavaScript file that is require()
'ed at runtime. This file can be specified in exactly one of two ways:
- By adding a
.toolbagrc.js
file to your project's working directory. - By specifying a
TOOLBAG_PATH
environment variable. This takes precedence over a local.toolbagrc.js
file.
The configuration file should export a single function whose signature is configure (defaults, callback)
. defaults
contain the default configuration values set by toolbag
. callback
is a function with the signature callback (err, config)
. err
represents any error that might have occurred. config
is an object that will be applied to defaults
. The config
object should adhere to the following schema.
errors
(object) - Defines howtoolbag
errors are handled. Becausetoolbag
is preloaded, normal applications are unable to handle any errors that may occur. These settings allowtoolbag
users to define an error handling policy. Theerrors
object has the following schema.policy
(string) - Defines the error handling policy. Can be one of the following strings.swallow
- Errors are discarded.log
- Prints the error message tostderr
. This is the default.log-verbose
- Prints the error message and stack trace tostderr
.throw
- Throws the error.terminate
- Prints the error message and stack trace tostderr
then callsprocess.exit(1)
.
data
(object) - Information regarding any persistent storage required bytoolbag
.path
(string) - The directory where files (such as heapdumps) are stored. Defaults to atoolbag
directory in the system's temp directory.
plugins
(array of objects) - An array oftoolbag
plugins to register. Each plugin object follows the following schema.plugin
(object) - The plugin being registered. This should be the result ofrequire()
.options
(object) - An optional object that is used to pass any plugin specific configuration options.
Note: A number of plugins are provided in the toolbag-plugins
, as shown in the following example. In the future, toolbag-plugins
will be split up into a number of standalone npm modules.
'use strict';
const ToolbagPlugins = require('toolbag-plugins');
module.exports = function config (defaults, callback) {
callback(null, {
errors: {
policy: 'log'
},
plugins: [
{
plugin: ToolbagPlugins.BorlandCommander,
options: {
host: 'http://localhost:5000'
}
},
{
plugin: ToolbagPlugins.HttpReporter,
options: {
id: 'http reporter',
method: 'POST',
url: 'http://localhost:5000/report',
options: {}
}
},
{
plugin: ToolbagPlugins.UdpReporter,
options: {
id: 'udp reporter',
socketType: 'udp4',
port: 5001,
host: 'localhost'
}
},
{
plugin: ToolbagPlugins.Getfile,
options: defaults.data
},
{
plugin: ToolbagPlugins.Heapdump,
options: defaults.data
},
{
plugin: ToolbagPlugins.Profiler,
options: defaults.data
},
{ plugin: ToolbagPlugins.Signal },
{
plugin: ToolbagPlugins.StatsCollector,
options: {
enabled: true,
period: 1000,
eventLoopLimit: 30,
features: {
process: true,
system: true,
cpu: true,
memory: true,
gc: true,
handles: true,
requests: true,
eventLoop: true,
meta: {
tags: ['api']
}
}
}
},
{
plugin: ToolbagPlugins.Policy,
options: {
blacklist: {
modules: {
fs: 'log'
},
bindings: {
natives: 'log-verbose'
}
}
}
}
]
});
};
The command server is not mandatory, and is only required if you plan to use the command interface. As the command interface is defined via plugin, there is no predefined command server implementation. Instead command interface plugins should be developed in conjunction with a compatible server. An example is the borland
hapi server plugin, and the borland commander plugin shown in the example .toolbagrc.js
file.
This section documents the APIs used to create toolbag
plugins.
The manager responsible for general orchestration in toolbag
. The manager registers plugins, implements the application's error policy, and handles other important tasks. Plugins are not expected to construct new instances of Manager
. Instead, they should interact with the existing manager
instance that is provided to them. Manager
is an instance of EventEmitter
.
- Arguments
name
(string) - The name of the command being registered.fn (options, callback)
(function) - A function implementing the command being registered.options
is an object used to pass parameters to the command.callback ([err[, results]])
is used to pass an error or results from the command. Iferr
is provided, it is sent back to the command server usingclient.respond()
. Iferr
is falsey, andresults
is provided, then it is sent back as the response.
- Returns
- Nothing
This method is used to register commands that can be used with the command interface.
- Arguments
- None
- Returns
- Array of strings
Returns an array of all commands supported by the manager.
- Arguments
plugins
(object or array of objects) - An object or array of objects representingtoolbag
plugins.callback (err)
(function) - An optional function that is called once registration is complete.err
represents any errors that may have occurred.
- Returns
- Nothing
This method registers one or more plugins. If no errors occur during registration, the manager will emit a 'register'
event.
- Arguments
message
(object) - An object encapsulating a command from the command server. The object should adhere to the following schema.command
(string) - The name of the command to execute.options
(object) - Options passed to the command.
callback (err)
(function) - An optional function that is called on completion.err
represents any errors that may have occurred.
- Returns
- Nothing
When a command is received on the command interface, it is passed to execute()
. This method is responsible for running the command and sending any responses back to the server.
- Arguments
err
(object) - An error object to process.
- Returns
- Nothing
This method is used to process toolbag
errors. Because toolbag
is preloaded, and not part of the user's application, error()
is configurable. For example, in some applications, error()
is configured to swallow errors, while other applications may choose to exit on error.
- Arguments
policy
(string) - The error handler to retrieve.
- Returns
- Function or
undefined
- Function or
Returns the error handling function associated with the name policy
. If no error handler is defined for policy
, then undefined
is returned.
- Arguments
policy
(string) - The error handler to use.
- Returns
- Nothing
Sets error()
to the handler associated with policy
. If no error handler is defined for policy
, a TypeError
is thrown.
- Arguments
policy
(string) - The name of the error handling policy being defined.handler
(function) - The error handler function. This function should accept a single argument that represents the error being handled.
- Returns
- Nothing
Defines a new error handling policy named policy
. If a policy with this name already exists, it is overwritten. Note that this function only defines the error policy, it does not set it as the default policy.
The Client
object is responsible for interacting with the command and reporting interfaces. Plugins are not expected to construct new instances of Client
. Instead, they should interact with the existing manager.client
instance.
- Arguments
commander
(object) - An object that supports the command interface API.
- Returns
- Nothing
Sets up the command interface using commander
.
- Arguments
reporter
(object) - An object that supports the reporter API.
- Returns
- Nothing
Adds reporter
as a reporter.
- Arguments
callback (err)
(function) - Optional function that is invoked once connection is complete.err
represents any error that may have occurred.
- Returns
- Nothing
This method is used to establish a connection to the command server. If the command interface is configured during startup, toolbag
will call this method after all plugins have been registered. If this method is called, and the command interface has not been configured, then an error will be passed to callback()
.
- Arguments
message
(variable) - Data to send to the command server. If a non-string was passed in, it will be stringified before being passed on.callback (err)
(function) - Optional function that is invoked after responding is complete.err
represents any error that may have occurred.
- Returns
- Nothing
This method is used to respond to the command server after receiving and executing a command. If the command interface has not been configured, an error is passed to callback()
.
- Arguments
message
(variable) - Data to send via all attached reporters. If a non-string is passed in, it will be stringified before being passed on to the reporters.callback (err)
(function) - Optional function that is invoked after reporting is complete.err
represents any error that may have occurred.
- Returns
- Nothing
Sends data to all configured reporter destinations.
All plugins must be capable of being imported into an application via require()
. This means that plugins can easily be published to npm. Each plugin must expose a register()
function that toolbag
will invoke during plugin registration.
- Arguments
manager
(object) - An instance ofManager
.options
(variable) - Optional configuration data passed to the plugin.callback (err)
(function) - Invoked once registration is complete.err
represents any error that may have occurred.
- Returns
- Nothing
A reporter can be added by calling manager.client.addReporter(reporter)
, typically from within a plugin's register()
function. Any number of reporters can be added, but keep in mind that excessive reporting can potentially affect application performance.
- Arguments
message
(string) - Message passed to the reporter fromclient.report()
. If a non-string was passed toclient.report()
, it will be stringified before being passed on to this method.callback (err)
(function) - Invoked after reporting is complete.err
represents any error that may have occurred.
- Returns
- Nothing
All reporters must have a report()
method. When client.report()
is called, each reporter's report()
method is called. This method is responsible for passing message
to its destination.
toolbag
supports a single command interface, which is setup by calling manager.client.setCommander(commander)
. Implementers of the command interface must minimally define connect()
and respond()
methods.
- Arguments
manager
(object) - An instance ofManager
.callback (err)
(function) - Invoked once connection is complete.err
represents any error that may have occurred.
- Returns
- Nothing
This method is used to establish a connection to the command server. If the command interface is configured during startup, toolbag
will call this method after all plugins have been registered.
- Arguments
message
(string) - Message passed to the command interface fromclient.respond()
. If a non-string was passed toclient.respond()
, it will be stringified before being passed on to this method.callback (err)
(function) - Invoked after responding is complete.err
represents any error that may have occurred.
- Returns
- Nothing
This method is used to respond to the command server after receiving and executing a command.