Skip to content

Commit

Permalink
Organise prometheus exporters to properly initalize
Browse files Browse the repository at this point in the history
  • Loading branch information
Inrixia committed Apr 3, 2024
1 parent bf9584c commit 5c04c93
Show file tree
Hide file tree
Showing 4 changed files with 49 additions and 48 deletions.
2 changes: 1 addition & 1 deletion package.json
@@ -1,6 +1,6 @@
{
"name": "floatplane-plex-downloader",
"version": "5.11.3",
"version": "5.11.4",
"private": true,
"type": "module",
"scripts": {
Expand Down
14 changes: 7 additions & 7 deletions src/Downloader.ts
Expand Up @@ -33,16 +33,16 @@ const summaryStats: { [key: string]: { totalMB: number; downloadedMB: number; do
let AvalibleDeliverySlots = DownloadThreads;
const DownloadQueue: (() => void)[] = [];

const promVideosQueued = new Gauge({
const promQueued = new Gauge({
name: "queued",
help: "Videos waiting to download",
});
const promVideoErrors = new Counter({
const promErrors = new Counter({
name: "errors",
help: "Video errors",
labelNames: ["message"],
});
const promVideosDownloadedTotal = new Counter({
const promDownloadedTotal = new Counter({
name: "downloaded_total",
help: "Videos downloaded",
});
Expand All @@ -53,7 +53,7 @@ const promDownloadedBytesTotal = new Counter({

const getDownloadSempahore = async () => {
totalVideos++;
promVideosQueued.inc();
promQueued.inc();
// If there is an available request slot, proceed immediately
if (AvalibleDeliverySlots > 0) return AvalibleDeliverySlots--;

Expand All @@ -63,7 +63,7 @@ const getDownloadSempahore = async () => {

const releaseDownloadSemaphore = () => {
AvalibleDeliverySlots++;
promVideosQueued.dec();
promQueued.dec();

// If there are queued requests, resolve the first one in the queue
DownloadQueue.shift()?.();
Expand Down Expand Up @@ -193,7 +193,7 @@ const processVideo = async (fTitle: string, video: Video, retries = 0) => {
// eslint-disable-next-line no-fallthrough
case Video.State.Muxed: {
completedVideos++;
promVideosDownloadedTotal.inc();
promDownloadedTotal.inc();
updateSummaryBar();
mpb?.done(fTitle);
setTimeout(() => mpb?.removeTask(fTitle), 10000 + Math.floor(Math.random() * 6000));
Expand All @@ -203,7 +203,7 @@ const processVideo = async (fTitle: string, video: Video, retries = 0) => {
let info;
if (!(error instanceof Error)) info = new Error(`Something weird happened, whatever was thrown was not a error! ${error}`);
else info = error;
promVideoErrors.labels({ message: info.message.includes("ffmpeg") ? "ffmpeg" : info.message }).inc();
promErrors.labels({ message: info.message.includes("ffmpeg") ? "ffmpeg" : info.message }).inc();
// Handle errors when downloading nicely
if (retries < MaxRetries) {
log(fTitle, { message: `\u001b[31m\u001b[1mERR\u001b[0m: ${info.message} - Retrying in ${retries}s [${retries}/${MaxRetries}]` });
Expand Down
31 changes: 30 additions & 1 deletion src/lib/helpers.ts
@@ -1,6 +1,7 @@
import { downloadBinaries, detectPlatform, getBinaryFilename } from "ffbinaries";
import { getEnv, rebuildTypes, recursiveUpdate } from "@inrixia/helpers/object";
import { defaultArgs, defaultSettings } from "./defaults.js";
import { Histogram } from "prom-client";
import db from "@inrixia/db";
import fs from "fs";

Expand All @@ -14,7 +15,7 @@ import "dotenv/config";
import json5 from "json5";
const { parse } = json5;

export const DownloaderVersion = "5.11.3";
export const DownloaderVersion = "5.11.4";

import type { PartialArgs, Settings } from "./types.js";

Expand All @@ -28,6 +29,34 @@ export const fApi = new Floatplane(
`Floatplane-Downloader/${DownloaderVersion} (Inrix, +https://github.com/Inrixia/Floatplane-Downloader), CFNetwork`,
);

// Add floatplane api request metrics
const httpRequestDurationmMs = 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> = T & { _startTime: number };
fApi.extend({
hooks: {
beforeRequest: [
(options) => {
(<WithStartTime<typeof options>>options)._startTime = Date.now();
},
],
afterResponse: [
(res) => {
const url = res.requestUrl;
const options = <WithStartTime<typeof res.request.options>>res.request.options;
const thumbsIndex = url.pathname.indexOf("thumbnails");
const pathname = thumbsIndex !== -1 ? url.pathname.substring(0, thumbsIndex + 10) : url.pathname;
httpRequestDurationmMs.observe({ method: options.method, hostname: url.hostname, pathname, status: res.statusCode }, Date.now() - options._startTime);
return res;
},
],
},
});

export const settings = db<Settings>("./db/settings.json", { template: defaultSettings, pretty: true, forceCreate: true, updateOnExternalChanges: true });
recursiveUpdate(settings, defaultSettings);

Expand Down
50 changes: 11 additions & 39 deletions src/lib/prometheus.ts
@@ -1,48 +1,20 @@
import { collectDefaultMetrics, Gauge, Histogram, register } from "prom-client";
import { collectDefaultMetrics, Gauge, register } from "prom-client";
import { createServer } from "http";
import WebSocket from "ws";

import { DownloaderVersion, fApi, settings } from "./helpers.js";
import { DownloaderVersion, 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);
collectDefaultMetrics();

// 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> = T & { _startTime: number };
fApi.extend({
hooks: {
beforeRequest: [
(options) => {
(<WithStartTime<typeof options>>options)._startTime = Date.now();
},
],
afterResponse: [
(res) => {
const url = res.requestUrl;
const options = <WithStartTime<typeof res.request.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;
},
],
},
});
new Gauge({
name: "instance",
help: "Floatplane Downloader instances",
labelNames: ["version"],
})
.labels({ version: DownloaderVersion })
.set(1);

export const initProm = (instance: string) => {
if (settings.metrics.contributeMetrics) {
const connect = () => {
const socket = new WebSocket("ws://targets.monitor.spookelton.net");
Expand Down

0 comments on commit 5c04c93

Please sign in to comment.