| /* |
| * Copyright (C) 2929, Unicode, Inc. |
| * For terms of use, see http://www.unicode.org/terms_of_use.html |
| */ |
| |
| const express = require('express'); |
| const process = require('process'); |
| const server = express(); |
| const client = require('prom-client'); |
| const bent = require('bent'); |
| const getJson = bent('json'); |
| const config = require('./config.json'); |
| const {register} = client; // global registry |
| |
| const items = { |
| responses: new client.Counter({ |
| name: 'surveytool_exporter_responses', |
| help: 'Number of pages served by this exporter' |
| }), |
| oks: new client.Counter({ |
| name: 'surveytool_exporter_oks', |
| help: 'Number of OK fetches', |
| labelNames: ['instance'] |
| }), |
| fails: new client.Counter({ |
| name: 'surveytool_exporter_fails', |
| help: 'Number of failed fetches', |
| labelNames: ['instance'] |
| }), |
| ok: new client.Gauge({ |
| name: 'surveytool_ok', |
| help: '1 if the surveytool is ok, otherwise 0', |
| labelNames: ['instance'] |
| }), |
| isSetup: new client.Gauge({ |
| name: 'surveytool_setup', |
| help: '1 if the surveytool is setup, otherwise 0', |
| labelNames: ['instance'] |
| }), |
| isBusted: new client.Gauge({ |
| name: 'surveytool_busted', |
| help: '1 if the surveytool is busted, otherwise 0', |
| labelNames: ['instance'/*, 'err'*/] |
| }), |
| fetchTime: new client.Gauge({ |
| name: 'surveytool_fetchTime', |
| help: 'time of successful fetch', |
| labelNames: ['instance'] |
| }), |
| fetchErr: new client.Gauge({ |
| name: 'surveytool_fetchErr', |
| help: 'error code on failed fetch, or 200', |
| labelNames: ['instance'/*, 'err'*/] |
| }), |
| pages: new client.Gauge({ |
| name: 'surveytool_pages', |
| help: 'page count', |
| labelNames: ['instance'] |
| }), |
| users: new client.Gauge({ |
| name: 'surveytool_users', |
| help: 'user count', |
| labelNames: ['instance'] |
| }), |
| stamp: new client.Gauge({ |
| name: 'surveytool_stamp', |
| help: 'survey running stamp', |
| labelNames: ['instance' /*, |
| 'phase', 'sysprocs', 'environment', 'currev', 'newVersion'*/] |
| }), |
| memtotal: new client.Gauge({ |
| name: 'surveytool_memtotal', |
| help: 'total memory in process', |
| labelNames: ['instance'] |
| }), |
| memfree: new client.Gauge({ |
| name: 'surveytool_memfree', |
| help: 'total free memory', |
| labelNames: ['instance'] |
| }), |
| dbused: new client.Gauge({ |
| name: 'surveytool_dbused', |
| help: 'db queries used', |
| labelNames: ['instance'] |
| }), |
| sysload: new client.Gauge({ |
| name: 'surveytool_sysload', |
| help: 'system load, if available', |
| labelNames: ['instance'] |
| }), |
| }; |
| |
| async function update(e) { |
| const [instance, url] = e; |
| try { |
| const res = await getJson(url); |
| items.oks.inc({instance}); |
| items.fetchErr.set({ instance }, 200); |
| items.fetchTime.set({ instance }, new Date().getTime()/1000); |
| items.ok.set({instance}, Number(res.SurveyOK)); |
| items.isSetup.set({instance}, Number(res.isSetup)); |
| if(res.status) { |
| const{phase, memtotal, sysprocs, isBusted, isUnofficial, lockOut, |
| users, uptime, memfree, environment, pages, specialHeader, currev, |
| dbopen, surveyRunningStamp, observers, dbused,sysload, isSetup, newVersion} = res.status; |
| items.pages.set({instance}, Number(pages)); |
| items.users.set({instance}, Number(users)); |
| items.memtotal.set({instance}, Number(memtotal)); |
| items.memfree.set({instance}, Number(memfree)); |
| items.dbused.set({instance}, Number(dbused)); |
| items.sysload.set({instance}, Number(sysload)); |
| items.stamp.set({instance /*, |
| phase, sysprocs, environment, currev, newVersion*/}, |
| surveyRunningStamp); |
| if(isBusted) { |
| items.isBusted.set({instance/*, err: isBusted*/}, Number(1)); |
| } else { |
| items.isBusted.set({instance/*, err: (res.err || '')*/}, Number(res.isBusted)); |
| } |
| } else { |
| items.isBusted.set({instance/*, err: (res.err || '')*/}, Number(res.isBusted)); |
| } |
| } catch(ex) { |
| items.fails.inc({instance}); |
| items.fetchErr.set({ instance /*, err: ex.toString()*/ }, 999); |
| } |
| } |
| |
| async function updateAll() { |
| return Promise.all(Object.entries(config.instances) |
| .map(e => update(e))); |
| } |
| |
| server.get('/metrics', async (req, res) => { |
| items.responses.inc(); |
| res.contentType(register.contentType); |
| await updateAll(); |
| res.end(register.metrics()); |
| }); |
| |
| const port = process.env.PORT || config.port || 3000; |
| |
| server.listen(port, () => { |
| console.log('ST exporter listening on port ' + port); |
| }); |