Skip to main content

Reduce container startup time

When you start your instrumented application, Contrast applies source transformations to both your application and the dependency code your application loads. This code rewriting increases startup time when running applications with the agent.

Starting with version 4.X, the Node.js agent includes a command line utility you can use to pre-compile applications before starting them. When started with Contrast, the pre-compiled application loads the rewritten files from disk and significantly improves startup time. Starting with version 5, its utilities do not support command line arguments like --agent.logger.path /dev/null.

Use the rewriter

  1. In the Node.js agent's configuration file (contrast_security.yaml):

    • (Optional) Enable rewrite caching and specify the path of the cache location.

      • By default, the cache is enabled and will be written to the .contrast folder under the application directory.

      • If either agent.node.rewrite.enable or agent.node.rewrite.cache.enable are false, the CLI will throw an error.

    • (Optional) Specify the logging level.

      • The rewriter provides minimal logging at the default INFO level to inform the user which mode it is running under. At the DEBUG level, it will inform the user about failures in the rewriting process. At the TRACE level, it will log information about each file that is rewritten.

    • Enable assess or protect to specify the mode under which to run the rewriter. If both modes are enabled then the rewriter is in assess mode, since assess includes all of the transforms from protect.

    • Note

      You can also specify modes at runtime with the -a, --assess or -p, --protect flags.

    For example:

    // example config
    agent:
      logger:
        level: TRACE // Default: INFO
      node:
        rewrite:
          enable: true // default: true
          cache:
            enable: true // default: true
            path: ./path/relative/to/app/root // default: .contrast/
    assess:
      enable: true
    
  2. (Optional) Install the @contrast/cli package:

    • This can be a devDependency since it is not used by the agent at runtime.

    • npx will ask you to install the package when performing step 3 if you do not install it beforehand. This is fine, but installing it manually (and including @contrast/cli as a dependency in your package.json) will ensure you are using the specified version.

    npm install --save-dev @contrast/cli
  3. Invoke the executable and provide it with your application’s entry point (for example index.js).

    npx -p @contrast/cli rewrite index.js
    # or
    npx -p @contrast/cli rewrite -a index.js # force assess mode
    npx -p @contrast/cli rewrite -p index.js # force protect mode
  4. You can verify that the precompilation has occurred by checking the cache directory (.contrast by default). You should see several nested folders like .contrast/PACKAGE_NAME/CONTRAST_REWRITER_VERSION_NUMBER/MODE, for example, .contrast/my-package/1.7.0/assess. The contents of the _ directory in this path should match the structure of your application directory.

Known Limitations

A few scenarios cannot currently be handled by the rewriter CLI.

The rewriter CLI uses static analysis to determine the files to rewrite, so it cannot handle dynamic imports or requires. If a file is included in any of the following ways, the agent will instead rewrite that file when it is included at runtime.

// dynamic imports or requires
const name = 'foo.js';
await import(name);require(name);

// direct calls to createRequire
createRequire(import.meta.url)('foo.js');
// this should work, however:
const require = createRequire(import.meta.url);
require('foo.js');

// renamed require functions
const r = createRequire('...');
r('foo.js');
const myRequire = require;
myRequire('bar.js');