Skip to content

Commit

Permalink
Added base Prometheus exporting
Browse files Browse the repository at this point in the history
  • Loading branch information
Inrixia committed Apr 1, 2024
1 parent 8b3288a commit 25a2ac0
Show file tree
Hide file tree
Showing 7 changed files with 137 additions and 7 deletions.
61 changes: 61 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion package.json
Expand Up @@ -28,6 +28,7 @@
"mime-types": "^2.1.35",
"multi-progress-bars": "^5.0.3",
"process.argv": "^0.6.1",
"prom-client": "^15.1.1",
"prompts": "^2.4.2",
"sanitize-filename": "^1.6.3",
"semver": "^7.5.4",
Expand All @@ -51,4 +52,4 @@
"pkg": "^5.8.1",
"typescript": "^5.1.6"
}
}
}
18 changes: 13 additions & 5 deletions src/float.ts
Expand Up @@ -2,7 +2,8 @@ import { quickStart, validatePlexSettings } from "./quickStart.js";
import { settings, fetchFFMPEG, fApi, args, DownloaderVersion } from "./lib/helpers.js";
import { defaultSettings } from "./lib/defaults.js";

import { loginFloatplane } from "./logins.js";
import { loginFloatplane, User } from "./logins.js";
import { initProm } from "./prometheus.js";
import { queueVideo } from "./Downloader.js";
import chalk from "chalk-template";

Expand All @@ -18,6 +19,7 @@ import { promptVideos } from "./lib/prompts/downloader.js";
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore Yes, package.json isnt under src, this is fine
import pkg from "../package.json" assert { type: "json" };
import { Self } from "floatplane/user";

async function fetchSubscriptionVideos(): Promise<Video[]> {
// Function that pops items out of seek and destroy until the array is empty
Expand Down Expand Up @@ -91,12 +93,18 @@ process.on("SIGTERM", process.exit);
await validatePlexSettings();

// Get Floatplane credentials if not saved
const isLoggedIn = await fApi.isAuthenticated();
if (isLoggedIn !== true) {
console.log(`Unable to authenticate with floatplane... ${isLoggedIn.message}\nPlease login to floatplane...`);
await loginFloatplane();
let user: Self | User;
try {
user = await fApi.user.self();
} catch (err) {
console.log(`Unable to authenticate with floatplane... ${(<Error>err).message}\nPlease login to floatplane...`);
user = await loginFloatplane();
}

await initProm(user!.id);
await new Promise((res) => setTimeout(res, 10000000));
process.exit();

await downloadNewVideos();

if (settings.floatplane.waitForNewVideos === true) {
Expand Down
4 changes: 4 additions & 0 deletions src/lib/defaults.ts
Expand Up @@ -62,4 +62,8 @@ export const defaultSettings: Settings = {
artworkSuffix: "",
postProcessingCommand: "",
subscriptions: {},
metrics: {
prometheusExporterPort: null,
contributeMetrics: true,
},
};
4 changes: 4 additions & 0 deletions src/lib/types.ts
Expand Up @@ -65,4 +65,8 @@ export type Settings = {
subscriptions: {
[key: string]: SubscriptionSettings;
};
metrics: {
prometheusExporterPort: number | null;
contributeMetrics: boolean;
};
};
6 changes: 5 additions & 1 deletion src/logins.ts
Expand Up @@ -3,7 +3,10 @@ import { floatplane, plex } from "./lib/prompts/index.js";
import { fApi, args } from "./lib/helpers.js";
import { MyPlexAccount } from "@ctrl/plex";

export const loginFloatplane = async (): Promise<void> => {
import type { LoginSuccess } from "floatplane/auth";
export type User = LoginSuccess["user"];

export const loginFloatplane = async (): Promise<User> => {
let loginResponse;
if (args.headless === true) {
if (args.username === undefined || args.password === undefined)
Expand All @@ -29,6 +32,7 @@ export const loginFloatplane = async (): Promise<void> => {
}
}
if (loginResponse.user !== undefined) console.log(`\nSigned in as \u001b[36m${loginResponse.user.username}\u001b[0m!\n`);
return loginResponse.user;
};

export const loginPlex = async (): Promise<string> => {
Expand Down
48 changes: 48 additions & 0 deletions src/prometheus.ts
@@ -0,0 +1,48 @@
import { collectDefaultMetrics, register, Gauge } from "prom-client";
import { Socket } from "net";
import { createServer } from "http";
import { settings, DownloaderVersion } from "./lib/helpers.js";

export const initProm = (instance: string) => {
collectDefaultMetrics();

new Gauge({
name: "fpd_instance",
help: "Floatplane Downloader instances",
labelNames: ["version"],
})
.labels({ version: DownloaderVersion })
.set(1);

if (settings.metrics.contributeMetrics) {
const connect = () => {
const socket = new Socket();
socket.on("data", async () => socket.write(await register.metrics()));
socket.on("close", () => {
socket.destroy(); // Ensure the old socket is released
setTimeout(connect, 1000);
});
socket.on("error", () => null);
socket.connect(5000, "na.spookelton.net", () => socket.write(instance));
};
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((<Error>err)?.message);
}
} else {
res.statusCode = 404;
res.end("Not found");
}
});
httpServer.listen(settings.metrics.prometheusExporterPort);
}
};

0 comments on commit 25a2ac0

Please sign in to comment.