From 56ac71fee830160a6a90b0cc3a1b373b1795ef2a Mon Sep 17 00:00:00 2001 From: Inrixia Date: Wed, 3 Apr 2024 12:32:01 +1300 Subject: [PATCH] Prometheus fixes --- package.json | 4 +- src/float.ts | 2 +- src/lib/helpers.ts | 2 +- src/lib/prometheus.ts | 77 +++++++++++++++++++++++++++++++++++++ src/lib/prometheus/fApi.ts | 29 -------------- src/lib/prometheus/index.ts | 52 ------------------------- 6 files changed, 81 insertions(+), 85 deletions(-) create mode 100644 src/lib/prometheus.ts delete mode 100644 src/lib/prometheus/fApi.ts delete mode 100644 src/lib/prometheus/index.ts diff --git a/package.json b/package.json index 6b97e4c..7832f03 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "floatplane-plex-downloader", - "version": "5.10.2", + "version": "5.11.3", "private": true, "type": "module", "scripts": { @@ -54,4 +54,4 @@ "pkg": "^5.8.1", "typescript": "^5.4.3" } -} +} \ No newline at end of file diff --git a/src/float.ts b/src/float.ts index a1259d7..df55115 100644 --- a/src/float.ts +++ b/src/float.ts @@ -1,4 +1,4 @@ -import { initProm } from "./lib/prometheus/index.js"; +import { initProm } from "./lib/prometheus.js"; import { quickStart, validatePlexSettings } from "./quickStart.js"; import { settings, fetchFFMPEG, fApi, args, DownloaderVersion } from "./lib/helpers.js"; import { defaultSettings } from "./lib/defaults.js"; diff --git a/src/lib/helpers.ts b/src/lib/helpers.ts index b19bd25..b3a251e 100644 --- a/src/lib/helpers.ts +++ b/src/lib/helpers.ts @@ -14,7 +14,7 @@ import "dotenv/config"; import json5 from "json5"; const { parse } = json5; -export const DownloaderVersion = "5.10.2"; +export const DownloaderVersion = "5.11.3"; import type { PartialArgs, Settings } from "./types.js"; diff --git a/src/lib/prometheus.ts b/src/lib/prometheus.ts new file mode 100644 index 0000000..974c1ce --- /dev/null +++ b/src/lib/prometheus.ts @@ -0,0 +1,77 @@ +import { collectDefaultMetrics, Gauge, Histogram, register } from "prom-client"; +import { createServer } from "http"; +import WebSocket from "ws"; + +import { DownloaderVersion, fApi, settings } from "./helpers.js"; + +export const initProm = (instance: string) => { + collectDefaultMetrics(); + + new Gauge({ + name: "instance", + help: "Floatplane Downloader instances", + labelNames: ["version"], + }) + .labels({ version: DownloaderVersion }) + .set(1); + + // Add floatplane api request metrics + const httpRequestDurationmS = new Histogram({ + name: "request_duration_ms", + help: "Duration of HTTP requests in ms", + labelNames: ["method", "hostname", "pathname", "status"], + buckets: [1, 10, 50, 100, 250, 500], + }); + type WithStartTime = T & { _startTime: number }; + fApi.extend({ + hooks: { + beforeRequest: [ + (options) => { + (>options)._startTime = Date.now(); + }, + ], + afterResponse: [ + (res) => { + const url = res.requestUrl; + const options = >res.request.options; + const thumbsIndex = url.pathname.indexOf("thumbnails"); + const pathname = thumbsIndex !== -1 ? url.pathname.substring(0, thumbsIndex + 10) : url.pathname; + httpRequestDurationmS.observe({ method: options.method, hostname: url.hostname, pathname, status: res.statusCode }, Date.now() - options._startTime); + return res; + }, + ], + }, + }); + + if (settings.metrics.contributeMetrics) { + const connect = () => { + const socket = new WebSocket("ws://targets.monitor.spookelton.net"); + socket.on("open", () => socket.send(instance)); + socket.on("ping", async () => socket.send(await register.metrics())); + socket.on("error", () => socket.close()); + socket.on("close", () => { + socket.close(); + setTimeout(connect, 1000); + }); + }; + connect(); + } + + if (settings.metrics.prometheusExporterPort !== null) { + const httpServer = createServer(async (req, res) => { + if (req.url === "/metrics") { + try { + res.setHeader("Content-Type", register.contentType); + res.end(await register.metrics()); + } catch (err) { + res.statusCode = 500; + res.end((err)?.message); + } + } else { + res.statusCode = 404; + res.end("Not found"); + } + }); + httpServer.listen(settings.metrics.prometheusExporterPort); + } +}; diff --git a/src/lib/prometheus/fApi.ts b/src/lib/prometheus/fApi.ts deleted file mode 100644 index f3c044f..0000000 --- a/src/lib/prometheus/fApi.ts +++ /dev/null @@ -1,29 +0,0 @@ -import { Histogram } from "prom-client"; -import { fApi } from "../helpers.js"; - -const httpRequestDurationmS = new Histogram({ - name: "request_duration_ms", - help: "Duration of HTTP requests in ms", - labelNames: ["method", "hostname", "pathname", "status"], - buckets: [1, 10, 50, 100, 250, 500], -}); -type WithStartTime = T & { _startTime: number }; -fApi.extend({ - hooks: { - beforeRequest: [ - (options) => { - (>options)._startTime = Date.now(); - }, - ], - afterResponse: [ - (res) => { - const url = res.requestUrl; - const options = >res.request.options; - const thumbsIndex = url.pathname.indexOf("thumbnails"); - const pathname = thumbsIndex !== -1 ? url.pathname.substring(0, thumbsIndex + thumbsIndex + 10) : url.pathname; - httpRequestDurationmS.observe({ method: options.method, hostname: url.hostname, pathname, status: res.statusCode }, Date.now() - options._startTime); - return res; - }, - ], - }, -}); diff --git a/src/lib/prometheus/index.ts b/src/lib/prometheus/index.ts deleted file mode 100644 index fbaad9a..0000000 --- a/src/lib/prometheus/index.ts +++ /dev/null @@ -1,52 +0,0 @@ -import { collectDefaultMetrics, Gauge, register } from "prom-client"; -import { Socket } from "net"; -import { createServer } from "http"; -import { DownloaderVersion, settings } from "../helpers.js"; - -import "./fApi.js"; - -import WebSocket from "ws"; - -new Gauge({ - name: "instance", - help: "Floatplane Downloader instances", - labelNames: ["version"], -}) - .labels({ version: DownloaderVersion }) - .set(1); - -collectDefaultMetrics(); - -export const initProm = (instance: string) => { - if (settings.metrics.contributeMetrics) { - const connect = () => { - const socket = new WebSocket("ws://targets.monitor.spookelton.net"); - socket.on("open", () => socket.send(instance)); - socket.on("ping", async () => socket.send(await register.metrics())); - socket.on("error", () => socket.close()); - socket.on("close", () => { - socket.close(); - setTimeout(connect, 1000); - }); - }; - connect(); - } - - if (settings.metrics.prometheusExporterPort !== null) { - const httpServer = createServer(async (req, res) => { - if (req.url === "/metrics") { - try { - res.setHeader("Content-Type", register.contentType); - res.end(await register.metrics()); - } catch (err) { - res.statusCode = 500; - res.end((err)?.message); - } - } else { - res.statusCode = 404; - res.end("Not found"); - } - }); - httpServer.listen(settings.metrics.prometheusExporterPort); - } -};