Skip to content

Commit

Permalink
Merge pull request #6 from Bauer-Xcel-Media/development
Browse files Browse the repository at this point in the history
Release PR
  • Loading branch information
valdemon authored Oct 25, 2018
2 parents 7bb477f + 23f7cb3 commit 848e031
Show file tree
Hide file tree
Showing 7 changed files with 14,691 additions and 3,239 deletions.
51 changes: 47 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@
[![Commitizen friendly](https://img.shields.io/badge/commitizen-friendly-brightgreen.svg)](http://commitizen.github.io/cz-cli/)
[![codecov](https://codecov.io/gh/Bauer-Xcel-Media/node-healthchecks-api/branch/master/graph/badge.svg)](https://codecov.io/gh/Bauer-Xcel-Media/node-healthchecks-api)
[![semantic-release](https://img.shields.io/badge/%20%20%F0%9F%93%A6%F0%9F%9A%80-semantic--release-e10079.svg)](https://github.com/semantic-release/semantic-release)
[![Waffle.io - Issues in progress](https://badge.waffle.io/Bauer-Xcel-Media/node-healthchecks-api.png?label=in%20progress&title=In%20Progress)](http://waffle.io/Bauer-Xcel-Media/node-healthchecks-api)
[![Known Vulnerabilities](https://snyk.io/test/github/Bauer-Xcel-Media/node-healthchecks-api/badge.svg)](https://snyk.io/test/github/Bauer-Xcel-Media/node-healthchecks-api)
[![Greenkeeper badge](https://badges.greenkeeper.io/Bauer-Xcel-Media/node-healthchecks-api.svg)](https://greenkeeper.io/)

A [Node.js](https://nodejs.org) implementation of the [Health Checks API](https://github.com/hootsuite/health-checks-api) provided by [Hootsuite](https://hootsuite.com/).

Expand All @@ -19,7 +22,8 @@ A [Node.js](https://nodejs.org) implementation of the [Health Checks API](https:
- [Usage](#usage)
- [Service details (`about` endpoint)](#service-details-about-endpoint)
- [Configuration](#configuration)
- [Example - Express.js powered application](#example---expressjs-powered-application)
- [Initialization](#initialization)
- [Example - Express.js powered application](#example---expressjs-powered-application)
- [Check types](#check-types)
- [`self` check](#self-check)
- [Memory leak detection](#memory-leak-detection)
Expand Down Expand Up @@ -171,10 +175,49 @@ checks:
check: http
```
The library declaration depends on chosen `http server` framework, but in any case this will be about 2 lines of code.
> **NOTE**
>
> _Alternatively the configuration can be passed directly to the module initialization as an `options.service.config` attribute object value:_
>
> ```javascript
> const healthCheck = require('healthchecks-api');
> const express = require('express');
> const app = express();
> await healthCheck(app,
> {
> adapter: 'express',
> service: {
> config: {
> name: 'demo-app',
> description: 'Nice demo application :)',
> statsLinks: [ 'https://my-stats/demo-app' ],
> logsLinks: [ 'https://my-logs/demo-app/info', 'https://my-logs/demo-app/debug' ],
> checks: [
> {
> name: 'mongo',
> url: 'mongodb://mongo/test',
> type: 'internal',
> interval: 3000,
> check: 'mongo',
> },
> {
> name: 'service-1',
> url: 'http://service-1:3001',
> interval: 1000,
> check: 'http',
> }
> ]
> },
> },
> })
>```
### Initialization
The library initialization depends on chosen `http server` framework, but in any case this will be about 2 lines of code.
See the examples below.
### Example - Express.js powered application
#### Example - Express.js powered application
See: [Express.js framework](https://expressjs.com/).
Expand All @@ -186,7 +229,7 @@ const startServer = async () => {
// some initialization steps
await healthCheck(app);
// rest of initialization stepa
// rest of initialization steps
}
startServer();
Expand Down
48 changes: 32 additions & 16 deletions lib/health-check.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ const getCheckClasses = async () => {
const checkNames = await util.promisify(fs.readdir)(path.join(__dirname, 'checks'));
const checks = checkNames.reduce((result, filePath) => {
const _class = require(path.join(__dirname, 'checks', filePath));
result[_class.type] = _class;
result[_class.type || filePath] = _class;
return result;
}, {});
return Object.assign(checks, CHECKS);
Expand All @@ -42,7 +42,15 @@ const getRoutes = async () => {
handler
};
return route;
}).sort(route => route.handler.path ? 1 : 0);
}).sort((route1, route2) => {
// sort the routes with parameters at the end that the don't overlap the static routes
if (route1.handler.path && !route2.handler.path) {
return 1;
} else if (route2.handler.path && !route1.handler.path) {
return -1;
}
return route1.path.localeCompare(route2.path);
});
};

const checksSorter = (check1, check2) => {
Expand Down Expand Up @@ -76,6 +84,10 @@ module.exports = async (server, options = {
packageJson,
};

if (!(service.packageJson)) {
service.packageJson = packageJson;
}

const adapters = await getAdapters();

let _adapter = typeof adapter === 'function' ? adapter : adapters[adapter];
Expand All @@ -97,21 +109,25 @@ module.exports = async (server, options = {
throw new Error(`Config file: '${service.configPath}' does not exist.`);
}
service.config = yaml.safeLoad(await util.promisify(fs.readFile)(service.configPath));
if (service.config && service.config.checks) {
service.checks = await Promise.all(service.config.checks.map(async function (checkConfig) {
if (!(checkClasses[checkConfig.check] && checkClasses[checkConfig.check].prototype instanceof Check)) {
throw new Error(`${checkClasses[checkConfig.check]} is not an instance of ${Check.name}.`);
}
if (service.config && service.config.checks) {
service.checks = await Promise.all(service.config.checks.map(async function (checkConfig) {
if (!(checkClasses[checkConfig.check])) {
throw new Error(`${checkConfig.check} is not supported.`);
} if (!(checkClasses[checkConfig.check].prototype instanceof Check)) {
throw new Error(`${checkClasses[checkConfig.check]} is not an instance of ${Check.name}.`);
}
const _check = new (checkClasses[checkConfig.check])(checkConfig);
_check.on('statusChanged', function () {
if (this.checks) {
this.checks.sort(checksSorter);
}
const _check = new (checkClasses[checkConfig.check])(checkConfig);
_check.on('statusChanged', function () {
if (this.checks) {
this.checks.sort(checksSorter);
}
}.bind(this));
await _check.start();
return _check;
}.bind(service)));
}
}.bind(this));
await _check.start();
return _check;
}.bind(service)));
} else {
service.checks = [];
}
return await Promise.all((await getRoutes()).map(route => _adapter(service, server, route)));
};
Expand Down
Loading

0 comments on commit 848e031

Please sign in to comment.