162 lines
4.6 KiB
TypeScript
162 lines
4.6 KiB
TypeScript
import type { TaskQueue } from "@trigger.dev/database";
|
|
import type { Registry } from "prom-client";
|
|
import { Gauge } from "prom-client";
|
|
import { prisma } from "~/db.server";
|
|
import type { AuthenticatedEnvironment } from "~/services/apiAuth.server";
|
|
import { marqs } from "~/v3/marqs/index.server";
|
|
|
|
export async function registerProjectMetrics(
|
|
registry: Registry,
|
|
projectId: string,
|
|
userId: string
|
|
) {
|
|
// Register project metrics here
|
|
// Register queue metrics here
|
|
|
|
// Find the dev runtime environment for this project/user
|
|
const allEnvironments = await prisma.runtimeEnvironment.findMany({
|
|
where: {
|
|
projectId,
|
|
},
|
|
include: {
|
|
taskQueues: true,
|
|
project: true,
|
|
organization: true,
|
|
orgMember: true,
|
|
},
|
|
});
|
|
|
|
for (const env of allEnvironments) {
|
|
if (env.type === "DEVELOPMENT" && env.orgMember?.userId === userId) {
|
|
await registerEnvironmentMetrics(env, registry);
|
|
} else if (env.type !== "DEVELOPMENT") {
|
|
await registerEnvironmentMetrics(env, registry);
|
|
}
|
|
}
|
|
}
|
|
|
|
async function registerEnvironmentMetrics(
|
|
env: AuthenticatedEnvironment & { taskQueues: TaskQueue[] },
|
|
registry: Registry
|
|
) {
|
|
new Gauge({
|
|
name: sanitizeMetricName(`trigger_env_queue_${env.slug}_concurrency`),
|
|
help: `The number of tasks currently being executed in the dev environment queue`,
|
|
registers: [registry],
|
|
async collect() {
|
|
const length = await marqs?.currentConcurrencyOfEnvironment(env);
|
|
|
|
if (length) {
|
|
this.set(length);
|
|
}
|
|
},
|
|
});
|
|
|
|
new Gauge({
|
|
name: sanitizeMetricName(`trigger_env_queue_${env.slug}_concurrency_limit`),
|
|
help: `The concurrency limit for the dev environment queue`,
|
|
registers: [registry],
|
|
async collect() {
|
|
const length = await marqs?.getEnvConcurrencyLimit(env);
|
|
|
|
if (length) {
|
|
this.set(length);
|
|
}
|
|
},
|
|
});
|
|
|
|
new Gauge({
|
|
name: sanitizeMetricName(`trigger_env_queue_${env.slug}_capacity`),
|
|
help: `The capacity of the dev environment queue`,
|
|
registers: [registry],
|
|
async collect() {
|
|
const concurrencyLimit = await marqs?.getEnvConcurrencyLimit(env);
|
|
const currentConcurrency = await marqs?.currentConcurrencyOfEnvironment(env);
|
|
|
|
if (typeof concurrencyLimit === "number" && typeof currentConcurrency === "number") {
|
|
this.set(concurrencyLimit - currentConcurrency);
|
|
}
|
|
},
|
|
});
|
|
|
|
for (const queue of env.taskQueues) {
|
|
registerTaskQueueMetrics(registry, queue, env);
|
|
}
|
|
}
|
|
|
|
function registerTaskQueueMetrics(
|
|
registry: Registry,
|
|
queue: TaskQueue,
|
|
env: AuthenticatedEnvironment
|
|
) {
|
|
new Gauge({
|
|
name: sanitizeMetricName(`trigger_${env.slug}_task_queue_${queue.name}_length`),
|
|
help: `The number of tasks in the ${queue.name} queue`,
|
|
registers: [registry],
|
|
async collect() {
|
|
const length = await marqs?.lengthOfQueue(env, queue.name);
|
|
|
|
if (length) {
|
|
this.set(length);
|
|
}
|
|
},
|
|
});
|
|
|
|
new Gauge({
|
|
name: sanitizeMetricName(`trigger_${env.slug}_task_queue_${queue.name}_concurrency`),
|
|
help: `The number of tasks currently being executed in the ${queue.name} queue`,
|
|
registers: [registry],
|
|
async collect() {
|
|
const length = await marqs?.currentConcurrencyOfQueue(env, queue.name);
|
|
|
|
if (length) {
|
|
this.set(length);
|
|
}
|
|
},
|
|
});
|
|
|
|
new Gauge({
|
|
name: sanitizeMetricName(`trigger_${env.slug}_task_queue_${queue.name}_concurrency_limit`),
|
|
help: `The concurrency limit for the ${queue.name} queue`,
|
|
registers: [registry],
|
|
async collect() {
|
|
const length = await marqs?.getQueueConcurrencyLimit(env, queue.name);
|
|
|
|
if (length) {
|
|
this.set(length);
|
|
}
|
|
},
|
|
});
|
|
|
|
new Gauge({
|
|
name: sanitizeMetricName(`trigger_${env.slug}_task_queue_${queue.name}_capacity`),
|
|
help: `The capacity of the ${queue.name} queue`,
|
|
registers: [registry],
|
|
async collect() {
|
|
const concurrencyLimit = await marqs?.getQueueConcurrencyLimit(env, queue.name);
|
|
const currentConcurrency = await marqs?.currentConcurrencyOfQueue(env, queue.name);
|
|
|
|
if (typeof concurrencyLimit === "number" && typeof currentConcurrency === "number") {
|
|
this.set(concurrencyLimit - currentConcurrency);
|
|
}
|
|
},
|
|
});
|
|
|
|
new Gauge({
|
|
name: sanitizeMetricName(`trigger_${env.slug}_task_queue_${queue.name}_oldest_message_age`),
|
|
help: `The age of the oldest message in the ${queue.name} queue`,
|
|
registers: [registry],
|
|
async collect() {
|
|
const oldestMessage = await marqs?.oldestMessageInQueue(env, queue.name);
|
|
|
|
if (oldestMessage) {
|
|
this.set(oldestMessage);
|
|
}
|
|
},
|
|
});
|
|
}
|
|
|
|
function sanitizeMetricName(name: string) {
|
|
return name.replace(/[^a-zA-Z0-9_]/g, "_");
|
|
}
|