68 lines
2.3 KiB
JavaScript
68 lines
2.3 KiB
JavaScript
'use strict';
|
|
|
|
const http = require('http')
|
|
const DOM = require('jsdom').JSDOM
|
|
const prom = require('prom-client')
|
|
const memoize = require('memoizee')
|
|
|
|
const listenAddr = process.env.LISTEN_ADDR || '127.0.0.1:3000'
|
|
const cacheSeconds = process.env.CACHE_SECONDS ? Number(process.env.CACHE_SECONDS) : 118
|
|
|
|
const collectionError = new prom.Gauge({
|
|
name: 'place_utilization_error',
|
|
help: 'if collection failed for a place value is 1, otherwise 0 ',
|
|
labelNames: ['place'],
|
|
})
|
|
|
|
const collectTherme = memoize(async function() {
|
|
console.log(' fetching current utilization from carolus-thermen.de')
|
|
const res = await fetch('https://carolus-thermen.de/auslastung')
|
|
const html = await res.text()
|
|
|
|
const dom = new DOM(html)
|
|
const matches = Array.from(dom.window.document.querySelectorAll('.modulAuslastugsGrid span'))
|
|
console.log(` ${matches.map(x => x.innerHTML)}`)
|
|
if (matches.length !== 3)
|
|
throw new Error('unexpected html contents')
|
|
|
|
const [thermalbad, saunawelt, parkhaus] = matches.map(x => Number.parseInt(x.innerHTML.split('%')[0]))
|
|
const place = 'Carolus-Thermen'
|
|
this.set({ place, resource: 'Thermalbad' }, thermalbad)
|
|
this.set({ place, resource: 'Saunawelt' }, saunawelt)
|
|
this.set({ place, resource: 'Parkhaus' }, parkhaus)
|
|
}, {
|
|
maxAge: cacheSeconds*1000,
|
|
promise: true,
|
|
})
|
|
|
|
const utilization = new prom.Gauge({
|
|
name: 'place_utilization',
|
|
help: 'utilized capacity of a place\'s resource in percent (0-100)',
|
|
labelNames: ['place', 'resource'],
|
|
async collect () {
|
|
const place = 'Carolus-Thermen'
|
|
try {
|
|
await collectTherme.apply(this)
|
|
collectionError.set({ place }, 0)
|
|
} catch (err) {
|
|
collectionError.set({ place }, 1)
|
|
console.log(` error during metrics collection: ${err}`)
|
|
}
|
|
},
|
|
})
|
|
|
|
const server = http.createServer(async (req, res) => {
|
|
console.log(`received request ${req.method} ${req.url} from ${req.socket.remoteAddress}`)
|
|
try {
|
|
const metrics = await prom.register.metrics()
|
|
res.writeHead(200, { 'Content-Type': prom.register.contentType })
|
|
res.end(metrics)
|
|
} catch (err) {
|
|
res.writeHead(500).end(`${err}`)
|
|
}
|
|
})
|
|
|
|
const [addr, port] = listenAddr.split(':')
|
|
server.listen(Number.parseInt(port), addr, (err) => {
|
|
console.log(`Server listening on ${listenAddr}, metrics exposed on /metrics endpoint`)
|
|
})
|