public uptime monitoring + (soon) observability with events saved to PDS
at main 1.6 kB view raw
1import type { ServiceConfig, UptimeCheck } from './types.ts'; 2 3/** 4 * performs an uptime check on a service 5 * 6 * @param service the service configuration 7 * @returns the uptime check result 8 */ 9export async function checkService(service: ServiceConfig): Promise<UptimeCheck> { 10 const timeout = service.timeout || 5000; 11 const startTime = Date.now(); 12 const checkedAt = new Date().toISOString(); 13 14 try { 15 const controller = new AbortController(); 16 const timeoutId = setTimeout(() => { 17 controller.abort(); 18 }, timeout); 19 20 const headers: HeadersInit = {}; 21 if (service.host) { 22 headers.Host = service.host; 23 } 24 25 const response = await fetch(service.url, { 26 method: 'GET', 27 signal: controller.signal, 28 redirect: 'follow', 29 headers, 30 }); 31 32 clearTimeout(timeoutId); 33 34 const responseTime = Date.now() - startTime; 35 36 return { 37 ...(service.group && { groupName: service.group }), 38 serviceName: service.name, 39 ...(service.region && { region: service.region }), 40 serviceUrl: service.url, 41 checkedAt, 42 status: 'up', 43 responseTime, 44 httpStatus: response.status, 45 }; 46 } catch (error) { 47 const responseTime = Date.now() - startTime; 48 let errorMessage = 'unknown error'; 49 50 if (error instanceof Error) { 51 if (error.name === 'AbortError') { 52 errorMessage = `timeout after ${timeout}ms`; 53 } else { 54 errorMessage = error.message; 55 } 56 } 57 58 return { 59 ...(service.group && { groupName: service.group }), 60 serviceName: service.name, 61 ...(service.region && { region: service.region }), 62 serviceUrl: service.url, 63 checkedAt, 64 status: 'down', 65 responseTime: -1, 66 errorMessage, 67 }; 68 } 69}