UNPKG

kuzzle-plugin-prometheus

Version:
146 lines 5.42 kB
"use strict"; /* * Kuzzle, a backend software, self-hostable and ready to use * to power modern apps * * Copyright 2015-2021 Kuzzle * mailto: support AT kuzzle.io * website: http://kuzzle.io * * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * https://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.PrometheusPlugin = void 0; const kuzzle_1 = require("kuzzle"); const lodash_1 = __importDefault(require("lodash")); const MetricService_1 = require("./services/MetricService"); /** * @class PrometheusPlugin * * @property {PluginConfiguration} config Plugin configuration * @property {MetricService} metricService Metric service * * @externs */ class PrometheusPlugin extends kuzzle_1.Plugin { constructor() { super({ kuzzleVersion: '>=2.16.9 <3' }); /** * Default plugin configuration */ this.config = { default: { enabled: true, // Because this are standard metrics and official dashboards do not use prefix on it prefix: '', eventLoopMonitoringPrecision: 10, gcDurationBuckets: [0.001, 0.01, 0.1, 1, 2, 5], }, core: { monitorRequestDuration: true, prefix: 'kuzzle_', }, labels: {}, }; } /** * Plugin initialization * @param {PrometheusPluginConfiguration} config - Plugin configuration * @param {PluginContext} context - Kuzzle plugin context */ async init(config, context) { this.context = context; this.config = lodash_1.default.merge(this.config, config); this.config.labels.nodeId = this.context.accessors.nodeId; this.pipes = { 'server:afterMetrics': async (request) => this.pipeFormatMetrics(request), }; this.hooks = { 'request:onSuccess': this.recordRequest.bind(this), 'request:onError': this.recordRequest.bind(this), }; this.api = { prometheus: { actions: { metrics: { handler: (request) => this.metrics(request), http: [{ verb: 'get', path: 'metrics' }], }, }, } }; this.metricService = new MetricService_1.MetricService(this.config); } /** * On server:afterMetrics hook, format the metrics and send them to the client as Prometheus format * @param {KuzzleRequest} request - Kuzzle request * @returns {KuzzleRequest} */ async pipeFormatMetrics(request) { if (request.getString('format', 'invalid') === 'prometheus' && request.context.connection.protocol === 'http') { // coreMetrics need to be updated with Kuzzle core values before the metrics are sent to the client this.metricService.updateCoreMetrics(request.response.result); request.response.configure({ headers: { 'Content-Type': this.metricService.getPrometheusContentType() }, format: 'raw', }); request.response.result = await this.metricService.getMetrics(); } return request; } /** * Log the response time for the given request in the associated metric * @param {KuzzleRequest} request - Kuzzle request */ recordRequest(request) { this.metricService.recordResponseTime(Date.now() - request.timestamp, { action: request.input.action, controller: request.input.controller, protocol: request.context.connection.protocol, status: request.status }); } /** * Return the metrics in Prometheus format * NOTE: This is an HTTP route for Prometheus installations that do not support HTTP arguments * @param {KuzzleRequest} request - Kuzzle request * @returns {Promise<string>} */ async metrics(request) { if (request.context.connection.protocol === 'http') { const responsePayload = await this.context.accessors.sdk.query({ controller: 'server', action: 'metrics', }); this.metricService.updateCoreMetrics(responsePayload.result); request.response.configure({ headers: { 'Content-Type': this.metricService.getPrometheusContentType() }, format: 'raw', }); return await this.metricService.getMetrics(); } } } exports.PrometheusPlugin = PrometheusPlugin; //# sourceMappingURL=PrometheusPlugin.js.map