thermenlast_exporter/index.js
2025-01-31 22:17:15 +01:00

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`)
})