UNPKG

@adonisjs/lucid

Version:

SQL ORM built on top of Active Record pattern

143 lines (142 loc) 4.84 kB
/* * @adonisjs/lucid * * (c) AdonisJS * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ import { BaseCheck, Result } from '@adonisjs/core/health'; /** * The DbConnectionCountCheck can be used to monitor the active * database connections and report a warning or error after * a certain threshold has been execeeded. */ export class DbConnectionCountCheck extends BaseCheck { #client; /** * Method to compute the memory consumption */ #computeFn = async (client) => { if (client.dialect.name === 'postgres') { const response = await client.query().from('pg_stat_activity').count('* as connections'); return Number(response[0].connections); } if (client.dialect.name === 'mysql') { const response = await client .query() .from('information_schema.PROCESSLIST') .count('* as connections'); return Number(response[0].connections); } return null; }; /** * Connections count threshold after which a warning will be created */ #warnThreshold = 10; /** * Connections count threshold after which an error will be created */ #failThreshold = 15; /** * Health check public name */ name; constructor(client) { super(); this.#client = client; this.name = `Connection count health check (${client.connectionName})`; } /** * Returns connection metadata to be shared in the health checks * report */ #getConnectionMetadata() { return { connection: { name: this.#client.connectionName, dialect: this.#client.dialect.name, }, }; } /** * Returns connections count metadata to be shared in the * health checks report */ #getConnectionsCountMetadata(active) { return { connectionsCount: { active, warningThreshold: this.#warnThreshold, failureThreshold: this.#failThreshold, }, }; } /** * Define the connections count threshold after which a * warning should be created. * * ``` * .warnWhenExceeds(20) * ``` */ warnWhenExceeds(connectionsCount) { this.#warnThreshold = connectionsCount; return this; } /** * Define the connections count threshold after which an * error should be created. * * ``` * .failWhenExceeds(30) * ``` */ failWhenExceeds(connectionsCount) { this.#failThreshold = connectionsCount; return this; } /** * Define a custom callback to compute database connections count. * The return value must be a number of active connections * or null (if dialect is not supported). */ compute(callback) { this.#computeFn = callback; return this; } /** * Executes the health check */ async run() { try { const connectionsCount = await this.#computeFn(this.#client); if (!connectionsCount) { return Result.ok(`Check skipped. Unable to get active connections for ${this.#client.dialect.name} dialect`).mergeMetaData(this.#getConnectionMetadata()); } /** * Check if we have crossed the failure threshold */ if (connectionsCount > this.#failThreshold) { return Result.failed(`There are ${connectionsCount} active connections, which is above the threshold of ${this.#failThreshold} connections`) .mergeMetaData(this.#getConnectionMetadata()) .mergeMetaData(this.#getConnectionsCountMetadata(connectionsCount)); } /** * Check if we have crossed the warning threshold */ if (connectionsCount > this.#warnThreshold) { return Result.warning(`There are ${connectionsCount} active connections, which is above the threshold of ${this.#warnThreshold} connections`) .mergeMetaData(this.#getConnectionMetadata()) .mergeMetaData(this.#getConnectionsCountMetadata(connectionsCount)); } return Result.ok(`There are ${connectionsCount} active connections, which is under the defined thresholds`) .mergeMetaData(this.#getConnectionMetadata()) .mergeMetaData(this.#getConnectionsCountMetadata(connectionsCount)); } catch (error) { return Result.failed(error.message || 'Connection failed', error).mergeMetaData(this.#getConnectionMetadata()); } } }