diff --git a/.env.example b/.env.example index a3dfdc9..1acc1e3 100644 --- a/.env.example +++ b/.env.example @@ -17,3 +17,6 @@ ALL_IP_DOMAIN="whatever.whatever.com" ALLOW_SELF_SIGNED_SSL= PINNED_FP= CUSTOM_CA_PATH= +INFLUX_HOST= +INFLUX_TOKEN= + diff --git a/influxdb.js b/influxdb.js new file mode 100644 index 0000000..8177e27 --- /dev/null +++ b/influxdb.js @@ -0,0 +1,67 @@ +const { InfluxDB, Point } = require('@influxdata/influxdb-client') + , OpenAPIClientAxios = require('openapi-client-axios').default + , definition = require('./openapi-definition.js') + , { statsData } = require('./controllers/account.js') + , agent = require('./agent.js'); + +if (!process.env.INFLUX_HOST) { + return console.warn('INFLUX_HOST not set, statistics will not be recorded'); +} + +const writeApi = new InfluxDB({ url: process.env.INFLUX_HOST, token: (process.env.INFLUX_TOKEN || null) }).getWriteApi('proxmox', 'proxmoxdb'); +const clusterUrls = process.env.DEFAULT_CLUSTER.split(',').map(u => new URL(u)); +const base64Auth = Buffer.from(`${clusterUrls[0].username}:${clusterUrls[0].password}`).toString("base64"); +const dataPlaneAll = async (operationId, parameters, data, config) => { + const promiseResults = await Promise.all(clusterUrls.map(clusterUrl => { + const singleApi = new OpenAPIClientAxios({ definition, axiosConfigDefaults: { httpsAgent: agent, headers: { 'authorization': `Basic ${base64Auth}` } } }); + const singleApiInstance = singleApi.initSync(); + singleApiInstance.defaults.baseURL = `${clusterUrl.origin}/v2`; + return singleApiInstance[operationId](parameters, data, { ...config, baseUrl: `${clusterUrl.origin}/v2` }); + })); + return promiseResults.map(p => p.data); +}; + +const sendStats = async () => { + try { + const { frontendStats, serverStats } = await statsData(null, { locals: { dataPlaneAll }}, null); + let points = []; + frontendStats.forEach((s, i) => { + const hostname = clusterUrls[i].hostname; + const statPoints = Object.entries(s[0].stats[0].stats) + .map(e => { + return new Point(e[0]) + .tag('type', 'frontend') + .tag('hostname', hostname) + .floatField('value', e[1]); + }); + points = points.concat(statPoints); + }); + serverStats.forEach((host, i) => { + const hostname = clusterUrls[i].hostname; + host.forEach(server => { + server.stats.forEach(ss => { + const statPoints = Object.entries(ss.stats) + .map(e => { + return new Point(e[0]) + .tag('type', 'backend') + .tag('hostname', hostname) + .tag('server_name', ss.name) + .tag('server_address', ss.stats["Address"]) + .floatField('value', e[1]); + }); + points = points.concat(statPoints); + }); + }); + }); + writeApi.writePoints(points) + writeApi.flush() + .then(() => console.log('flushed stats to influxdb')) + .catch((e) => console.error(e)); + + } catch (e) { + console.error('Error writing stats:', e); + } +} +sendStats() +setInterval(sendStats, 30000); + diff --git a/package-lock.json b/package-lock.json index e3fafcc..dc076f4 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,6 +9,7 @@ "version": "1.0.0", "license": "AGPL-3.0-only", "dependencies": { + "@influxdata/influxdb-client": "^1.33.2", "acme-client": "^5.0.0", "bcrypt": "^5.1.0", "body-parser": "^1.20.2", @@ -1225,6 +1226,11 @@ "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==", "dev": true }, + "node_modules/@influxdata/influxdb-client": { + "version": "1.33.2", + "resolved": "https://registry.npmjs.org/@influxdata/influxdb-client/-/influxdb-client-1.33.2.tgz", + "integrity": "sha512-RT5SxH+grHAazo/YK3UTuWK/frPWRM0N7vkrCUyqVprDgQzlLP+bSK4ak2Jv3QVF/pazTnsxWjvtKZdwskV5Xw==" + }, "node_modules/@mapbox/node-pre-gyp": { "version": "1.0.10", "resolved": "https://registry.npmjs.org/@mapbox/node-pre-gyp/-/node-pre-gyp-1.0.10.tgz", diff --git a/package.json b/package.json index e511882..cb2ba79 100644 --- a/package.json +++ b/package.json @@ -14,6 +14,7 @@ "author": "Thomas Lynch (fatchan) ", "license": "AGPL-3.0-only", "dependencies": { + "@influxdata/influxdb-client": "^1.33.2", "acme-client": "^5.0.0", "bcrypt": "^5.1.0", "body-parser": "^1.20.2", diff --git a/server.js b/server.js index 8238533..9a68dae 100644 --- a/server.js +++ b/server.js @@ -18,7 +18,8 @@ const server = require('express') , bodyParser = require('body-parser') , cookieParser = require('cookie-parser') , acme = require('./acme.js') - , db = require('./db.js'); + , db = require('./db.js') + , influx = require('./influxdb.js'); app.prepare() .then(async () => {