diff --git a/README.md b/README.md index f829888..7eb6473 100644 --- a/README.md +++ b/README.md @@ -82,7 +82,17 @@ const graceful = new Graceful({ timeoutMs: 5000, // options to pass to `lil-http-terminator` to override defaults - lilHttpTerminator: {} + lilHttpTerminator: {}, + + // + // appends a `true` boolean value to a property of this name in the logger meta object + // (this is useful for Cabin/Axe as it will prevent a log from being created in MongoDB) + // (and instead of having a DB log created upon graceful exit, it will simply log to console) + // (defer to the Forward Email codebase, specifically the logger helper) + // + // NOTE: if you set this to `false` then this will be ignored and no meta property will be populated + // + ignoreHook: 'ignore_hook' }); // @@ -157,16 +167,17 @@ This package works with any server created with `http.createServer` or `net.crea Here is the full list of options and their defaults. See [index.js](index.js) for more insight if necessary. -| Property | Type | Default Value | Description | -| ------------------- | ------ | ------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| `servers` | Array | `[]` | An array of HTTP or NET servers to gracefully close on exit | -| `brees` | Array | `[]` | An array of [Bree][] instances to gracefully exit | -| `redisClients` | Array | `[]` | An array of Redis client instances to gracefully exit | -| `mongooses` | Array | `[]` | An array of Mongoose connections to gracefully exit | -| `customHandlers` | Array | `[]` | An array of functions (custom handlers) to invoke upon graceful exit | -| `logger` | Object | `console` | This is the default logger. **We recommend using [Cabin][cabin]** instead of using `console` as your default logger. Set this value to `false` to disable logging entirely (uses noop function) | -| `timeoutMs` | Number | `5000` | A number in milliseconds for how long to wait to gracefully exit | -| `lilHttpTerminator` | Object | `{}` | An object of options to pass to `lil-http-terminator` to override default options provided | +| Property | Type | Default Value | Description | +| ------------------- | ------------------------- | --------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `servers` | Array | `[]` | An array of HTTP or NET servers to gracefully close on exit | +| `brees` | Array | `[]` | An array of [Bree][] instances to gracefully exit | +| `redisClients` | Array | `[]` | An array of Redis client instances to gracefully exit | +| `mongooses` | Array | `[]` | An array of Mongoose connections to gracefully exit | +| `customHandlers` | Array | `[]` | An array of functions (custom handlers) to invoke upon graceful exit | +| `logger` | Object | `console` | This is the default logger. **We recommend using [Cabin][cabin]** instead of using `console` as your default logger. Set this value to `false` to disable logging entirely (uses noop function) | +| `timeoutMs` | Number | `5000` | A number in milliseconds for how long to wait to gracefully exit | +| `lilHttpTerminator` | Object | `{}` | An object of options to pass to `lil-http-terminator` to override default options provided | +| `ignoreHook` | String or `false` Boolean | `"ignore_hook"` | Appends a `true` boolean property to a property with this value in logs, e.g. `console.log('graceful exiting', { ignore_hook: true });` which is useful for preventing logs from being written to a database in hooks (this is meant for usage with [Cabin][] and [Axe][] and made for [Forward Email][forward-email]). If you pass a `false` value then this property will not get populated. | ## Examples @@ -214,3 +225,7 @@ You can also read more about Bree at . [cabin]: https://cabinjs.com [bree]: https://jobscheduler.net + +[axe]: https://github.com/cabinjs/axe + +[forward-email]: https://github.com/forwardemail diff --git a/index.d.ts b/index.d.ts index 4e75f87..b9271bf 100644 --- a/index.d.ts +++ b/index.d.ts @@ -1,16 +1,16 @@ -interface Logger { +type Logger = { info(): unknown; warn(): unknown; error(): unknown; -} +}; -interface LilHttpTerminator { +type LilHttpTerminator = { gracefulTerminationTimeout?: number; maxWaitTimeout?: number; logger?: Logger; -} +}; -export interface GracefulOptions { +export type GracefulOptions = { servers?: Array<{ close(): unknown }>; brees?: Array<{ stop(): Promise }>; redisClients?: Array<{ disconnect(): unknown }>; @@ -19,7 +19,8 @@ export interface GracefulOptions { logger?: Logger; timeoutMs?: number; lilHttpTerminator?: LilHttpTerminator; -} + ignoreHook?: string | boolean; +}; export default class Graceful { constructor(options?: GracefulOptions); diff --git a/index.js b/index.js index 5d171fe..620f0ba 100644 --- a/index.js +++ b/index.js @@ -19,6 +19,7 @@ class Graceful { logger: console, timeoutMs: 5000, lilHttpTerminator: {}, + ignoreHook: 'ignore_hook', ...config }; @@ -30,12 +31,9 @@ class Graceful { error() {} }; - // shortcut logger - this.logger = this.config.logger; - - // if lilHttpTerminator does not have a logger set then re-use `this.logger` + // if lilHttpTerminator does not have a logger set then re-use `this.config.logger` if (!this.config.lilHttpTerminator.logger) - this.config.lilHttpTerminator.logger = this.logger; + this.config.lilHttpTerminator.logger = this.config.logger; // prevent multiple SIGTERM/SIGHUP/SIGINT from firing graceful exit this._isExiting = false; @@ -79,7 +77,7 @@ class Graceful { process.on('warning', (warning) => { // warning.emitter = null; - this.logger.warn(warning); + this.config.logger.warn(warning); }); // handle uncaught promises @@ -95,7 +93,7 @@ class Graceful { // handle uncaught exceptions process.once('uncaughtException', (err) => { - this.logger.error(err); + this.config.logger.error(err); process.exit(1); }); @@ -103,7 +101,11 @@ class Graceful { // process.on('message', async (message) => { if (message === 'shutdown') { - this.logger.info('Received shutdown message'); + if (this.config.ignoreHook) + this.config.logger.info('Received shutdown message', { + [this.config.ignoreHook]: true + }); + else this.config.logger.info('Received shutdown message'); await this.exit(); } }); @@ -139,7 +141,10 @@ class Graceful { : util.promisify(server.close).bind(server)()); } } catch (err) { - this.logger.error(err, { code }); + this.config.logger.error(err, { + code, + ...(this.config.ignoreHook ? { [this.config.ignoreHook]: true } : {}) + }); } } @@ -154,7 +159,10 @@ class Graceful { try { await client.disconnect(); } catch (err) { - this.logger.error(err, { code }); + this.config.logger.error(err, { + code, + ...(this.config.ignoreHook ? { [this.config.ignoreHook]: true } : {}) + }); } } @@ -170,7 +178,10 @@ class Graceful { try { await mongoose.disconnect(); } catch (err) { - this.logger.error(err, { code }); + this.config.logger.error(err, { + code, + ...(this.config.ignoreHook ? { [this.config.ignoreHook]: true } : {}) + }); } } @@ -184,7 +195,10 @@ class Graceful { try { await bree.stop(); } catch (err) { - this.logger.error(err, { code }); + this.config.logger.error(err, { + code, + ...(this.config.ignoreHook ? { [this.config.ignoreHook]: true } : {}) + }); } } @@ -198,7 +212,10 @@ class Graceful { try { await handler(); } catch (err) { - this.logger.error(err, { code }); + this.config.logger.error(err, { + code, + ...(this.config.ignoreHook ? { [this.config.ignoreHook]: true } : {}) + }); } } @@ -211,10 +228,17 @@ class Graceful { } async exit(code) { - if (code) this.logger.info('Gracefully exiting', { code }); + if (code) + this.config.logger.info('Gracefully exiting', { + code, + ...(this.config.ignoreHook ? { [this.config.ignoreHook]: true } : {}) + }); if (this._isExiting) { - this.logger.info('Graceful exit already in progress', { code }); + this.config.logger.info('Graceful exit already in progress', { + code, + ...(this.config.ignoreHook ? { [this.config.ignoreHook]: true } : {}) + }); return; } @@ -222,11 +246,14 @@ class Graceful { // give it only X ms to gracefully exit setTimeout(() => { - this.logger.error( + this.config.logger.error( new Error( `Graceful exit failed, timeout of ${this.config.timeoutMs}ms was exceeded` ), - { code } + { + code, + ...(this.config.ignoreHook ? { [this.config.ignoreHook]: true } : {}) + } ); // eslint-disable-next-line unicorn/no-process-exit process.exit(1); @@ -245,11 +272,17 @@ class Graceful { // custom handlers this.stopCustomHandlers(code) ]); - this.logger.info('Gracefully exited', { code }); + this.config.logger.info('Gracefully exited', { + code, + ...(this.config.ignoreHook ? { [this.config.ignoreHook]: true } : {}) + }); // eslint-disable-next-line unicorn/no-process-exit process.exit(0); } catch (err) { - this.logger.error(err, { code }); + this.config.logger.error(err, { + code, + ...(this.config.ignoreHook ? { [this.config.ignoreHook]: true } : {}) + }); // eslint-disable-next-line unicorn/no-process-exit process.exit(1); } diff --git a/package.json b/package.json index 666fb01..e0c441e 100644 --- a/package.json +++ b/package.json @@ -18,28 +18,28 @@ "p-is-promise": "3" }, "devDependencies": { - "@commitlint/cli": "^17.0.2", - "@commitlint/config-conventional": "^17.0.2", - "@ladjs/api": "^10.0.3", - "@ladjs/web": "^14.0.3", - "ava": "^4.3.0", + "@commitlint/cli": "^17.2.0", + "@commitlint/config-conventional": "^17.2.0", + "@ladjs/api": "^12.0.2", + "@ladjs/web": "^18.0.4", + "ava": "^5.1.0", "cross-env": "^7.0.3", - "eslint": "8.17.0", + "eslint": "8.27.0", "eslint-config-xo-lass": "^2.0.1", - "express": "^4.18.1", - "fastify": "^3.29.0", + "express": "^4.18.2", + "fastify": "^4.10.0", "fixpack": "^4.0.0", "get-port": "5", - "husky": "^8.0.1", - "ioredis": "^5.0.6", + "husky": "^8.0.2", + "ioredis": "^5.2.4", "ioredis-mock": "^8.2.2", "koa": "^2.13.4", - "lint-staged": "^13.0.0", + "lint-staged": "^13.0.3", "nyc": "^15.1.0", - "remark-cli": "^10.0.1", + "remark-cli": "^11.0.0", "remark-preset-github": "^4.0.4", "smtp-server": "^3.11.0", - "xo": "^0.49.0" + "xo": "^0.52.4" }, "engines": { "node": ">=14"