feat: add health dashboard and local ticket archive
This commit is contained in:
parent
0d78abbb6f
commit
0a6b808d99
15 changed files with 824 additions and 60 deletions
76
convex/ops.ts
Normal file
76
convex/ops.ts
Normal file
|
|
@ -0,0 +1,76 @@
|
|||
import { ConvexError, v } from "convex/values"
|
||||
|
||||
import { query } from "./_generated/server"
|
||||
import { getOfflineThresholdMs, getStaleThresholdMs } from "./machines"
|
||||
|
||||
const MACHINE_SCAN_LIMIT = 1200
|
||||
|
||||
export const healthSnapshot = query({
|
||||
args: {
|
||||
token: v.optional(v.string()),
|
||||
},
|
||||
handler: async (ctx, args) => {
|
||||
const requiredToken = process.env["INTERNAL_HEALTH_TOKEN"] ?? process.env["REPORTS_CRON_SECRET"] ?? null
|
||||
if (requiredToken && args.token !== requiredToken) {
|
||||
throw new ConvexError("Nao autorizado")
|
||||
}
|
||||
|
||||
const now = Date.now()
|
||||
const offlineMs = getOfflineThresholdMs()
|
||||
const staleMs = getStaleThresholdMs(offlineMs)
|
||||
|
||||
const machines = await ctx.db.query("machines").take(MACHINE_SCAN_LIMIT)
|
||||
const heartbeats = await ctx.db.query("machineHeartbeats").collect()
|
||||
|
||||
let online = 0
|
||||
let warning = 0
|
||||
let offline = 0
|
||||
let newest = 0
|
||||
let oldest = 0
|
||||
const withHeartbeat = new Set<string>()
|
||||
|
||||
for (const hb of heartbeats) {
|
||||
const ageMs = now - hb.lastHeartbeatAt
|
||||
withHeartbeat.add(String(hb.machineId))
|
||||
if (newest === 0 || hb.lastHeartbeatAt > newest) {
|
||||
newest = hb.lastHeartbeatAt
|
||||
}
|
||||
if (oldest === 0 || hb.lastHeartbeatAt < oldest) {
|
||||
oldest = hb.lastHeartbeatAt
|
||||
}
|
||||
if (ageMs <= offlineMs) {
|
||||
online += 1
|
||||
} else if (ageMs <= staleMs) {
|
||||
warning += 1
|
||||
} else {
|
||||
offline += 1
|
||||
}
|
||||
}
|
||||
|
||||
const withoutHeartbeat = machines.length - withHeartbeat.size
|
||||
const totalOffline = offline + (withoutHeartbeat > 0 ? withoutHeartbeat : 0)
|
||||
|
||||
return {
|
||||
totals: {
|
||||
machines: machines.length,
|
||||
heartbeats: heartbeats.length,
|
||||
withoutHeartbeat: withoutHeartbeat > 0 ? withoutHeartbeat : 0,
|
||||
truncated: machines.length === MACHINE_SCAN_LIMIT,
|
||||
},
|
||||
connectivity: {
|
||||
online,
|
||||
warning,
|
||||
offline: totalOffline,
|
||||
},
|
||||
heartbeatAgeMs: {
|
||||
newest: newest ? now - newest : null,
|
||||
oldest: oldest ? now - oldest : null,
|
||||
},
|
||||
thresholds: {
|
||||
offlineMs,
|
||||
staleMs,
|
||||
},
|
||||
generatedAt: now,
|
||||
}
|
||||
},
|
||||
})
|
||||
Loading…
Add table
Add a link
Reference in a new issue