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 mochten; die @loadfocus/monitoring CLI ermittelt den Unterschied zum Live-Zustand und gleicht ihn ab (erstellen, aktualisieren, loschen).

Es ist deklarativ und idempotent: Wenn Sie deploy zweimal ausfuhren, andert sich beim zweiten Mal nichts. Ihre Dateien sind die einzige Quelle der Wahrheit, sodass Anderungen uber Pull Requests laufen und Ihr Monitoring-Verlauf in Git lebt.

Alles lauft 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 Oberflache tun konnten.

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 zuruckgibt. Sie prufen den Plan und wenden ihn dann an.

  • Verfassen — Beschreiben Sie Ressourcen als Dateien (YAML- oder JS-Konstrukte).
  • Planendeploy --dry-run zeigt genau, was erstellt, aktualisiert, ubernommen oder geloscht wird.
  • Anwendendeploy gleicht Ihr Konto so ab, dass es den Dateien entspricht.
  • Identitat abgleichen — jede Ressource tragt eine stabile, von Ihnen gewahlte logicalId. So verfolgt die CLI eine Ressource uber Umbenennungen hinweg, sodass das Andern des Anzeigenamens eines Checks ihn nie neu erstellt.

Installation

Die CLI ist ein Node-Paket (Node 18+). Fuhren 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/monitoring
loadfocus-monitoring --help

Authentifizierung

Die CLI authentifiziert sich mit einem LoadFocus-API-Schlussel und einer Team-ID. Ihren API-Schlussel 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 login
loadfocus-monitoring whoami # confirm who you are and which team you're targeting

