Monitoring as Code
Monitoring as Code
Mit Monitoring as Code definieren Sie Ihr LoadFocus-Monitoring-Setup als versionierte Dateien und wenden es von der Kommandozeile oder aus CI an — genauso, wie Sie Infrastruktur mit Terraform oder Pulumi verwalten. Sie beschreiben die Monitore, Gruppen, Benachrichtigungen, Wartungsfenster, Dashboards und Statusseiten, die Sie haben möchten; die @loadfocus/monitoring CLI ermittelt den Unterschied zum Live-Zustand und gleicht ihn ab (erstellen, aktualisieren, löschen).
Es ist deklarativ und idempotent: Wenn Sie deploy zweimal ausführen, ändert sich beim zweiten Mal nichts. Ihre Dateien sind die einzige Quelle der Wahrheit, sodass Änderungen über Pull Requests laufen und Ihr Monitoring-Verlauf in Git lebt.
Alles läuft in Ihrem Konto und Ihrem aktiven Team, wobei Ihre Plan-Limits vom LoadFocus-Backend genauso durchgesetzt werden wie im Dashboard. Die CLI tut nur, was Sie auch selbst in der Oberfläche tun könnten.
Wie es funktioniert
Sie pflegen einen Ordner mit kleinen YAML- (oder JavaScript-) Dateien — eine Ressource pro Datei — sowie eine loadfocus.config.yaml, die auf sie verweist. Die CLI sendet diese Definitionen an LoadFocus, das sie auf Live-Ressourcen abbildet, vergleicht und einen Plan zurückgibt. Sie prüfen den Plan und wenden ihn dann an.
- Verfassen — Beschreiben Sie Ressourcen als Dateien (YAML- oder JS-Konstrukte).
- Planen —
deploy --dry-runzeigt genau, was erstellt, aktualisiert, übernommen oder gelöscht wird. - Anwenden —
deploygleicht Ihr Konto so ab, dass es den Dateien entspricht. - Identität abgleichen — jede Ressource trägt eine stabile, von Ihnen gewählte
logicalId. So verfolgt die CLI eine Ressource über Umbenennungen hinweg, sodass das Ändern des Anzeigenamens eines Checks ihn nie neu erstellt.
Installation
Die CLI ist ein Node-Paket (Node 18+). Führen Sie es bei Bedarf mit npx aus:
npx @loadfocus/monitoring --help
…oder installieren Sie es global, um den Befehl loadfocus-monitoring zu erhalten:
npm install -g @loadfocus/monitoringloadfocus-monitoring --help
Authentifizierung
Die CLI authentifiziert sich mit einem LoadFocus-API-Schlüssel und einer Team-ID. Ihren API-Schlüssel finden Sie im Dashboard unter Ihren Konto-/API-Einstellungen und Ihre Team-ID auf der Teams-Seite.
Melden Sie sich einmal an, und die Anmeldedaten werden in ~/.loadfocus/config.json gespeichert:
loadfocus-monitoring loginloadfocus-monitoring whoami # confirm who you are and which team you're targeting
Für CI sind Umgebungsvariablen vorzuziehen (sie überschreiben die gespeicherte Konfiguration und werden nie auf die Festplatte geschrieben):
export LOADFOCUS_API_KEY="apikey_xxxxxxxx"export TEAM_ID="team_xxxxxxxx"# optional: export API_URL="https://apimonitor.loadfocus.com"
Ein Projekt erstellen
Erzeugen Sie ein Gerüst aus Konfigurationsdatei und Beispielmonitor in Ihrem Repository:
loadfocus-monitoring init
Dies schreibt loadfocus.config.yaml:
project: my-project # a namespace for this set of resourcescheckMatch:- "monitors/**/*.{check,group,alertRule,maintenanceWindow,dashboard,statusPage,alertChannel,variable}.{yaml,yml,js}"defaults:schedule: "300" # applied to checks that omit a schedulelocations: [us-east-1]
projectgrenzt alles ein, was die CLI verwaltet. Ressourcen in einem Projekt werden gemeinsam abgeglichen; alles im Projekt, was nicht mehr in Ihren Dateien steht, wird beideploygelöscht. Nutzen Sie separate Projekte, um unabhängige Monitor-Sets zu verwalten.checkMatchist das Glob (bzw. die Globs) für Ihre Verfassungs-Dateien.defaultsfülltschedule,locationsundalertChannelsfür Checks aus, die sie weglassen.
Der Workflow
loadfocus-monitoring validate # compile locally + server-side dry-run; great as a PR gateloadfocus-monitoring deploy --dry-run # show the plan (created / updated / adopted / deleted)loadfocus-monitoring deploy # apply itloadfocus-monitoring list # inventory of what's deployed in the projectloadfocus-monitoring list --status # …with each check's latest up/down/degraded statusloadfocus-monitoring get <logicalId> # show one deployed resourceloadfocus-monitoring trigger <logicalId> # run a check nowloadfocus-monitoring destroy # delete everything managed in the project
deploy ist standardmäßig sicher: Es zeigt den Plan und fragt bei interaktiver Ausführung nach, bevor es etwas löscht. In CI (nicht-interaktiv) verweigert es das Löschen ohne --yes und beendet sich mit einem klaren Code, statt an einer Eingabeaufforderung zu hängen. Fügen Sie Lese-/Ergebnisbefehlen --json hinzu, um maschinenlesbare Ausgaben zu erhalten.
Bestehende Monitore übernehmen
Sie haben bereits Monitore im Dashboard? Holen Sie sie in Dateien, statt sie neu zu erstellen:
loadfocus-monitoring import --project my-project --out monitors
Dies schreibt eine Datei pro Ressource und eine loadfocus.config.yaml. Prüfen, committen und dann deploy --dry-run ausführen — übereinstimmende Ressourcen werden an Ort und Stelle übernommen (unter Verwaltung gestellt), statt dupliziert zu werden.
Ressourcen
Jede Ressource ist eine Datei mit einem kind, einer logicalId (Ihr stabiler Bezeichner) und den Feldern für dieses kind. Verweise zwischen Ressourcen nutzen logicalIds (oder Namen für Benachrichtigungskanäle) — der Server löst sie auf, und die Deploy-Reihenfolge wird für Sie geregelt.
Checks
Ein Monitor-kind deckt jeden Check-Typ über type ab: api, browser, multistep, tcp, heartbeat.
kind: checktype: apilogicalId: homename: Home APIschedule: "300" # seconds between runslocations: [us-east-1, eu-west-1]request:url: "https://example.com/health"method: GETassertions:- { type: statusCode, comparison: equals, value: 200 }- { type: responseTime, comparison: lessThan, value: 1000 }
- api — HTTP-Anfrage mit Assertions zu Status, Body, Headern, Antwortzeit, SSL-Ablauf.
- browser — ein Playwright-User-Flow-Skript mit Screenshots und Zeiten pro Schritt (kostenpflichtig).
- multistep — eine geordnete Folge von API-Anfragen, die Daten zwischen den Schritten weitergeben.
- tcp — eine Port-/Erreichbarkeitsprüfung aus mehreren Regionen.
- heartbeat — ein Totmannschalter: Ein externer Job pingt eine URL nach Zeitplan, und LoadFocus benachrichtigt, wenn ein Ping ausbleibt.
Gruppen
Teilen Sie Standorte, Benachrichtigungskanäle, Frequenz und Aktivierung über viele Checks hinweg. Ein Check tritt einer Gruppe mit group: <logicalId> bei.
kind: grouplogicalId: webname: Web serviceslocations: [us-east-1, eu-west-1]
Benachrichtigungsregeln
Benachrichtigen, wenn die Metrik eines Checks einen Schwellenwert überschreitet.
kind: alertRulelogicalId: home-latencyname: Home API latencycheck: home # reference a check by logicalIdmetric: responseTime # responseTime | statusCode | durationcondition: aboveconditionValue: 1500 # milliseconds
Benachrichtigungskanäle
Verwalten Sie Benachrichtigungskanäle als Code und referenzieren Sie sie per Name aus einem Check, einer Gruppe oder einer Benachrichtigungsregel. Unterstützte types: email, slack, microsoftteams, webhook, discord, pagerduty, opsgenie. Geheime Felder (webhookUrl, routingKey, apiKey) nehmen eine {{secrets.NAME}}-Referenz entgegen — der Wert wird mit env set-secret gespeichert und beim Senden einer Benachrichtigung aufgelöst, niemals in Ihre Dateien committet.
kind: alertChannellogicalId: oncall # the name checks / groups / alert rules referencetype: pagerdutyroutingKey: "{{secrets.PAGERDUTY_KEY}}"
Wartungsfenster
Unterdrücken Sie Benachrichtigungen während geplanter Arbeiten. Zeiten sind in UTC. startsAt / endsAt akzeptieren einen ISO-8601-String (z. B. "2026-07-01T00:00:00Z") oder Unix-Millisekunden.
kind: maintenanceWindowlogicalId: weekly-deployname: Weekly deploy windowenabled: truestartsAt: "2026-07-01T00:00:00Z" # ISO-8601 or unix msendsAt: "2026-07-01T02:00:00Z"repeat: weekly # none | daily | weekly | monthlyweekdays: [2] # 0=Sun … 6=Sattargets:allChecks: falsecheckIds: [home] # by logicalId
Dashboards
Eine gemeinsame Ansicht ausgewählter Checks, optional öffentlich über einen Slug.
kind: dashboardlogicalId: status-overviewname: Status overviewvisibility: private # private | publicchecks: [home] # by logicalIdwindow: 24h # 24h | 7d | 30d
Statusseiten
Eine öffentliche Statusseite unter <slug>.loadfoc.us, optional auf Ihrer eigenen, benutzerdefinierten Domain.
kind: statusPagelogicalId: public-statustitle: Acme Statusslug: acme # -> acme.loadfoc.us (globally unique)enabled: truecustomDomain: status.acme.com # optional, paid; point a CNAME at cname.loadfoc.usgroups:- { id: core, name: Core Services, order: 0 }components:- id: apiname: APIgroupId: coremonitors: [home] # checks shown on this component, by logicalIdbranding:brandColor: "#5353a4"colorTheme: dark
Eine benutzerdefinierte Domain geht live, sobald Sie den CNAME erstellen und das Zertifikat ausgestellt ist — deploy deklariert sie; die Verifizierung erfolgt außerhalb des Ablaufs.
Variablen
Nicht geheime Werte (Basis-URLs, IDs), die Checks zur Laufzeit als {{vars.NAME}} referenzieren. Die logicalId ist der Variablenschlüssel. (Für Secrets verwenden Sie env set-secret — legen Sie sie niemals in Dateien ab.)
kind: variablelogicalId: BASE_URLvalue: "https://api.example.com"
Verfassen in JavaScript oder TypeScript
Wenn Sie Code statt YAML bevorzugen, erstellen Sie dieselben Definitionen programmatisch und exportieren Sie sie — die Konstrukte erzeugen identische Ressourcen:
const { Monitor, Group, AlertRule, Maintenance, Dashboard, StatusPage, AlertChannel, Variable } = require('@loadfocus/monitoring');new Monitor({type: 'api', logicalId: 'home', name: 'Home API', schedule: '300',locations: ['us-east-1'],request: { url: 'https://example.com/health', method: 'GET' },assertions: [{ type: 'statusCode', comparison: 'equals', value: 200 }],});new Group({ logicalId: 'web', name: 'Web services', locations: ['us-east-1'] });
Lassen Sie checkMatch auf Ihre .js-Dateien zeigen, und die CLI lädt sie wie jede andere Ressource.
Secrets und Variablen
Referenzieren Sie Werte aus Ihren Checks, ohne sie zu committen. Secrets (Tokens, Passwörter) werden ausschließlich imperativ verwaltet und in Check-Feldern sowie geheimen Feldern von Benachrichtigungskanälen als {{secrets.NAME}} referenziert. Variablen (nicht geheim) können als Dateien deklariert (kind: variable, siehe oben) oder imperativ gesetzt werden und werden als {{vars.NAME}} referenziert.
loadfocus-monitoring env set-secret API_TOKEN "s3cr3t"loadfocus-monitoring env set-variable BASE_URL "https://example.com"loadfocus-monitoring env ls # list secret + variable keys (values never shown)
In CI ausführen
Eine typische Pipeline validiert bei jedem Pull Request und deployt beim Merge in den Main-Branch.
# .github/workflows/monitoring.ymlname: monitoringon:pull_request:push:branches: [main]jobs:monitoring:runs-on: ubuntu-latestenv:LOADFOCUS_API_KEY: ${{ secrets.LOADFOCUS_API_KEY }}TEAM_ID: ${{ secrets.LOADFOCUS_TEAM_ID }}steps:- uses: actions/checkout@v4- uses: actions/setup-node@v4with: { node-version: 20 }- run: npx @loadfocus/monitoring validate- if: github.ref == 'refs/heads/main'run: npx @loadfocus/monitoring deploy --yes
Wissenswertes
logicalIdist die Identität. Halten Sie sie stabil. Sie könnennameodertitleeines Checks beliebig ändern; das Ändern derlogicalIdwird so behandelt, als würde eine Ressource gelöscht und eine andere erstellt.- Löschungen sind auf das Projekt beschränkt.
deployentfernt nur Ressourcen im aktuellenproject, die nicht mehr in Ihren Dateien stehen — niemals etwas in einem anderen Projekt oder außerhalb von Monitoring as Code Erstelltes (bis Sie es übernehmen). - Statusseiten-Slugs sind global.
slugwird zu einer Subdomain, muss also über alle LoadFocus-Kunden hinweg eindeutig sein. - Kostenpflichtige Funktionen scheitern laut. Ein kostenloses Team, das ein nur kostenpflichtiges Feld deklariert (eine benutzerdefinierte Statusseiten-Domain, das Entfernen des "Powered by"-Badges), erhält bei
deployeinen klaren Fehler statt eines stillschweigend unvollständigen Ergebnisses. - Plan-Limits gelten. Das Erstellen von Ressourcen über die CLI unterliegt denselben Plan-Kontingenten wie das Dashboard.