111 lines
3.4 KiB
JavaScript
111 lines
3.4 KiB
JavaScript
/* istanbul ignore file */
|
|
/* eslint-disable no-unused-vars */
|
|
'use strict'
|
|
|
|
const knex = require('../db/knex')
|
|
const prometheusClient = require('prom-client')
|
|
|
|
let metricFree = null
|
|
let metricUsed = null
|
|
let metricPendingCreates = null
|
|
let metricPendingValidations = null
|
|
let metricRemainingCapacity = null
|
|
let metricPendingAquires = null
|
|
let metricQueryDuration = null
|
|
let metricQueryErrors = null
|
|
|
|
const queryStartTime = {}
|
|
const postgresMaxConnections =
|
|
parseInt(process.env.POSTGRES_MAX_CONNECTIONS_SERVER) || 4
|
|
|
|
module.exports = {
|
|
initKnexPrometheusMetrics() {
|
|
metricFree = new prometheusClient.Gauge({
|
|
name: 'speckle_server_knex_free',
|
|
help: 'Number of free DB connections',
|
|
collect() {
|
|
this.set(knex.client.pool.numFree())
|
|
}
|
|
})
|
|
|
|
metricUsed = new prometheusClient.Gauge({
|
|
name: 'speckle_server_knex_used',
|
|
help: 'Number of used DB connections',
|
|
collect() {
|
|
this.set(knex.client.pool.numUsed())
|
|
}
|
|
})
|
|
|
|
metricPendingAquires = new prometheusClient.Gauge({
|
|
name: 'speckle_server_knex_pending',
|
|
help: 'Number of pending DB connection aquires',
|
|
collect() {
|
|
this.set(knex.client.pool.numPendingAcquires())
|
|
}
|
|
})
|
|
|
|
metricPendingCreates = new prometheusClient.Gauge({
|
|
name: 'speckle_server_knex_pending_creates',
|
|
help: 'Number of pending DB connection creates',
|
|
collect() {
|
|
this.set(knex.client.pool.numPendingCreates())
|
|
}
|
|
})
|
|
|
|
metricPendingValidations = new prometheusClient.Gauge({
|
|
name: 'speckle_server_knex_pending_validations',
|
|
help: 'Number of pending DB connection validations. This is a state between pending acquisition and acquiring a connection.',
|
|
collect() {
|
|
this.set(knex.client.pool.numPendingValidations())
|
|
}
|
|
})
|
|
|
|
metricRemainingCapacity = new prometheusClient.Gauge({
|
|
name: 'speckle_server_knex_remaining_capacity',
|
|
help: 'Remaining capacity of the DB connection pool',
|
|
collect() {
|
|
const postgresMaxConnections =
|
|
parseInt(process.env.POSTGRES_MAX_CONNECTIONS_SERVER) || 4
|
|
const demand =
|
|
knex.client.pool.numUsed() +
|
|
knex.client.pool.numPendingCreates() +
|
|
knex.client.pool.numPendingValidations() +
|
|
knex.client.pool.numPendingAcquires()
|
|
|
|
this.set(Math.max(postgresMaxConnections - demand, 0))
|
|
}
|
|
})
|
|
|
|
metricQueryDuration = new prometheusClient.Summary({
|
|
name: 'speckle_server_knex_query_duration',
|
|
help: 'Summary of the DB query durations in seconds'
|
|
})
|
|
|
|
metricQueryErrors = new prometheusClient.Counter({
|
|
name: 'speckle_server_knex_query_errors',
|
|
help: 'Number of DB queries with errors'
|
|
})
|
|
|
|
knex.on('query', (data) => {
|
|
const queryId = data.__knexQueryUid + ''
|
|
queryStartTime[queryId] = Date.now()
|
|
})
|
|
|
|
knex.on('query-response', (data, obj, builder) => {
|
|
const queryId = obj.__knexQueryUid + ''
|
|
const durationSec = (Date.now() - queryStartTime[queryId]) / 1000
|
|
delete queryStartTime[queryId]
|
|
if (!isNaN(durationSec)) metricQueryDuration.observe(durationSec)
|
|
})
|
|
|
|
knex.on('query-error', (err, querySpec) => {
|
|
const queryId = querySpec.__knexQueryUid + ''
|
|
const durationSec = (Date.now() - queryStartTime[queryId]) / 1000
|
|
delete queryStartTime[queryId]
|
|
|
|
if (!isNaN(durationSec)) metricQueryDuration.observe(durationSec)
|
|
metricQueryErrors.inc()
|
|
})
|
|
}
|
|
}
|