report-toolkit Configuration
report-toolkit’s behavior can be controlled via configuration file. This document serves as both a guide and configuration file format reference.
- Do I Need a Configuration File?
- Configuration File Location and Naming
- Configuration File Format
- Configuration By Example
- Configuration File Reference
Do I Need a Configuration File?
In general, you only need a configuration file if one of the following statements is true:
- You want to customize the behavior of built-in rules when using
inspect
. - You want to use a custom rule with
inspect
. - You want to configure one or more commands to always use a particular option (unless overridden by command-line flags).
- You want to configure alternative transformer defaults.
If you have answered “no” to all of the above, then you don’t need a configuration file. Come back to this page if you ever do!
Configuration File Location and Naming
Unless given an explicit filepath to a configuration file, rtk
will search for a configuration file. This section describes recommended locations (depending on use-case), and the places in which it will otherwise search.
Recommended Locations
For a configuration specific to a project, the recommended location is in the project root as .rtkrc.js
, alongside package.json
and your other dotfiles. Keep the configuration under version control.
For a configuration at the system level, the recommended location is the user’s home directory in $HOME/.rtkrc.js
. The “user”, in this case, is the user executing rtk
; this is not the owner of the process which generated the Diagnostic Report file!
Configuration Search Paths
In addition to the recommended locations, report-toolkit will search for a configuration file named .rtkrc.js
(preferred) or rtk.config.js
in the following order, choosing the first found:
- The current working directory
- The parent of the current working directory, and the grandparent, all the way up to the user’s
$HOME
directory or the filesystem root (whichever comes first) - The user’s
$HOME
directory, if it is not an ancestor of the current working directory - The subdirectory
etc/
of the result ofnpm config prefix get
(e.g.,/usr/local/etc
or$HOME/.nvm/versions/node/(version)/etc
) - (If on a POSIX OS)
$XDG_CONFIG_HOME
and$XDG_CONFIG_DIRS
- (If on a POSIX OS)
/etc
Remember, if none of the above work for your use-case, you can always specify an explicit filepath.
Configuration File Format
Many tools allow configuration in different file formats, including JSON, YAML, and JavaScript. report-toolkit is not such a tool.
report-toolkit configuration files are JavaScript only.
There are benefits and drawbacks to this approach, of course, but choosing JavaScript means more power for the user, and easier parsing for report-toolkit.
As for the content of the configuration file, it must:
- Be written in JavaScript.
- Export an non-empty
Array
property namedconfig
.
With that understood, let’s look at some examples.
Configuration By Example
We’ll start by looking at a minimal configuration example, then exploring the builtin “recommended” configuration, and finally learn how to customize it.
Minimal Configuration Example
The simplest configuration file is perhaps the following:
exports.config = ['rtk:recommended'];
This loads the built-in “recommended” configuration by its alias, rtk:recommended
. rtk:recommended
also happens to be the default configuration (if no config file is present), so the above is rather pointless.
The above can be expressed in an awkward, verbose way (which is what the alias is for):
// don't do this!exports.config = [require('@report-toolkit/common/src/configs/recommended')];
For an less-trivial example, let’s take a closer look at this rtk:recommended
config.
Basic Configuration Example
This is the contents of the rtk:recommended
config, which can serve as a basic
example:
/*** The "recommended" config, which can be referenced by its alias, `rtk:recommended`.* This is _also_ the _default_ config if no config file is used.* @type {import('../config').ConfigListItem[]}**/exports.config = [{rules: {'cpu-usage': true,'library-mismatch': true,'long-timeout': true,'memory-usage': true}}];/*** @type {import('../config').BuiltinConfigAliases}*/exports.alias = 'rtk:recommended';
The above configuration file has two exports; config
and alias
. The latter, alias
, is reserved for built-in configurations—this is where the rtk:recommended
name comes from; it can be safely ignored.
The config
export is always an array. In the case above, the array has a single object with a rules
property. This property configures the Rules which the inspect command uses. The keys are Rule names, and the values are the corresponding Rule-specific configuration for each Rule.
While each Rule has its own set of options, we can use true
to enable the Rule and its default behavior. Conversely, false
will disable the Rule altogether.
In the rtk:recommended
config, all four (4) the built-in rules are enabled with their defaults.
Next, we’ll learn how to build on top of the “recommended” config with our own configuration.
Customizing the “Recommended” Configuration
We’re going to customize the “recommended” configuration. Create an empty config file and call it .rtkrc.js
—and place it in your current working directory (or project root, or even your user’s $HOME
directory; for our purposes, this doesn’t matter, as long as rtk
can find it):
Open .rtkrc.js
in your favorite editor. Copy and paste this into it:
exports.config = ['rtk.recommended'];
It is no accident that the config
property is an Array
. Each item in the config
export is deeply merged into the item before it. Kind of like the parameters to Object.assign()
—but a “deep” instead of “shallow” copy. In practical terms, we can override any given property within the rtk.recommended
config by appending a configuration object to the config
export.
Let’s take advantage of the deep merging, and configure the cpu-usage
rule (which emits a message if the total CPU usage across all cores is not within a defined range) to increase its threshold from the default, 50%, to 75%.
Change your .rtkrc.js
to the following:
exports.config = ['rtk.recommended',{rules: {'cpu-usage': {enabled: true,max: 75}}}];
Internally, the merge of our configuration object (the second item in exports.config
) into the rtk:recommended
config results in a final object that looks somewhat like this:
// This is just for purposes of illustration, and is not a configuration file!let config = {rules: {'cpu-usage': {enabled: true,max: 75},'library-mismatch': true,'long-timeout': true,'memory-usage': true}};
Now, when you run rtk inspect <report-file>
, the cpu-usage
rule won’t emit a Message unless the total CPU usage in the report is at or above 75%.
Using a Shared Configuration
A shared configuration is essentially some other config file. The “recommended” config is a shared configuration. Recall that, instead of using the rtk:recommended
alias, we could require()
it instead. The previous example config could be rewritten as:
exports.config = [require('@report-toolkit/common/src/configs/recommended'),{rules: {'cpu-usage': {enabled: true,max: 75}}}];
Of course, that’s tedious; hence the rtk:recommended
alias. But the idea is still applicable: you can include any other config file via require()
. Perhaps you have a custom config that you wish to share with your team. For example, you could create a package called report-toolkit-config-pork-chop-sandwich
and publish it to npm. This package would contain an index.js
, which would just be a regular report-toolkit
config file (containing a config
export). You can then install it into your project, and use it like so:
exports.config = ['rtk:recommended',require('report-toolkit-config-pork-chop-sandwich'),{rules: {// customize report-toolkit-pork-chop-sandwich further}}];
All three config objects will be merged together, with priority in ascending order.
This covers the basics of using configuration files. The next section is a reference of the allowed configuration properties.
Configuration Reference
Exports
A configuration file has a single export: config
.
The config
export be an Array
of config objects or string
s corresponding to builtin aliases.
Order matters; subsequent items will be deeply merged into previous items, overriding their settings.
Config Objects
A config object is an object containing zero or more of the following properties:
commands
: An object containing keys corresponding to Command names, and values of Command-specific defaults.plugins
: An array of Plugins.rules
: An object containing keys corresponding to Rule names, and values of Rule-specific options.transformers
: An object containing keys corresponding to Transformer names, and values of Transformer-specific defaults.
When you require()
another config file, you’re requiring a module with a config
export. This means that the following property is supported, but not used directly:
config
: Contains a config object.
The contents of commands
, plugins
, rules
, and transformers
are described below.
commands
Property
A Command is an rtk
command. Use the commands
property to change the default behavior of one or more Commands.
Allowed keys are the supported command names:
diff
inspect
redact
transform
Allowed properties of each are described below; these correspond to the allowed options for the particular command. In addition, properties corresponding to global options are allowed.
commands.diff
Properties
If present in a commands.diff
object, these properties will influence the default behavior of rtk diff
. Command-line arguments will have precedence over these defaults.
For more information on these options, please see the docs for diff
’s options.
includeProp
{string|string[]}
: One or more properties in “dot notation” (e.g.,header.nodeJsVersion
) to include.excludeProp
{string|string[]}
: One or more properties in “dot notation” to (e.g.,header.nodeJsVersion
) exclude.all
{boolean}
: Iftrue
, include all properties in a diff.
Also included are the common output properties.
commands.inspect
Properties
If present in a commands.inspect
object, these properties will influence the default behavior of rtk inspect
. Command-line arguments will have precedence over these defaults.
For more information on these options, please see the docs for inspect
’s options.
severity
{"error"|"warning"|"info"}
: Minimum severity level of a Message to display. The default iswarning
.
Also included are the common output properties.
commands.redact
Properties
If present in a commands.redact
object, these properties will influence the default behavior of rtk redact
. Command-line arguments will have precedence over these defaults.
For more information on these options, please see the docs for redact
’s options.
replace
{boolean}
: Iftrue
, overwrite report file in place.pretty
{boolean}
: Iffalse
, do not output pretty-printed JSON. Defaults totrue
.
command.transform
Properties
Note: these settings apply only to the transform
command. To change default transformer behavior across all commands, use the [transformers
config property].
If present in a commands.transform
object, these properties will influence the default behavior of rtk transform
. Command-line arguments will have precedence over these defaults.
commands.transform
has no unique properties in addition to the common output properties.
Common Output Properties
These properties can be used within commands.diff
, commands.inspect
, and commands.transform
. They influence the default behavior, and command-line arguments will have precedence over these.
output
{string}
: Write output to file instead ofSTDOUT
. Be sure this is what you really want!show-secrets-unsafe
{boolean}
: Iftrue
, do not redact secrets. Careful!transform
{string}: Use a transformer. Read more about the allowed transformers.
Also allowed are transformer-specific options, which are equivalent to the list of those available in the CLI.
transformers
Property
This property allows default transformer behavior to be set “globally”. For instance, if you’d like to not pretty-print JSON when using the json
transformer (with any command), use transformers
to configure this.
Each key in this property corresponds to a transformer name. The value is an object corresponding to the transformer-specific options for the transformer.
The example above can be expressed as:
{transformers: {json: {pretty: false;}}}
Command-specific transformer configuration has precedence over this “global” configuration. For example, you can re-enable pretty
for redact
, while remaining disabled for all other commands:
{transformers: {json: {pretty: false}},commands: {redact: {pretty: true}}}
rules
Property
The rules
property allows configuration of Rule behavior (used with the inspect
command).
This property is an object where the keys correspond to a Rule identifier. Each Rule—builtin or custom—has a unique identifier. The builtin Rule identifiers are:
cpu-usage
: Assert CPU usage % is within a rangelibrary-mismatch
: Identify potential shared library version mismatcheslong-timeout
: Warn about far-future callbacks in timeout queuememory-usage
: Assert memory usage % is within a range
cpu-usage
Options
The cpu-usage
Rule checks if the total CPU usage is within an allowed range. The total CPU usage is calculated across all cores. Besides the obvious, it also supports a minimum value, which can surface issues with processes that should be using cycles, but aren’t.
cpu-usage
can check the aggregate of multiple reports.
max
{integer}
: Maximum allowed CPU usage, used as a percentage. Default is50
.min
{integer}
: Minimum allowed CPU usage, used as a percentage. Default is0
.mode
{"mean"|"min"|"max"|"all"}
: One of four different modes:mean
: Check the mean CPU usage across all reports. Default.min
: Check the minimum CPU usage found across all reports.max
: Check the maximum CPU usage found across all reports.all
: Check each report individually for CPU usage in the allowed range.
library-mismatch
Options
The library-mismatch
Rule checks the shared libraries in use vs. what libraries Node.js was compiled with. A version mismatch can cause unexpected behavior.
library-mismatch
checks a single report at a time.
ignore
{string}[]
: One (1) or more components (as found in the keys ofheader.componentVersions
) to ignore; mismatches will not be reported for these libraries.
long-timeout
Options
The long-timeout
Rule checks for suspicious callbacks waiting in the event loop. These can cause a program to keep running when it was expected to exit.
long-timeout
checks a single report at a time.
timeout
{integer|string}
: A number (in milliseconds) or shorthand string representation of time, e.g.,1s
. See the ms package for formatting of strings. An active timeout in the event loop waiting at least this long will cause the Rule to emit. Default timeout is ten (10) seconds.
memory-usage
Options
The memory
Rule checks the memory usage is within a range.
memory-usage
can check the aggregate of multiple reports.
max
{integer}
: Maximum allowed memory usage, used as a percentage. Default is50
.min
{integer}
: Minimum allowed memory usage, used as a percentage. Default is0
.mode
{"mean"|"min"|"max"|"all"}
: One of four different modes:mean
: Check the mean memory usage across all reports. Default.min
: Check the minimum memory usage found across all reports.max
: Check the maximum memory usage found across all reports.all
: Check each report individually for memory usage in the allowed range.
plugins
Property
This property is a list of third-party plugins. The @report-toolkit/inspector
“plugin” (which provides the builtin Rules) is always loaded. This does not imply all rules are enabled, however!
Example:
{plugins: ['@bigco/big-report-toolkit-plugin'];}
Plugins will be resolved from the current working directory. Try require.resolve('my-plugin')
or an absolute path if you’re having trouble.
TODO: Document how to write a plugin!