/** * NATS monitoring endpoint collector. * Enable: PEARDATA_NATS=1 * URL: PEARDATA_NATS_URL=http://127.0.0.1:8222 */ import { CollectorPlugin } from './plugin.js' import { registerChart } from '../../../shared/metrics.js' export function isNatsEnabled() { const v = process.env.PEARDATA_NATS return v === '1' || v === 'on' || v === 'true' } function base() { return (process.env.PEARDATA_NATS_URL || 'http://127.0.0.1:8222').replace(/\/$/, '') } export class NatsCollector extends CollectorPlugin { constructor() { super({ name: 'nats' }) } isEnabled() { return isNatsEnabled() } async collect() { const ts = Date.now() registerChart({ id: 'nats.up', name: 'nats.up', context: 'nats.up', title: 'NATS up', units: 'boolean', family: 'nats', chartType: 'line', priority: 8850, plugin: 'nats', dimensions: [{ id: 'up', name: 'up', algorithm: 'absolute' }], }) try { const res = await fetch(`${base()}/varz`, { signal: AbortSignal.timeout(2000) }) if (!res.ok) throw new Error(String(res.status)) const j = await res.json() registerChart({ id: 'nats.connections', name: 'nats.connections', context: 'nats.connections', title: 'NATS connections', units: 'connections', family: 'nats', chartType: 'line', priority: 8860, plugin: 'nats', dimensions: [ { id: 'connections', name: 'connections', algorithm: 'absolute' }, { id: 'routes', name: 'routes', algorithm: 'absolute' }, { id: 'remotes', name: 'remotes', algorithm: 'absolute' }, ], }) registerChart({ id: 'nats.messages', name: 'nats.messages', context: 'nats.messages', title: 'NATS messages', units: 'messages', family: 'nats', chartType: 'line', priority: 8870, plugin: 'nats', dimensions: [ { id: 'in_msgs', name: 'in_msgs', algorithm: 'absolute' }, { id: 'out_msgs', name: 'out_msgs', algorithm: 'absolute' }, ], }) return [ { chart: 'nats.up', context: 'nats.up', ts, values: { up: 1 } }, { chart: 'nats.connections', context: 'nats.connections', ts, values: { connections: j.connections || 0, routes: j.routes || 0, remotes: j.remotes || 0, }, }, { chart: 'nats.messages', context: 'nats.messages', ts, values: { in_msgs: j.in_msgs || 0, out_msgs: j.out_msgs || 0 }, }, ] } catch { return [{ chart: 'nats.up', context: 'nats.up', ts, values: { up: 0 } }] } } } let singleton = null export function getNatsCollector() { if (!singleton) singleton = new NatsCollector() return singleton }