niveau

0.2.1 • Public • Published

Build Status Greenkeeper badge npm

niveau

Node.js package to switch log level per request in Cloud Foundry

Goals

  • Change the log level without restart - no downtime
  • Change the log level per request. Setting the log level to debug on an app with high load could result in log flood and even loss of log messages.
  • All application instances use the same log level.
  • Set the log level from server-side as it is often hard to change client requests. This is also less susceptible to DoS attacks.
  • Temporary log level change
    • Time based
    • Request count based
  • Integrate with different logging libraries. Logging lib agnostic.

Requirements

  • Node.js 6 (or later)
  • Cloud Foundry
  • Redis

Design

We need some persistence of the log level, so new instances can load it. To achieve this, we use Redis as it provides both storage and change notification via keyspace notifications.

This package provides a CLI interface to change the log configuration. There are several options to invoke it:

Deployment options:

  • As part of an existing Node.js app
    • No additional app
  • As a separate app
    • Can be used with applications that do not run on Node.js
    • Does not need to run. Executing CF task will start a temporary instance automatically
    • One more app to manage

In any case the application should be bound to a Redis instance.

Usage

In the application

Install the package.

npm install --save niveau

With npm 5 you don't need the --save option.

Configure niveau and add it as a middleware:

const express = require('express');
const niveau = require('niveau');
 
let nv = niveau(/* redis options */);
nv.on('error', err => {
  console.error(err);
});
nv.on('config', config => {
  // log configuration changed
});
nv.on('request', (req, config) => {
  // request matches logging criteria
  // set log level for this request to config.level
});
 
let app = express();
app.use(nv);
app.use((req, res, next) => {
  // req.logLevel - the log level to be used for this request (if present)
  // nv.logConfig - the current log configuration
});

See example applications in examples folder.

niveau([options])

  • options Redis connection options + additional properties:
    • redisKey name of the Redis key that stores the configuration, default is log-config

Creates niveau middleware. It matches incoming requests against the criteria in the log configuration. For matching requests it sets logLevel property on the request object to the log level from the configuration.

If options is not provided, use bound Redis service. If no Redis service is bound, use local Redis on default port.

The middleware also listens for log configuration changes and emits some events.

Event 'error'

Event arguments:

  • error an Error object

Emitted in case of error, e.g. Redis connection failed.

Event 'config'

Event arguments:

Emitted when log configuration is changed or deleted.

Event 'request'

Event arguments:

Emitted when an HTTP request matches the criteria in the log configuration.

nv.logConfig

Contains the current log configuration. It is null if no log configuration is set.

Log configuration

Log configuration object:

  • request (optional) request matching criteria, if missing or empty, the log level should be used for all requests
    • url (optional) RegExp to match against the request URL
    • ip (optional) RegExp to match against the client IP address
    • headers (optional) an object to match against request headers, each values is a RegExp
  • level log level as a string to use for matching requests

Changing the log level

This package provides a command line tool to change the log level. The provided log level will be used only for HTTP requests that match all the given criteria. Each command invocation overwrites any previous settings.

set-log-level [options...] [<level>]

Options

  • -l, --url <regex> - matches request URL (without protocol, host, port)
  • -h, --header <name>:<regex> - matches given request header value
  • -i, --ip <regex> - matches sender IP address
  • -x, --expire <value> - expiration time with s/m/h suffix
  • -r, --reset - reset log level to default (do not provide level)
  • --help - print usage
  • <level> - log level to use for matching requests, supported values depend on your log library

Invoke via CF task

This will start a temporary instance of the application, run the task inside and stop that instance.

cf run-task APP-NAME "set-log-level [options] [<level>]" [-m MEMORY] [--name TASK_NAME]

Check the output in the logs

cf logs --recent APP-NAME

Invoke via SSH to the application

Log into the container of a running application and execute the command:

cf ssh APP-NAME
export PATH=$PATH:~/deps/0/bin:~/app/node_modules/.bin
set-log-level [options...] <level>

This is useful if you need to run it multiple times and see the output immediately.

Examples

Set log level to debug for requests on URLs starting with /api/v2. Reset log level after 15 min.

set-log-level -l '^/api/v2/' --expire 15m debug

Contributing

Install all dependencies:

npm install

Run static code checks with eslint and unit tests:

npm test

Integration tests require Redis to run on localhost on default port 6379. Install docker, unless you have it already. Start Redis:

npm run redis

Run the integration tests against Redis:

npm run itest

Generate test coverage report:

npm run coverage

After editing README.md update its table of contents:

npm run toc

Future

Ideas for new features are tracked in GitHub issues. You are encouraged to comment, add new ideas and contribute in any way.

Readme

Keywords

Package Sidebar

Install

npm i niveau

Weekly Downloads

1

Version

0.2.1

License

MIT

Unpacked Size

18.5 kB

Total Files

8

Last publish

Collaborators

  • dotchev