npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

nodejs-health-checker-lw

v1.0.1

Published

The main purpose of this package is to substitute nodejs-health-checker package and standardize the liveness and readiness actions for Nodejs applications running in Kubernetes deployments, without adding complexity and extra package installs.

Downloads

117

Readme

nodejs-health-checker-lw

npm

test build Coverage Status GitHub GitHub issues npm Tag Status Languages Status Repo Size Status

contributors

contributors

Made with contributors-img.


A successor package for nodejs-health-checker to simplify health checks.

The main purpose of this package is to substitute nodejs-health-checker package and standardize the liveness and readiness actions for Nodejs applications running in Kubernetes deployments, without adding complexity and extra package installs.

Read more about migrating from nodejs-health-checker or creating your tests in MIGRATIONS GUIDELINES


Liveness method

Will return a JSON as below:

{
  "status": "fully functional",
  "version": "v1.0.0"
}

Readiness method

Will return a JSON as below:

The status prop will return true once all your integrations works. If one of then fails, this status prop will reflect that something went wrong and you need to check the status inside integrations prop

{
  "name": "myapp",
  "version": "v1.0.0",
  "status": true,
  "date": "2022-07-10T00:46:19.186Z",
  "duration": 0.068,
  "integrations": [
    {
      "name": "github integration",
      "status": true,
      "response_time": 0.068,
      "url": "https://github.com/status"
    }
  ]
}

How to install

npm i --save nodejs-health-checker-lw

OR

yarn add nodejs-health-checker-lw

How to init

First, you need to write your test like below:

this example is using http check for API integrations. Remember that you can write using your own methods and patterns. You need only to return an instance of nodejs-health-checker Check.

// file src/integrations/github.ts
import { Check } from 'nodejs-health-checker-lw'
import { fetch } from 'node-fetch'
export async function TestGithubIntegration() Promise<Check> {
  return new Promise((resolve, _) => {
    let result = new Check({ url: 'https://github.com/status' })
    // call a url to test connectivity and HTTP status
    fetch(result.url, { timeout: 10000 })
      .then(response => {
        if (response.status !== 200) {
          result.error = {
            status: response.status,
            body: response.body
          }
        }
      })
      .catch(error => result.error = error)
      .finally(() => resolve(result))
  })
}

Then in your main declarations, you MUST create a const with HealthChecker from nodejs-health-checker-lw and fill a few props to create a re-usable pointer to be called after as below.

Read more about the version in this topic

// file src/healthchecker.ts
import { HealthChecker} from 'nodejs-health-checker-lw'
import { TestGithubIntegration } from 'src/integrations/github' // as the example above. This list can grow as mush as you need
export const check = new HealthChecker({
  name: 'myapp', // set your application name
  version: 'v1.0.0', // set the version of your application
  // integrations are the list of tests that needs to be executed.
  integrations: [
    {
      // set the name of the integration that will be tested
      name: 'github integration', 
      // pass the functions that tests this integration
      handle: MyIntegrationTest
    }
  ]
})

How to use it

Once you create a constant with an instance of HealthChecker, you can now call the methods, liveness, and readiness, in your application, in CLI or API mode

CLI interface

import check from 'src/healthchecker' // as the example above
const cliArgs = process.argv.slice(2)
switch (cliArgs[0]) {
  case 'liveness':
    console.log(check.liveness())
    break
  case 'readiness':
    check.readiness().then(response => {
      if (!response.status) {
        // do something like trigger an alarm or log to other obervability stacks
        console.warning(JSON.stringify({message: "health check fails", results: response}))
      } else {
        // or just log OK to track
        console.info(JSON.stringify(response));
      }
    })
    break
  default:
    console.error(`invalid option: ${cliArgs[0]}... accepty only liveness or readiness`)
}

In Kubernetes deployment

apiVersion: apps/v1
kind: Deployment
metadata:
  name: your-nodejs-app
spec:
  selector:
    matchLabels:
      app: your-nodejs-app
  template:
    metadata:
      labels:
        app: your-nodejs-app
    spec:
      containers:
      - name: your-nodejs-app
        image: your-nodejs-app:tag
        resources:
          limits:
            memory: "128Mi"
            cpu: "500m"
        ports:
        - containerPort: 80
        livenessProbe:
          exec:
            command:
              - "/bin/node"
              - "your-script.js"
            args:
              - "liveness"
        readinessProbe:
          exec:
            command:
              - "/bin/node"
              - "your-script.js"
            args:
              - "readiness"

HTTP interface

In Javascript

import express from 'express'
import check from 'src/healthchecker' // as the example above
const PORT = process.env.PORT||80;
const server = express()
server.get('/health-check/liveness', (_, res) => {
  res.json(check.liveness())
})
server.get('/health-check/readiness', async (_, res) => {
  const result = await check.readiness()
  if (!response.status) {
    // do something like trigger an alarm or log to other obervability stacks
    console.warning(JSON.stringify({message: "health check fails", results: response}))
  } else {
    // or just log OK to track
    console.info(JSON.stringify(response));
  }
  res.json(result)
})
server.listen(PORT, () => {
  console.log(`[SERVER] Running at http://localhost:${PORT}`);
});

In Kubernetes deployment

apiVersion: apps/v1
kind: Deployment
metadata:
  name: your-nodejs-app
spec:
  selector:
    matchLabels:
      app: your-nodejs-app
  template:
    metadata:
      labels:
        app: your-nodejs-app
    spec:
      containers:
      - name: your-nodejs-app
        image: your-nodejs-app:tag
        resources:
          limits:
            memory: "128Mi"
            cpu: "500m"
        ports:
        - containerPort: 80
        livenessProbe:
          httpGet:
            path: /health-check/liveness
            port: http
        readinessProbe:
          httpGet:
            path: /health-check/readiness
            port: http

It's important to share that you MUST return always an OK status in Kubernetes liveness and readiness because if one of your integration fails, this can teardown all of your pods and make your application unavailable. Use other observability stacks like Zabbix or Grafana alarms to track your application logs and then take actions based on observability! (I learned it by the hard way =/ )


More pieces of information


Version in your HealthChecker

I highly recommend you fill this prop using a dynamic file content loading like:

  • reading the package.json file and using the version value to fill the HealthChecker.version placeholder like below:

    import fs from 'fs'
    import path from 'path'
    import { HealthChecker } from 'nodejs-health-checker-lw'
    import { TestGithubIntegration } from 'src/integrations/github' 
      
    const versionFilePath = path('package.json')
    const file = {
      content: null
      error: undefined
    }
    try {
      let tmpRawData = await fs.readFileSync(versionFilePath, {encoding: 'utf8'})
      file.content = JSON.parse(tmpRawData)
    } catch (error) {
      file.error = error
    }
    
    export const check = new HealthChecker({
      name: 'myapp',
      version: file.error || file.content.version
      integrations: [/*and the list of your integrations here*/]
    })
    
  • creating a file like version.txt using a command like the below in the pipeline before a docker build/push steps:

    git show -s --format="%ai %H %s %aN" HEAD > version.txt

    then use it in your code like:

    import fs from 'fs'
    import path from 'path'
    import { HealthChecker } from 'nodejs-health-checker-lw'
    import { TestGithubIntegration } from 'src/integrations/github' 
    
    const versionFilePath = path('version.txt')
    const file = {
      content: null
      error: undefined
    }
    try {
      file.content = await fs.readFileSync(versionFilePath, {encoding: 'utf8'})
    } catch (error) {
      file.error = error
    }
    export const check = new HealthChecker({
      name: 'myapp',
      version: file.error || file.content
      integrations: [/*and the list of your integrations here*/]
    })