1*912701f9SAndroid Build Coastguard Worker/* 2*912701f9SAndroid Build Coastguard Worker * Copyright (C) 2929, Unicode, Inc. 3*912701f9SAndroid Build Coastguard Worker * For terms of use, see http://www.unicode.org/terms_of_use.html 4*912701f9SAndroid Build Coastguard Worker */ 5*912701f9SAndroid Build Coastguard Worker 6*912701f9SAndroid Build Coastguard Workerconst express = require('express'); 7*912701f9SAndroid Build Coastguard Workerconst process = require('process'); 8*912701f9SAndroid Build Coastguard Workerconst server = express(); 9*912701f9SAndroid Build Coastguard Workerconst client = require('prom-client'); 10*912701f9SAndroid Build Coastguard Workerconst bent = require('bent'); 11*912701f9SAndroid Build Coastguard Workerconst getJson = bent('json'); 12*912701f9SAndroid Build Coastguard Workerconst config = require('./config.json'); 13*912701f9SAndroid Build Coastguard Workerconst {register} = client; // global registry 14*912701f9SAndroid Build Coastguard Worker 15*912701f9SAndroid Build Coastguard Workerconst items = { 16*912701f9SAndroid Build Coastguard Worker responses: new client.Counter({ 17*912701f9SAndroid Build Coastguard Worker name: 'surveytool_exporter_responses', 18*912701f9SAndroid Build Coastguard Worker help: 'Number of pages served by this exporter' 19*912701f9SAndroid Build Coastguard Worker }), 20*912701f9SAndroid Build Coastguard Worker oks: new client.Counter({ 21*912701f9SAndroid Build Coastguard Worker name: 'surveytool_exporter_oks', 22*912701f9SAndroid Build Coastguard Worker help: 'Number of OK fetches', 23*912701f9SAndroid Build Coastguard Worker labelNames: ['instance'] 24*912701f9SAndroid Build Coastguard Worker }), 25*912701f9SAndroid Build Coastguard Worker fails: new client.Counter({ 26*912701f9SAndroid Build Coastguard Worker name: 'surveytool_exporter_fails', 27*912701f9SAndroid Build Coastguard Worker help: 'Number of failed fetches', 28*912701f9SAndroid Build Coastguard Worker labelNames: ['instance'] 29*912701f9SAndroid Build Coastguard Worker }), 30*912701f9SAndroid Build Coastguard Worker ok: new client.Gauge({ 31*912701f9SAndroid Build Coastguard Worker name: 'surveytool_ok', 32*912701f9SAndroid Build Coastguard Worker help: '1 if the surveytool is ok, otherwise 0', 33*912701f9SAndroid Build Coastguard Worker labelNames: ['instance'] 34*912701f9SAndroid Build Coastguard Worker }), 35*912701f9SAndroid Build Coastguard Worker isSetup: new client.Gauge({ 36*912701f9SAndroid Build Coastguard Worker name: 'surveytool_setup', 37*912701f9SAndroid Build Coastguard Worker help: '1 if the surveytool is setup, otherwise 0', 38*912701f9SAndroid Build Coastguard Worker labelNames: ['instance'] 39*912701f9SAndroid Build Coastguard Worker }), 40*912701f9SAndroid Build Coastguard Worker isBusted: new client.Gauge({ 41*912701f9SAndroid Build Coastguard Worker name: 'surveytool_busted', 42*912701f9SAndroid Build Coastguard Worker help: '1 if the surveytool is busted, otherwise 0', 43*912701f9SAndroid Build Coastguard Worker labelNames: ['instance'/*, 'err'*/] 44*912701f9SAndroid Build Coastguard Worker }), 45*912701f9SAndroid Build Coastguard Worker fetchTime: new client.Gauge({ 46*912701f9SAndroid Build Coastguard Worker name: 'surveytool_fetchTime', 47*912701f9SAndroid Build Coastguard Worker help: 'time of successful fetch', 48*912701f9SAndroid Build Coastguard Worker labelNames: ['instance'] 49*912701f9SAndroid Build Coastguard Worker }), 50*912701f9SAndroid Build Coastguard Worker fetchErr: new client.Gauge({ 51*912701f9SAndroid Build Coastguard Worker name: 'surveytool_fetchErr', 52*912701f9SAndroid Build Coastguard Worker help: 'error code on failed fetch, or 200', 53*912701f9SAndroid Build Coastguard Worker labelNames: ['instance'/*, 'err'*/] 54*912701f9SAndroid Build Coastguard Worker }), 55*912701f9SAndroid Build Coastguard Worker pages: new client.Gauge({ 56*912701f9SAndroid Build Coastguard Worker name: 'surveytool_pages', 57*912701f9SAndroid Build Coastguard Worker help: 'page count', 58*912701f9SAndroid Build Coastguard Worker labelNames: ['instance'] 59*912701f9SAndroid Build Coastguard Worker }), 60*912701f9SAndroid Build Coastguard Worker users: new client.Gauge({ 61*912701f9SAndroid Build Coastguard Worker name: 'surveytool_users', 62*912701f9SAndroid Build Coastguard Worker help: 'user count', 63*912701f9SAndroid Build Coastguard Worker labelNames: ['instance'] 64*912701f9SAndroid Build Coastguard Worker }), 65*912701f9SAndroid Build Coastguard Worker stamp: new client.Gauge({ 66*912701f9SAndroid Build Coastguard Worker name: 'surveytool_stamp', 67*912701f9SAndroid Build Coastguard Worker help: 'survey running stamp', 68*912701f9SAndroid Build Coastguard Worker labelNames: ['instance' /*, 69*912701f9SAndroid Build Coastguard Worker 'phase', 'sysprocs', 'environment', 'currev', 'newVersion'*/] 70*912701f9SAndroid Build Coastguard Worker }), 71*912701f9SAndroid Build Coastguard Worker memtotal: new client.Gauge({ 72*912701f9SAndroid Build Coastguard Worker name: 'surveytool_memtotal', 73*912701f9SAndroid Build Coastguard Worker help: 'total memory in process', 74*912701f9SAndroid Build Coastguard Worker labelNames: ['instance'] 75*912701f9SAndroid Build Coastguard Worker }), 76*912701f9SAndroid Build Coastguard Worker memfree: new client.Gauge({ 77*912701f9SAndroid Build Coastguard Worker name: 'surveytool_memfree', 78*912701f9SAndroid Build Coastguard Worker help: 'total free memory', 79*912701f9SAndroid Build Coastguard Worker labelNames: ['instance'] 80*912701f9SAndroid Build Coastguard Worker }), 81*912701f9SAndroid Build Coastguard Worker dbused: new client.Gauge({ 82*912701f9SAndroid Build Coastguard Worker name: 'surveytool_dbused', 83*912701f9SAndroid Build Coastguard Worker help: 'db queries used', 84*912701f9SAndroid Build Coastguard Worker labelNames: ['instance'] 85*912701f9SAndroid Build Coastguard Worker }), 86*912701f9SAndroid Build Coastguard Worker sysload: new client.Gauge({ 87*912701f9SAndroid Build Coastguard Worker name: 'surveytool_sysload', 88*912701f9SAndroid Build Coastguard Worker help: 'system load, if available', 89*912701f9SAndroid Build Coastguard Worker labelNames: ['instance'] 90*912701f9SAndroid Build Coastguard Worker }), 91*912701f9SAndroid Build Coastguard Worker}; 92*912701f9SAndroid Build Coastguard Worker 93*912701f9SAndroid Build Coastguard Workerasync function update(e) { 94*912701f9SAndroid Build Coastguard Worker const [instance, url] = e; 95*912701f9SAndroid Build Coastguard Worker try { 96*912701f9SAndroid Build Coastguard Worker const res = await getJson(url); 97*912701f9SAndroid Build Coastguard Worker items.oks.inc({instance}); 98*912701f9SAndroid Build Coastguard Worker items.fetchErr.set({ instance }, 200); 99*912701f9SAndroid Build Coastguard Worker items.fetchTime.set({ instance }, new Date().getTime()/1000); 100*912701f9SAndroid Build Coastguard Worker items.ok.set({instance}, Number(res.SurveyOK)); 101*912701f9SAndroid Build Coastguard Worker items.isSetup.set({instance}, Number(res.isSetup)); 102*912701f9SAndroid Build Coastguard Worker if(res.status) { 103*912701f9SAndroid Build Coastguard Worker const{phase, memtotal, sysprocs, isBusted, isUnofficial, lockOut, 104*912701f9SAndroid Build Coastguard Worker users, uptime, memfree, environment, pages, specialHeader, currev, 105*912701f9SAndroid Build Coastguard Worker dbopen, surveyRunningStamp, observers, dbused,sysload, isSetup, newVersion} = res.status; 106*912701f9SAndroid Build Coastguard Worker items.pages.set({instance}, Number(pages)); 107*912701f9SAndroid Build Coastguard Worker items.users.set({instance}, Number(users)); 108*912701f9SAndroid Build Coastguard Worker items.memtotal.set({instance}, Number(memtotal)); 109*912701f9SAndroid Build Coastguard Worker items.memfree.set({instance}, Number(memfree)); 110*912701f9SAndroid Build Coastguard Worker items.dbused.set({instance}, Number(dbused)); 111*912701f9SAndroid Build Coastguard Worker items.sysload.set({instance}, Number(sysload)); 112*912701f9SAndroid Build Coastguard Worker items.stamp.set({instance /*, 113*912701f9SAndroid Build Coastguard Worker phase, sysprocs, environment, currev, newVersion*/}, 114*912701f9SAndroid Build Coastguard Worker surveyRunningStamp); 115*912701f9SAndroid Build Coastguard Worker if(isBusted) { 116*912701f9SAndroid Build Coastguard Worker items.isBusted.set({instance/*, err: isBusted*/}, Number(1)); 117*912701f9SAndroid Build Coastguard Worker } else { 118*912701f9SAndroid Build Coastguard Worker items.isBusted.set({instance/*, err: (res.err || '')*/}, Number(res.isBusted)); 119*912701f9SAndroid Build Coastguard Worker } 120*912701f9SAndroid Build Coastguard Worker } else { 121*912701f9SAndroid Build Coastguard Worker items.isBusted.set({instance/*, err: (res.err || '')*/}, Number(res.isBusted)); 122*912701f9SAndroid Build Coastguard Worker } 123*912701f9SAndroid Build Coastguard Worker } catch(ex) { 124*912701f9SAndroid Build Coastguard Worker items.fails.inc({instance}); 125*912701f9SAndroid Build Coastguard Worker items.fetchErr.set({ instance /*, err: ex.toString()*/ }, 999); 126*912701f9SAndroid Build Coastguard Worker } 127*912701f9SAndroid Build Coastguard Worker} 128*912701f9SAndroid Build Coastguard Worker 129*912701f9SAndroid Build Coastguard Workerasync function updateAll() { 130*912701f9SAndroid Build Coastguard Worker return Promise.all(Object.entries(config.instances) 131*912701f9SAndroid Build Coastguard Worker .map(e => update(e))); 132*912701f9SAndroid Build Coastguard Worker} 133*912701f9SAndroid Build Coastguard Worker 134*912701f9SAndroid Build Coastguard Workerserver.get('/metrics', async (req, res) => { 135*912701f9SAndroid Build Coastguard Worker items.responses.inc(); 136*912701f9SAndroid Build Coastguard Worker res.contentType(register.contentType); 137*912701f9SAndroid Build Coastguard Worker await updateAll(); 138*912701f9SAndroid Build Coastguard Worker res.end(register.metrics()); 139*912701f9SAndroid Build Coastguard Worker}); 140*912701f9SAndroid Build Coastguard Worker 141*912701f9SAndroid Build Coastguard Workerconst port = process.env.PORT || config.port || 3000; 142*912701f9SAndroid Build Coastguard Worker 143*912701f9SAndroid Build Coastguard Workerserver.listen(port, () => { 144*912701f9SAndroid Build Coastguard Worker console.log('ST exporter listening on port ' + port); 145*912701f9SAndroid Build Coastguard Worker});