UNPKG

hyper-instrument

Version:

Instrument services in the hypercore ecosystem

138 lines (120 loc) 3.41 kB
const { isBare } = require('which-runtime') if (isBare) require('bare-process/global') const process = require('process') const HyperswarmStats = require('hyperswarm-stats') const HypercoreStats = require('hypercore-stats') const HyperDhtStats = require('hyperdht-stats') const ReadyResource = require('ready-resource') const DhtPromClient = require('dht-prom-client') const promClient = require('bare-prom-client') class HyperInstrumentation extends ReadyResource { constructor({ swarm, corestore, dht, scraperPublicKey, scraperSecret, prometheusAlias, prometheusServiceName, moduleVersions = null, version = null }) { super() if (swarm && dht) throw new Error('Exactly 1 of dht or swarm should be specified') if (swarm) dht = swarm.dht if (!moduleVersions) { moduleVersions = [ 'udx-native', 'dht-rpc', 'hyperdht', 'hyperswarm', 'hypercore', 'corestore', 'hyperbee', 'autobase', 'hyperdb' ] } promClient.collectDefaultMetrics() if (version) registerPackageVersion(version) registerModuleVersions(moduleVersions) registerProcessId() this.swarmStats = null this.dhtStats = null if (swarm) { this.swarmStats = new HyperswarmStats(swarm) this.swarmStats.registerPrometheusMetrics(promClient) } else { this.dhtStats = new HyperDhtStats(dht) this.dhtStats.registerPrometheusMetrics(promClient) } this.hypercoreStats = null if (corestore) { this.hypercoreStats = HypercoreStats.fromCorestore(corestore) this.hypercoreStats.registerPrometheusMetrics(promClient) } this.dhtPromClient = new DhtPromClient( dht, promClient, scraperPublicKey, prometheusAlias, scraperSecret, prometheusServiceName ) } get promClient() { return this.dhtPromClient.promClient } async _open() { await this.dhtPromClient.ready() } async _close() { await this.dhtPromClient.close() } registerLogger(logger = console) { this.dhtPromClient.registerLogger(logger) if (this.hypercoreStats) { this.hypercoreStats.on('internal-error', (e) => { console.warn(`Hypercore stats internal error: ${e.stack}`) }) } } } function registerPackageVersion(version) { // Gauges expect a number, so we set the version as label instead return new promClient.Gauge({ name: 'package_version', help: 'Package version in config.json', labelNames: ['version'], collect() { this.labels(version).set(1) } }) } function registerModuleVersions(names) { for (const name of names) { const normName = name.replace('@', '').replaceAll('/', '_').replaceAll('-', '_') try { const v = require(`${name}/package.json`).version new promClient.Gauge({ // eslint-disable-line no-new name: `${normName}_version`, help: `${name} version`, labelNames: [`${normName}_version`], collect() { this.labels(v).set(1) } }) } catch {} // dependency not found or version can't be extracted } } function registerProcessId() { return new promClient.Gauge({ name: 'process_pid', help: 'Process id on the operating system', collect() { this.set(process.pid) } }) } module.exports = HyperInstrumentation