Git Product home page Git Product logo

service-tools's Introduction

Node.js Service Tools

Prepare your Node.js application for production!

This library provides common functionalities, like graceful error handling & shutdown, structured JSON logging and several HTTP middleware to make your application truly ready for modern containerised environments, like Kubernetes.

Installation

npm i @banzaicloud/service-tools
# or
yarn add @banzaicloud/service-tools

Usage & Examples

This library is written in TypeScript, refer to the published types or the source code for argument and return types.

Examples are available for Express and Koa frameworks. Check out the examples folder!

Main exports

catchErrors(options)

Catch uncaught exceptions and unhandled Promise rejections. It is not safe to resume normal operation after 'uncaughtException'.

const { catchErrors } = require('@banzaicloud/service-tools')

// ...

// the handlers return a Promise
// the handlers are called in order
catchErrors([closeServer, closeDB])

// the error will be caught and the handlers will be called before exiting
throw new Error()

gracefulShutdown(handlers, options)

Graceful shutdown: release resources (databases, HTTP connections, ...) before exiting. When the application receives SIGTERM or SIGINT signals, the close handlers will be called. The handlers should return a Promise.

const { gracefulShutdown } = require('@banzaicloud/service-tools')

// ...

// the handlers return a Promise
// the handlers are called in order
gracefulShutdown([closeServer, closeDB])

logger

A pino structured JSON logger instance configured with config.pino.

const { logger } = require('@banzaicloud/service-tools')

logger.info({ metadata: true }, 'log message')
// > {"level":30,"time":<ts>,"msg":"log message","pid":0,"hostname":"local","metadata":true,"v":1}
Use provided logger instead of console

Globally overwrite the console and use the logger provided by the library to print out messages.

const { logger } = require('@banzaicloud/service-tools')

console.log('log message')
// > log message

logger.interceptConsole()

console.log('log message')
// > {"level":30,"time":<ts>,"msg":"log message","pid":0,"hostname":"local","v":1}

Config

Load configurations dynamically.

config.environment

Uses the NODE_ENV environment variable, with accepted values of: production, development, test.

const { config } = require('@banzaicloud/service-tools')
// validates the NODE_ENV environment variable
console.log(config.environment)
// > { nodeEnv: 'production' }

config.pino

Used by the provided logger. Uses the LOGGER_LEVEL and LOGGER_REDACT_FIELDS environment variables. The LOGGER_LEVEL can be one of the following: fatal, error, warn, info, debug, trace. LOGGER_REDACT_FIELDS is a comma separated list of field names to mask out in the output (defaults to: 'password, pass, authorization, auth, cookie, _object').

const pino = require('pino')
const { config } = require('@banzaicloud/service-tools')

const logger = pino(config.pino)

logger.info({ metadata: true, password: 'secret' }, 'log message')
// > {"level":30,"time":<ts>,"msg":"log message","pid":0,"hostname":"local","metadata":true,"password":"[REDACTED]","v":1}

Middleware (Koa)

Several middleware for the Koa web framework.

errorHandler(options)

Koa error handler middleware.

const Koa = require('koa')
const { koa: middleware } = require('@banzaicloud/service-tools').middleware

const app = new Koa()

// this should be the first middleware
app.use(middleware.errorHandler())

healthCheck(checks, options)

Koa health check endpoint handler.

const Koa = require('koa')
const Router = require('koa-router')
const { koa: middleware } = require('@banzaicloud/service-tools').middleware

// ...

const app = new Koa()
const router = new Router()

// the checks return a Promise
router.get('/health', middleware.healthCheck([checkDB]))

app.use(router.routes())
app.use(router.allowedMethods())

prometheusMetrics(options)

Koa Prometheus metrics endpoint handler. By default it collects some default metrics.

const Koa = require('koa')
const Router = require('koa-router')
const { koa: middleware } = require('@banzaicloud/service-tools').middleware

// ...

const app = new Koa()
const router = new Router()

router.get('/metrics', middleware.prometheusMetrics())

app.use(router.routes())
app.use(router.allowedMethods())

requestValidator(options)

Koa request validator middleware. Accepts Joi schemas for body (body parser required), params and query (query parser required). Returns with 400 if the request is not valid. Assigns validated values to ctx.state.validated.

const joi = require('joi')
const qs = require('qs')
const Koa = require('koa')
const Router = require('koa-router')
const bodyParser = require('koa-bodyparser')
const { koa: middleware } = require('@banzaicloud/service-tools').middleware

// ...

const app = new Koa()
const router = new Router()

const paramsSchema = joi
  .object({
    id: joi
      .string()
      .hex()
      .length(64)
      .required(),
  })
  .required()

const bodySchema = joi.object({ name: joi.string().required() }).required()

const querySchema = joi.object({ include: joi.array().default([]) }).required()

