import { t } from "@lingui/core/macro" import { Trans } from "@lingui/react/macro" import { redirectPage } from "@nanostores/router" import { LoaderCircleIcon, SendIcon } from "lucide-react" import { useEffect, useState } from "react" import { $router } from "@/components/router" import { Badge } from "@/components/ui/badge" import { Button } from "@/components/ui/button" import { Separator } from "@/components/ui/separator" import { toast } from "@/components/ui/use-toast" import { isAdmin, pb } from "@/lib/api" import { cn } from "@/lib/utils" interface HeartbeatStatus { enabled: boolean url?: string interval?: number method?: string msg?: string } export default function HeartbeatSettings() { const [status, setStatus] = useState(null) const [isLoading, setIsLoading] = useState(true) const [isTesting, setIsTesting] = useState(false) if (!isAdmin()) { redirectPage($router, "settings", { name: "general" }) } useEffect(() => { fetchStatus() }, []) async function fetchStatus() { try { setIsLoading(true) const res = await pb.send("/api/beszel/heartbeat-status", {}) setStatus(res) } catch (error: unknown) { toast({ title: t`Error`, description: (error as Error).message, variant: "destructive", }) } finally { setIsLoading(false) } } async function sendTestHeartbeat() { setIsTesting(true) try { const res = await pb.send<{ err: string | false }>("/api/beszel/test-heartbeat", { method: "POST", }) if ("err" in res && !res.err) { toast({ title: t`Heartbeat sent successfully`, description: t`Check your monitoring service`, }) } else { toast({ title: t`Error`, description: (res.err as string) ?? t`Failed to send heartbeat`, variant: "destructive", }) } } catch (error: unknown) { toast({ title: t`Error`, description: (error as Error).message, variant: "destructive", }) } finally { setIsTesting(false) } } return (

Heartbeat Monitoring

Send periodic outbound pings to an external monitoring service so you can monitor Beszel without exposing it to the internet.

{status?.enabled ? ( ) : ( )}
) } function EnabledState({ status, isTesting, sendTestHeartbeat, }: { status: HeartbeatStatus isTesting: boolean sendTestHeartbeat: () => void }) { const TestIcon = isTesting ? LoaderCircleIcon : SendIcon return (
Active

Test heartbeat

Send a single heartbeat ping to verify your endpoint is working.

Payload format

When using POST, each heartbeat includes a JSON payload with system status summary, list of down systems, and triggered alerts.

The overall status is ok when all systems are up, warn when alerts are triggered, and{" "} error when any system is down.

) } function NotEnabledState({ isLoading }: { isLoading?: boolean }) { return (

Set the following environment variables on your Beszel hub to enable heartbeat monitoring:

After setting the environment variables, restart your Beszel hub for changes to take effect.

) } function ConfigItem({ label, value, mono }: { label: string; value: string; mono?: boolean }) { return (

{label}

{value}

) } function EnvVarItem({ name, description, example }: { name: string; description: string; example: string }) { return (
{name}

{description}

Example: {example}

) }