78 lines
2.1 KiB
TypeScript
78 lines
2.1 KiB
TypeScript
import vine from '@vinejs/vine'
|
|
import type { HttpContext } from '@adonisjs/core/http'
|
|
import Site from '#models/site'
|
|
import siteMonitor from '#services/site_monitor'
|
|
import UserError from '#exceptions/user_error'
|
|
|
|
const showValidator = vine.create({
|
|
range: vine.enum(['24h', '7d', '30d'] as const).optional(),
|
|
})
|
|
|
|
const RANGES = {
|
|
'24h': { seconds: 86_400, bucket: 300 },
|
|
'7d': { seconds: 7 * 86_400, bucket: 1800 },
|
|
'30d': { seconds: 30 * 86_400, bucket: 7200 },
|
|
} as const
|
|
|
|
export default class SitesController {
|
|
async index() {
|
|
const [sites, day, week] = await Promise.all([
|
|
Site.query().orderBy('active', 'desc').orderBy('domain'),
|
|
siteMonitor.stats(86_400),
|
|
siteMonitor.stats(7 * 86_400),
|
|
])
|
|
|
|
return sites.map((site) => ({
|
|
...serializeSite(site),
|
|
uptime24h: day.get(site.id)?.uptime ?? null,
|
|
uptime7d: week.get(site.id)?.uptime ?? null,
|
|
avgResponseMs24h: day.get(site.id)?.avgResponseMs ?? null,
|
|
}))
|
|
}
|
|
|
|
async show({ params, request }: HttpContext) {
|
|
const { range = '24h' } = await showValidator.validate(request.qs())
|
|
const site = await Site.find(params.id)
|
|
if (!site) throw new UserError('Site introuvable.', 404)
|
|
|
|
const { seconds, bucket } = RANGES[range]
|
|
const [history, stats] = await Promise.all([
|
|
siteMonitor.history(site.id, seconds, bucket),
|
|
siteMonitor.stats(seconds),
|
|
])
|
|
|
|
return {
|
|
site: serializeSite(site),
|
|
range,
|
|
bucket,
|
|
uptime: stats.get(site.id)?.uptime ?? null,
|
|
avgResponseMs: stats.get(site.id)?.avgResponseMs ?? null,
|
|
...history,
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Runs the checks right away instead of waiting for the next minute.
|
|
*/
|
|
async check() {
|
|
await siteMonitor.checkAll()
|
|
return this.index()
|
|
}
|
|
}
|
|
|
|
function serializeSite(site: Site) {
|
|
return {
|
|
id: site.id,
|
|
domain: site.domain,
|
|
active: site.active,
|
|
kind: site.kind,
|
|
upstream: site.upstream,
|
|
lastOk: site.lastOk,
|
|
lastStatus: site.lastStatus,
|
|
lastResponseMs: site.lastResponseMs,
|
|
lastError: site.lastError,
|
|
lastCheckedAt: site.lastCheckedAt,
|
|
certExpiresAt: site.certExpiresAt,
|
|
}
|
|
}
|