router.get(
  '/',
  middleware.requestValidator({ params: paramsSchema, body: bodySchema, query: querySchema }),
  async function routeHandler(ctx) {
    const { params, body, query } = ctx.state.validated
    // ...
  }
)

app.use(bodyParser())
// query parser
app.use(async function parseQuery(ctx, next) {
  ctx.query = qs.parse(ctx.querystring, options)
  ctx.request.query = ctx.query
  await next()
})
app.use(router.routes())
app.use(router.allowedMethods())

requestLogger(options)

Koa request logger middleware. Useful for local development and debugging.

const Koa = require('koa')
const { koa: middleware } = require('@banzaicloud/service-tools').middleware

// ...

const app = new Koa()

// this should be the second middleware after the error handler
// ...
app.use(middleware.requestLogger())

Middleware (Express)

Several middleware for the Express web framework.

errorHandler(options)

Express error handler middleware.

const express = require('express')
const { express: middleware } = require('@banzaicloud/service-tools').middleware

const app = express()

// this should be the last middleware
app.use(middleware.errorHandler())

healthCheck(checks, options)

Express health check endpoint handler.

const express = require('express')
const { express: middleware } = require('@banzaicloud/service-tools').middleware

// ...

const app = express()

// the checks return a Promise
app.get('/health', middleware.healthCheck([checkDB]))

prometheusMetrics(options)

Express Prometheus metrics endpoint handler. By default it collects some default metrics.

const express = require('express')
const { express: middleware } = require('@banzaicloud/service-tools').middleware

// ...

const app = express()

app.get('/metrics', middleware.prometheusMetrics())

requestValidator(options)

Express request validator middleware. Accepts Joi schemas for body (body parser required), params and query. Returns with 400 if the request is not valid. Assigns validated values to req.

const joi = require('joi')
const express = require('express')
const { express: middleware } = require('@banzaicloud/service-tools').middleware

// ...

const app = express()

const paramsSchema = joi
  .object({
    id: joi
      .string()
      .hex()
      .length(64)
      .required(),
  })
  .required()

const bodySchema = joi.object({ name: joi.string().required() }).required()

const querySchema = joi.object({ include: joi.array().default([]) }).required()

app.use(express.json())
app.get(
  '/',
  middleware.requestValidator({ params: paramsSchema, body: bodySchema, query: querySchema }),
  function routeHandler(req, res) {
    const { params, body, query } = req
    // ...
  }
)

service-tools's People

Contributors

dependabot[bot] avatar tothandras avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

service-tools's Issues

Add support for Hapi

Is your feature request related to a problem? Please describe.
Although Express and Koa have more performance over Hapi, there is still a great number of applications written using Hapi. This feature request is to add Hapi support on service-tools

Describe the solution you'd like to see
All existing Express capabilities supported by service-tools on Hapi

Describe alternatives you've considered
I have tried to integrate a nodejs clean architecture using Hapi, but service-tools is so good for Kubernetes ecosystem that I had to migrate to Express. My repo can be find at https://github.com/EvertonSA/nodejs-baseline

pino default level not found

Thanks for this great library.

Weird, I am getting this error

    throw Error(`default level:${defaultLevel} must be included in custom levels`)
          ^
Error: default level:undefined must be included in custom levels

I've got in my .env

LOGGER_LEVEL=debug
LOGGER_REDACT_FIELDS=password, pass, authorization, auth, cookie, _object

Thanks

Extraneous dependency: `request-promise-native`

Overview of the Issue

This package includes a reference to the very sizable request-promise-native package under dependencies here, and is implemented as part of makeRequest helper function.

๐Ÿ‘‰ install size

The exported makeRequest helper function is not officially documented, and appears to be utilized only within unit test scripts.

Reproduce the Error

npm install
npm ls --prod | grep request-promise-native

Related Issues

N/A

Suggest a Fix

Without specific knowledge of the project roadmap for exposing such http helper functions, it may be worthwhile either installing under devDependencies or refactoring to use a more lightweight HTTP request package:

Warning during compilation

The following warning shows, might be a good idea to update dependencies

Sincerely,

warning @banzaicloud/service-tools > [email protected]: This module has moved and is now available at @hapi/joi. Please update your dependencies as this version is no longer maintained an may contain bugs and security issues.
warning @banzaicloud/service-tools > joi > [email protected]: This module has moved and is now available at @hapi/topo. Please update your dependencies as this version is no longer maintained an may contain bugs and security issues.
warning @banzaicloud/service-tools > joi > [email protected]: This module has moved and is now available at @hapi/hoek. Please update your dependencies as this version is no longer maintained an may contain bugs and security issues.
warning @banzaicloud/service-tools > joi > topo > [email protected]: This module has moved and is now available at @hapi/hoek. Please update your dependencies as this version is no longer maintained an may contain bugs and security issues.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.