A tool for parsing traffic on the jetstream and applying a moderation workstream based on regexp based rules
1import express from "express";
2import { Counter, Registry, collectDefaultMetrics } from "prom-client";
3import { HOST } from "./config.js";
4import { logger } from "./logger.js";
5
6const register = new Registry();
7collectDefaultMetrics({ register });
8
9export const labelsAppliedCounter = new Counter({
10 name: "skywatch_labels_applied_total",
11 help: "Total number of labels applied by type",
12 labelNames: ["label_type", "target_type"],
13 registers: [register],
14});
15
16export const labelsCachedCounter = new Counter({
17 name: "skywatch_labels_cached_total",
18 help: "Total number of labels skipped due to cache/existing label",
19 labelNames: ["label_type", "target_type", "reason"],
20 registers: [register],
21});
22
23export const unlabelsRemovedCounter: Counter = new Counter({
24 name: "skywatch_labels_removed_total",
25 help: "Total number of labels removed due to criteria no longer matching",
26 labelNames: ["label_type", "target_type"],
27 registers: [register],
28});
29
30export const accountLabelsThresholdAppliedCounter = new Counter({
31 name: "skywatch_account_labels_threshold_applied_total",
32 help: "Total number of account actions applied due to threshold",
33 labelNames: ["account_label", "action"],
34 registers: [register],
35});
36
37export const accountThresholdChecksCounter = new Counter({
38 name: "skywatch_account_threshold_checks_total",
39 help: "Total number of account threshold checks performed",
40 labelNames: ["post_label"],
41 registers: [register],
42});
43
44export const accountThresholdMetCounter = new Counter({
45 name: "skywatch_account_threshold_met_total",
46 help: "Total number of times account thresholds were met",
47 labelNames: ["account_label"],
48 registers: [register],
49});
50
51export const starterPackThresholdChecksCounter = new Counter({
52 name: "skywatch_starter_pack_threshold_checks_total",
53 help: "Total number of starter pack threshold checks performed",
54 registers: [register],
55});
56
57export const starterPackThresholdMetCounter = new Counter({
58 name: "skywatch_starter_pack_threshold_met_total",
59 help: "Total number of times starter pack thresholds were met",
60 labelNames: ["account_label"],
61 registers: [register],
62});
63
64export const starterPackLabelsThresholdAppliedCounter = new Counter({
65 name: "skywatch_starter_pack_labels_threshold_applied_total",
66 help: "Total number of account actions applied due to starter pack threshold",
67 labelNames: ["account_label", "action"],
68 registers: [register],
69});
70
71export const moderationActionsFailedCounter = new Counter({
72 name: "skywatch_moderation_actions_failed_total",
73 help: "Total number of moderation actions that failed",
74 labelNames: ["action", "target_type"],
75 registers: [register],
76});
77
78const app = express();
79
80app.get("/metrics", (req, res) => {
81 register
82 .metrics()
83 .then((metrics) => {
84 res.set("Content-Type", register.contentType);
85 res.send(metrics);
86 })
87 .catch((ex: unknown) => {
88 logger.error(
89 { process: "METRICS", error: (ex as Error).message },
90 "Error serving metrics",
91 );
92 res.status(500).end((ex as Error).message);
93 });
94});
95
96export const startMetricsServer = (port: number) => {
97 return app.listen(port, HOST, () => {
98 logger.info(
99 { process: "METRICS", host: HOST, port },
100 "Metrics server is listening",
101 );
102 });
103};