Fur CI sind Umgebungsvariablen vorzuziehen (sie uberschreiben 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 Gerust aus Konfigurationsdatei und Beispielmonitor in Ihrem Repository:

loadfocus-monitoring init

Dies schreibt loadfocus.config.yaml:

project: my-project # a namespace for this set of resources
checkMatch:
- "monitors/**/*.{check,group,alertRule,maintenanceWindow,dashboard,statusPage,alertChannel,variable}.{yaml,yml,js}"
defaults:
schedule: "300" # applied to checks that omit a schedule
locations: [us-east-1]
  • project grenzt alles ein, was die CLI verwaltet. Ressourcen in einem Projekt werden gemeinsam abgeglichen; alles im Projekt, was nicht mehr in Ihren Dateien steht, wird bei deploy geloscht. Nutzen Sie separate Projekte, um unabhangige Monitor-Sets zu verwalten.
  • checkMatch ist das Glob (bzw. die Globs) fur Ihre Verfassungs-Dateien.
  • defaults fullt schedule, locations und alertChannels fur Checks aus, die sie weglassen.

Der Workflow

loadfocus-monitoring validate # compile locally + server-side dry-run; great as a PR gate
loadfocus-monitoring deploy --dry-run # show the plan (created / updated / adopted / deleted)
loadfocus-monitoring deploy # apply it
loadfocus-monitoring list # inventory of what's deployed in the project
loadfocus-monitoring list --status # …with each check's latest up/down/degraded status
loadfocus-monitoring get <logicalId> # show one deployed resource
loadfocus-monitoring trigger <logicalId> # run a check now
loadfocus-monitoring destroy # delete everything managed in the project

deploy ist standardmassig sicher: Es zeigt den Plan und fragt bei interaktiver Ausfuhrung nach, bevor es etwas loscht. In CI (nicht-interaktiv) verweigert es das Loschen ohne --yes und beendet sich mit einem klaren Code, statt an einer Eingabeaufforderung zu hangen. Fugen Sie Lese-/Ergebnisbefehlen --json hinzu, um maschinenlesbare Ausgaben zu erhalten.

Bestehende Monitore ubernehmen

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. Prufen, committen und dann deploy --dry-run ausfuhren — ubereinstimmende Ressourcen werden an Ort und Stelle ubernommen (unter Verwaltung gestellt), statt dupliziert zu werden.

Ressourcen

Jede Ressource ist eine Datei mit einem kind, einer logicalId (Ihr stabiler Bezeichner) und den Feldern fur dieses kind. Verweise zwischen Ressourcen nutzen logicalIds (oder Namen fur Benachrichtigungskanale) — der Server lost sie auf, und die Deploy-Reihenfolge wird fur Sie geregelt.

Checks

Ein Monitor-kind deckt jeden Check-Typ uber type ab: api, browser, multistep, tcp, heartbeat.

kind: check
type: api
logicalId: home
name: Home API
schedule: "300" # seconds between runs
locations: [us-east-1, eu-west-1]
request:
url: "https://example.com/health"
method: GET
assertions:
- { 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-/Erreichbarkeitsprufung 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, Benachrichtigungskanale, Frequenz und Aktivierung uber viele Checks hinweg. Ein Check tritt einer Gruppe mit group: <logicalId> bei.

kind: group
logicalId: web
name: Web services
locations: [us-east-1, eu-west-1]

Benachrichtigungsregeln

Benachrichtigen, wenn die Metrik eines Checks einen Schwellenwert uberschreitet.

kind: alertRule
logicalId: home-latency
name: Home API latency
check: home # reference a check by logicalId
metric: responseTime # responseTime | statusCode | duration
condition: above
conditionValue: 1500 # milliseconds

Benachrichtigungskanale

Verwalten Sie Benachrichtigungskanale als Code und referenzieren Sie sie per Name aus einem Check, einer Gruppe oder einer Benachrichtigungsregel. Unterstutzte 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 aufgelost, niemals in Ihre Dateien committet.

kind: alertChannel
logicalId: oncall # the name checks / groups / alert rules reference
type: pagerduty
routingKey: "{{secrets.PAGERDUTY_KEY}}"

Wartungsfenster

Unterdrucken Sie Benachrichtigungen wahrend geplanter Arbeiten. Zeiten sind in UTC. startsAt / endsAt akzeptieren einen ISO-8601-String (z. B. "2026-07-01T00:00:00Z") oder Unix-Millisekunden.

kind: maintenanceWindow
logicalId: weekly-deploy
name: Weekly deploy window
enabled: true
startsAt: "2026-07-01T00:00:00Z" # ISO-8601 or unix ms
endsAt: "2026-07-01T02:00:00Z"
repeat: weekly # none | daily | weekly | monthly
weekdays: [2] # 0=Sun6=Sat
targets:
allChecks: false
checkIds: [home] # by logicalId

Dashboards

Eine gemeinsame Ansicht ausgewahlter Checks, optional offentlich uber einen Slug.

kind: dashboard
logicalId: status-overview
name: Status overview
visibility: private # private | public
checks: [home] # by logicalId
window: 24h # 24h | 7d | 30d

Statusseiten

Eine offentliche Statusseite unter <slug>.loadfoc.us, optional auf Ihrer eigenen, benutzerdefinierten Domain.

kind: statusPage
logicalId: public-status
title: Acme Status
slug: acme # -> acme.loadfoc.us (globally unique)
enabled: true
customDomain: status.acme.com # optional, paid; point a CNAME at cname.loadfoc.us
groups:
- { id: core, name: Core Services, order: 0 }
components:
- id: api
name: API
groupId: core
monitors: [home] # checks shown on this component, by logicalId
branding:
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 ausserhalb des Ablaufs.

Variablen

Nicht geheime Werte (Basis-URLs, IDs), die Checks zur Laufzeit als {{vars.NAME}} referenzieren. Die logicalId ist der Variablenschlussel. (Fur Secrets verwenden Sie env set-secret — legen Sie sie niemals in Dateien ab.)

kind: variable
logicalId: BASE_URL
value: "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 ladt sie wie jede andere Ressource.

Secrets und Variablen

Referenzieren Sie Werte aus Ihren Checks, ohne sie zu committen. Secrets (Tokens, Passworter) werden ausschliesslich imperativ verwaltet und in Check-Feldern sowie geheimen Feldern von Benachrichtigungskanalen als {{secrets.NAME}} referenziert. Variablen (nicht geheim) konnen 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 ausfuhren

Eine typische Pipeline validiert bei jedem Pull Request und deployt beim Merge in den Main-Branch.

# .github/workflows/monitoring.yml
name: monitoring
on:
pull_request:
push:
branches: [main]
jobs:
monitoring:
runs-on: ubuntu-latest
env:
LOADFOCUS_API_KEY: ${{ secrets.LOADFOCUS_API_KEY }}
TEAM_ID: ${{ secrets.LOADFOCUS_TEAM_ID }}
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with: { node-version: 20 }
- run: npx @loadfocus/monitoring validate
- if: github.ref == 'refs/heads/main'
run: npx @loadfocus/monitoring deploy --yes

Wissenswertes

  • logicalId ist die Identitat. Halten Sie sie stabil. Sie konnen name oder title eines Checks beliebig andern; das Andern der logicalId wird so behandelt, als wurde eine Ressource geloscht und eine andere erstellt.
  • Loschungen sind auf das Projekt beschrankt. deploy entfernt nur Ressourcen im aktuellen project, die nicht mehr in Ihren Dateien stehen — niemals etwas in einem anderen Projekt oder ausserhalb von Monitoring as Code Erstelltes (bis Sie es ubernehmen).
  • Statusseiten-Slugs sind global. slug wird zu einer Subdomain, muss also uber 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), erhalt bei deploy einen klaren Fehler statt eines stillschweigend unvollstandigen Ergebnisses.
  • Plan-Limits gelten. Das Erstellen von Ressourcen uber die CLI unterliegt denselben Plan-Kontingenten wie das Dashboard.

Verwandt