#288 war mit dem Transport allein nicht behoben. Die Ansichtsrettung fragte dokumentweit nach der offenen Unteransicht: document.querySelector('.subtab-content.active') Im Markup tragen aber ACHT Unteransichten diese Klasse - jedes Modul hat seine eigene Startansicht, und switchMainTab() raeumt nur innerhalb des Moduls auf, das es oeffnet. Zurueck kam deshalb immer die erste in Dokumentreihenfolge (sub-projects-list), voellig unabhaengig davon, was gerade sichtbar war. Wer im Bugtracker filterte, waere also auf der Projektverwaltung gelandet. Dass die Rettung fuer POST-Formulare zu funktionieren schien, lag an den wenigen, die ihren Anker fest in der action stehen haben. Gesucht wird jetzt erst das aktive Modul und darin die Unteransicht. Zusaetzlich tragen die drei Filterformulare das Feld "view" fest im Markup. Dort ist ohne Zweifel bekannt, wo sie stehen - das haengt an keiner DOM-Abfrage mehr. Und restoreViewFromHash() faellt bei einer unbekannten Unteransicht auf das Modul zurueck, statt wortlos im Dashboard zu landen. Nachgewiesen an einer DOM-Probe, die die Modulstruktur aus index.php nachbaut und die echten Funktionen darauf laufen laesst: alte Fassung -> tab-projects, neue Fassung -> sub-bugtracker-items. Ausserdem, aus derselben Sitzung gemeldet: Die Suche findet Eintraege jetzt ueber ihre Nummer. Sie ist das, was ueberall zitiert wird, und stand in keiner der durchsuchten Spalten - "288" lief ins Leere. "288" findet jetzt das Item mit dieser Nummer und alles, was die Zahl im Text hat; "#288" ausschliesslich dieses eine. Gilt fuer Bugtracker, Fehler-Stream und den Parameter search der API, der bei der Gelegenheit auch in die OpenAPI-Beschreibung gekommen ist. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
559 lines
18 KiB
Markdown
559 lines
18 KiB
Markdown
# Deployment Center — Agenten-Handbuch
|
|
|
|
Diese Seite beschreibt, wie ein Coding-Agent den Bugtracker und den
|
|
UpdateService des Deployment Centers benutzt.
|
|
|
|
**Maschinenlesbare Fassung:** `GET /api/openapi.json`
|
|
|
|
---
|
|
|
|
## 0. Was sich geändert hat
|
|
|
|
Wer eine ältere Integration betreibt, muss zwei Dinge anpassen:
|
|
|
|
| Änderung | Auswirkung |
|
|
|---|---|
|
|
| `POST /api/bugtracker/v1/report` verlangt jetzt zwingend ein Token | Aufrufe ohne Token liefern `401 unauthorized` |
|
|
| `GET /api/bugtracker/v1/projects` verlangt jetzt ein Token | dito |
|
|
| `POST` auf UpdateService-Publish verlangt `updateservice:publish` | Aufrufe ohne Token liefern `401` |
|
|
| Antwortformat vereinheitlicht | Erfolg: `{"status":"success",...}`, Fehler: `{"status":"error","error":{"code":"…","message":"…"}}` |
|
|
|
|
Der Feldname `error_hash` bleibt erhalten; zusätzlich gibt es `dedup_key`.
|
|
|
|
---
|
|
|
|
## 1. Authentifizierung
|
|
|
|
Alle Endpunkte akzeptieren das Token in einem dieser Header:
|
|
|
|
```
|
|
Authorization: Bearer dc_sub_xxxxxxxxxxxx
|
|
X-Agent-Token: dc_sub_xxxxxxxxxxxx
|
|
```
|
|
|
|
### Token-Hierarchie
|
|
|
|
* **Master-Token** (`dc_master_…`) — wird im WebUI unter *Token-Verwaltung* erzeugt.
|
|
Langlebig, gehört auf den Rechner bzw. in die CI, nicht in ein Repository.
|
|
* **Sub-Token** (`dc_sub_…`) — erzeugt sich ein Agent selbst aus dem Master-Token.
|
|
Rechte lassen sich dabei nur **einschränken**, nie erweitern.
|
|
|
|
### Sub-Token anfordern
|
|
|
|
```bash
|
|
curl -X POST https://dc.mhdf.de/api/tokens/v1/provision \
|
|
-H "X-Master-Token: dc_master_xxxxxxxx" \
|
|
-H "Content-Type: application/json" \
|
|
-d '{
|
|
"client_name": "claude-code auf DEV-WORKSTATION-01",
|
|
"instance_id": "DEV-WORKSTATION-01",
|
|
"scopes": ["bugtracker:report", "bugtracker:read", "bugtracker:manage"],
|
|
"environment": "development"
|
|
}'
|
|
```
|
|
|
|
Das zurückgegebene `sub_token` wird **nur einmal** ausgeliefert.
|
|
|
|
### Rechte (Scopes)
|
|
|
|
| Scope | Erlaubt |
|
|
|---|---|
|
|
| `bugtracker:report` | Bugs, Feature Requests und Ideen melden |
|
|
| `bugtracker:read` | Items und Projekte lesen |
|
|
| `bugtracker:manage` | Übernehmen, kommentieren, Status setzen, schließen |
|
|
| `watchdog:ping` | Heartbeats senden |
|
|
| `updateservice:read` | Auf Updates prüfen |
|
|
| `updateservice:publish` | Releases veröffentlichen |
|
|
| `bugtracker:*` | alle Bugtracker-Rechte |
|
|
| `*` | alles |
|
|
|
|
Ist ein Token an ein Projekt gebunden, greifen alle Aufrufe automatisch nur
|
|
auf dieses Projekt zu — ein Zugriff auf ein anderes liefert `403 project_forbidden`.
|
|
|
|
### Was kann mein Token? (ab 2.7.1)
|
|
|
|
```bash
|
|
curl https://dc.mhdf.de/api/tokens/v1/whoami \
|
|
-H "Authorization: Bearer $DC_TOKEN"
|
|
```
|
|
|
|
```json
|
|
{
|
|
"status": "success",
|
|
"name": "Werkbank polytrader",
|
|
"type": "master",
|
|
"owner_type": "dev_agent",
|
|
"is_workbench": true,
|
|
"project_slug": "polytrader",
|
|
"environment": "all",
|
|
"scopes": ["bugtracker:manage", "license:dev"],
|
|
"last_used_at": "2026-08-30 09:12:44",
|
|
"expires_at": null
|
|
}
|
|
```
|
|
|
|
Gedacht für Werkzeuge, die ihre Voraussetzungen prüfen wollen, **bevor** sie
|
|
etwas tun. Ohne diese Auskunft ließe sich ein Recht nur durch Ausprobieren
|
|
feststellen — und das hat Nebenwirkungen: eine Probe auf `bugtracker:manage`
|
|
übernähme ein Item, eine auf `license:dev` stellte einen Schlüssel aus.
|
|
|
|
`is_workbench` ist der Wert, der über Fremdmeldungen entscheidet: nur ein Token
|
|
der Besitzerart `dev_agent` darf in ein fremdes Projekt melden. Der
|
|
Klartextwert des Tokens wird nicht ausgeliefert; ein widerrufenes oder
|
|
abgelaufenes Token bekommt `401`.
|
|
|
|
---
|
|
|
|
## 2. Projekte finden
|
|
|
|
```bash
|
|
curl https://dc.mhdf.de/api/bugtracker/v1/projects \
|
|
-H "Authorization: Bearer $DC_TOKEN"
|
|
```
|
|
|
|
```json
|
|
{
|
|
"status": "success",
|
|
"count": 4,
|
|
"projects": [
|
|
{
|
|
"slug": "deploymentcenter",
|
|
"name": "Deployment Center",
|
|
"repo_url": "https://git.example.com/Richard/Deploymentcenter.git",
|
|
"default_agent": null,
|
|
"open_items": 3,
|
|
"critical_items": 0
|
|
}
|
|
]
|
|
}
|
|
```
|
|
|
|
> Findest du einen Fehler im Deployment Center selbst, melde ihn unter
|
|
> `project_slug: "deploymentcenter"`.
|
|
|
|
---
|
|
|
|
## 3. Etwas melden
|
|
|
|
```bash
|
|
curl -X POST https://dc.mhdf.de/api/bugtracker/v1/report \
|
|
-H "Authorization: Bearer $DC_TOKEN" \
|
|
-H "Content-Type: application/json" \
|
|
-H "Idempotency-Key: run-2026-08-07-42" \
|
|
-d '{
|
|
"project_slug": "myapp",
|
|
"type": "bug",
|
|
"title": "NullReferenceException in UserAuthService",
|
|
"description": "Tritt beim Login ohne gesetzte Session auf.",
|
|
"error_message": "Object reference not set to an instance of an object.",
|
|
"stack_trace": "at MyApp.Core.UserAuthService.ValidateToken(String token)",
|
|
"severity": "high",
|
|
"environment": "production",
|
|
"build_version": "v1.4.2",
|
|
|
|
"repo_url": "https://git.example.com/me/myapp.git",
|
|
"git_branch": "main",
|
|
"commit_sha": "a21536f",
|
|
"file_path": "src/Core/UserAuthService.cs",
|
|
"line_no": 42
|
|
}'
|
|
```
|
|
|
|
### Felder
|
|
|
|
| Feld | Pflicht | Bedeutung |
|
|
|---|---|---|
|
|
| `title` | ja | Kurze Beschreibung, max. 255 Zeichen |
|
|
| `project_slug` | empfohlen | Aus der Projektliste; Vorgabe `default` |
|
|
| `type` | nein | `bug` (Vorgabe) oder `feature_request` |
|
|
| `severity` | nein | `idea`, `wishlist`, `low`, `medium` (Vorgabe), `high`, `critical` |
|
|
| `environment` | nein | `production` (Vorgabe), `development`, `staging`, `testing` |
|
|
| `client_ref` | empfohlen | Idempotenz-Schlüssel, alternativ Header `Idempotency-Key` |
|
|
| `repo_url`, `git_branch`, `commit_sha`, `file_path`, `line_no` | empfohlen | Code-Kontext — spart dem nächsten Agenten das Parsen des Stacktrace |
|
|
| `context` | nein | Beliebiges JSON-Objekt für Zusatzinformationen |
|
|
| `push_id`, `target_agent`, `tags` | nein | Workflow-Zuordnung |
|
|
|
|
`created_by` wird aus dem Token abgeleitet und kann nicht gesetzt werden.
|
|
|
|
### Was der Server daraus macht
|
|
|
|
* **Deduplizierung** — gleiche Fehler werden zusammengefasst und
|
|
`occurrence_count` erhöht. Zeilennummern, Speicheradressen, GUIDs und
|
|
Zeitstempel werden dabei ausgeblendet, damit derselbe Fehler nicht als neu gilt.
|
|
Feature Requests und Ideen werden über den Titel dedupliziert.
|
|
* **Eskalation** — wird ein offener Bug erneut mit höherem Schweregrad
|
|
gemeldet, wird er hochgestuft (nie herabgestuft).
|
|
* **Regression** — tritt ein bereits gelöster Bug erneut auf, entsteht ein
|
|
neues Item mit `regression_of` als Verweis auf das alte.
|
|
* **Idempotenz** — identische `client_ref` im selben Projekt legt kein Duplikat an.
|
|
|
|
### Antwort
|
|
|
|
```json
|
|
{
|
|
"status": "success",
|
|
"item_id": 42,
|
|
"is_new": true,
|
|
"idempotent_hit": false,
|
|
"occurrence_count": 1,
|
|
"dedup_key": "e2c918a514d89a42f...",
|
|
"item_status": "open",
|
|
"regression_of": null,
|
|
"message": "Bug erfasst."
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## 4. Die Agenten-Schleife
|
|
|
|
Basis: `https://dc.mhdf.de/api/bugtracker/v1/manage`
|
|
|
|
### 4.1 Arbeit holen und übernehmen
|
|
|
|
Ein Aufruf, der die nächsten offenen Items liefert **und** exklusiv für dich
|
|
reserviert — damit arbeiten nicht zwei Agenten am selben Bug:
|
|
|
|
```bash
|
|
curl -X POST "https://dc.mhdf.de/api/bugtracker/v1/manage?action=next" \
|
|
-H "Authorization: Bearer $DC_TOKEN" \
|
|
-H "Content-Type: application/json" \
|
|
-d '{"project_slug": "myapp", "limit": 1, "severity": "critical,high"}'
|
|
```
|
|
|
|
Die Reservierung (Lease) läuft nach 30 Minuten automatisch ab. Brauchst du
|
|
länger, erneuere sie mit `action=claim` auf dieselbe ID.
|
|
|
|
### 4.2 Zwischenstand dokumentieren
|
|
|
|
```bash
|
|
curl -X POST "https://dc.mhdf.de/api/bugtracker/v1/manage?action=comment&id=42" \
|
|
-H "Authorization: Bearer $DC_TOKEN" \
|
|
-H "Content-Type: application/json" \
|
|
-d '{
|
|
"comment": "Ursache gefunden: Session wird vor dem Redirect nicht initialisiert.",
|
|
"action_taken": "investigated"
|
|
}'
|
|
```
|
|
|
|
Empfohlene Werte für `action_taken`: `investigated`, `fix_proposed`,
|
|
`pr_opened`, `needs_human`, `blocked`, `commented`.
|
|
|
|
### 4.3 Abschließen
|
|
|
|
```bash
|
|
curl -X POST "https://dc.mhdf.de/api/bugtracker/v1/manage?action=resolve&id=42" \
|
|
-H "Authorization: Bearer $DC_TOKEN" \
|
|
-H "Content-Type: application/json" \
|
|
-d '{
|
|
"resolved_in_build": "v1.4.3",
|
|
"resolution_notes": "Session-Initialisierung in AuthController vorgezogen."
|
|
}'
|
|
```
|
|
|
|
### 4.4 Wieder freigeben
|
|
|
|
Kommst du nicht weiter, gib das Item zurück, statt den Lease verfallen zu lassen:
|
|
|
|
```bash
|
|
curl -X POST "https://dc.mhdf.de/api/bugtracker/v1/manage?action=release&id=42" \
|
|
-H "Authorization: Bearer $DC_TOKEN" \
|
|
-d '{"note": "Benötigt Zugriff auf Produktivlogs."}'
|
|
```
|
|
|
|
---
|
|
|
|
## 5. Lesen und Filtern
|
|
|
|
```bash
|
|
curl "https://dc.mhdf.de/api/bugtracker/v1/manage?action=list&project_slug=myapp&status=open,in_progress&order=severity&limit=20" \
|
|
-H "Authorization: Bearer $DC_TOKEN"
|
|
```
|
|
|
|
| Parameter | Bedeutung |
|
|
|---|---|
|
|
| `status`, `severity` | Mehrere Werte kommagetrennt |
|
|
| `type`, `environment`, `project_slug` | Einzelwert oder `all` |
|
|
| `target_agent`, `claimed_by`, `push_id` | Exakte Übereinstimmung |
|
|
| `search` | Volltext über Titel, Beschreibung, Fehlermeldung, Tags, Dateipfad. Eine Zahl findet zusätzlich das Item mit dieser **Nummer**, `#288` ausschließlich dieses eine |
|
|
| `unclaimed_only` | `true` — nur Items, die kein Agent bearbeitet |
|
|
| `updated_since` | ISO-8601 — **Delta-Abfrage für effizientes Polling** |
|
|
| `order` | `newest`, `oldest`, `updated`, `severity`, `occurrences` |
|
|
| `limit`, `offset` | Pagination, max. 500 pro Seite |
|
|
|
|
Die Antwort enthält `total`, `limit`, `offset` und `has_more`.
|
|
|
|
### Polling-Muster
|
|
|
|
```bash
|
|
# Nur was sich seit dem letzten Durchlauf geändert hat
|
|
curl "…/manage?action=list&updated_since=2026-08-07T09:00:00Z&order=updated" \
|
|
-H "Authorization: Bearer $DC_TOKEN"
|
|
```
|
|
|
|
---
|
|
|
|
## 6. Release veröffentlichen und Items automatisch schließen
|
|
|
|
Der Kreis schließt sich hier: Items, deren `resolved_in_build` der
|
|
veröffentlichten Version entspricht, werden beim Publish automatisch geschlossen.
|
|
|
|
```bash
|
|
curl -X POST https://dc.mhdf.de/api/updateservice/v1/publish \
|
|
-H "Authorization: Bearer $DC_TOKEN" \
|
|
-H "Content-Type: application/json" \
|
|
-d '{
|
|
"product_slug": "myapp",
|
|
"version": "1.4.3",
|
|
"channel": "prod",
|
|
"download_url": "https://dc.mhdf.de/downloads/myapp-1.4.3.zip",
|
|
"sha256_hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
|
|
"git_commit": "a21536f",
|
|
"release_notes": "Behebt den Login-Fehler."
|
|
}'
|
|
```
|
|
|
|
```json
|
|
{
|
|
"status": "success",
|
|
"release_id": 12,
|
|
"created": true,
|
|
"auto_resolved": 3,
|
|
"message": "Release 1.4.3 (prod) für \"myapp\" veröffentlicht. 3 Bugtracker-Item(s) automatisch geschlossen."
|
|
}
|
|
```
|
|
|
|
Der Versionsvergleich folgt der semantischen Versionsordnung — `1.10.0` gilt
|
|
korrekt als neuer als `1.9.0`.
|
|
|
|
---
|
|
|
|
## 7. Fehlerbehandlung
|
|
|
|
Fehler tragen einen stabilen, maschinenlesbaren Code. Reagiere auf `code`,
|
|
nicht auf `message`:
|
|
|
|
```json
|
|
{
|
|
"status": "error",
|
|
"error": { "code": "already_claimed", "message": "Item #42 ist bereits vergeben." }
|
|
}
|
|
```
|
|
|
|
| Code | HTTP | Bedeutung und Reaktion |
|
|
|---|---|---|
|
|
| `unauthorized` | 401 | Token fehlt, ist abgelaufen oder hat den Scope nicht |
|
|
| `project_forbidden` | 403 | Token ist an ein anderes Projekt gebunden |
|
|
| `already_claimed` | 409 | Anderer Agent arbeitet daran — nächstes Item nehmen |
|
|
| `not_claimed` | 409 | Freigabe eines Items, das dir nicht gehört |
|
|
| `not_found` | 404 | Item existiert nicht |
|
|
| `rate_limited` | 429 | Sendefrequenz senken, später erneut |
|
|
| `invalid_json` | 400 | Request-Body ist kein gültiges JSON |
|
|
| `missing_id`, `missing_status`, `missing_build` | 400 | Pflichtfeld fehlt |
|
|
| `invalid_status`, `invalid_version`, `invalid_hash` | 400 | Wert nicht zulässig |
|
|
| `internal_error` | 500 | Serverfehler — wird automatisch selbst im Bugtracker erfasst |
|
|
|
|
**Rate-Limit:** 60 Reports pro Minute und IP. Bei `429` das Intervall verdoppeln.
|
|
|
|
---
|
|
|
|
## 8. Vollständige Beispielschleife (Python)
|
|
|
|
```python
|
|
import os, requests
|
|
|
|
BASE = "https://dc.mhdf.de/api/bugtracker/v1/manage"
|
|
HEAD = {"Authorization": f"Bearer {os.environ['DC_TOKEN']}",
|
|
"Content-Type": "application/json"}
|
|
|
|
|
|
def next_item(project):
|
|
r = requests.post(f"{BASE}?action=next", headers=HEAD,
|
|
json={"project_slug": project, "limit": 1})
|
|
r.raise_for_status()
|
|
items = r.json().get("items", [])
|
|
return items[0] if items else None
|
|
|
|
|
|
def comment(item_id, text, action="investigated"):
|
|
requests.post(f"{BASE}?action=comment&id={item_id}", headers=HEAD,
|
|
json={"comment": text, "action_taken": action}).raise_for_status()
|
|
|
|
|
|
def resolve(item_id, build, notes):
|
|
requests.post(f"{BASE}?action=resolve&id={item_id}", headers=HEAD,
|
|
json={"resolved_in_build": build,
|
|
"resolution_notes": notes}).raise_for_status()
|
|
|
|
|
|
def release(item_id, reason):
|
|
requests.post(f"{BASE}?action=release&id={item_id}", headers=HEAD,
|
|
json={"note": reason}).raise_for_status()
|
|
|
|
|
|
item = next_item("myapp")
|
|
if item is None:
|
|
print("Nichts zu tun.")
|
|
else:
|
|
print(f"#{item['id']}: {item['title']}")
|
|
if item.get("file_path"):
|
|
print(f" -> {item['file_path']}:{item.get('line_no', '?')}")
|
|
|
|
comment(item["id"], "Analyse gestartet.")
|
|
try:
|
|
# ... hier die eigentliche Arbeit ...
|
|
resolve(item["id"], "v1.4.3", "Fix in AuthController.")
|
|
except Exception as exc:
|
|
release(item["id"], f"Abbruch: {exc}")
|
|
```
|
|
|
|
---
|
|
|
|
## 8a. Fehler melden (Laufzeitfehler)
|
|
|
|
Für den globalen Exception-Handler einer Anwendung gibt es einen schlankeren
|
|
Eingang. Titel und Dringlichkeit leitet der Server ab:
|
|
|
|
```bash
|
|
curl -X POST https://dc.mhdf.de/api/errors/v1/report \
|
|
-H "Authorization: Bearer $DC_TOKEN" \
|
|
-H "Content-Type: application/json" \
|
|
-d '{
|
|
"project_slug": "polytrader",
|
|
"exception": "PDOException",
|
|
"message": "SQLSTATE[23000]: Duplicate entry '\''MKT-88213'\'' for key '\''uq_market'\''",
|
|
"stack_trace": "at Importer.php:142",
|
|
"level": "error",
|
|
"build": "v2.0.1",
|
|
"environment": "production",
|
|
"file": "src/Market/Importer.php",
|
|
"line": 142
|
|
}'
|
|
```
|
|
|
|
`level` unterscheidet die technische Art des Ereignisses — unabhängig von der
|
|
geschäftlichen Dringlichkeit:
|
|
|
|
| Wert | Bedeutung |
|
|
|---|---|
|
|
| `fatal` | Der Prozess hat sich beendet |
|
|
| `error` | Ein Vorgang ist fehlgeschlagen, das Programm läuft weiter (Vorgabe) |
|
|
| `warning` | Auffälligkeit ohne Funktionsverlust |
|
|
|
|
### Gruppierung
|
|
|
|
Gleiche Fehler werden zu einer Gruppe zusammengefasst und hochgezählt.
|
|
Veränderliche Bestandteile werden dabei ausgeblendet — Werte in
|
|
Anführungszeichen, die Ziffern enthalten, Speicheradressen, GUIDs, Zeitstempel
|
|
und Zeilennummern. Diese drei Meldungen ergeben **eine** Gruppe:
|
|
|
|
```
|
|
Duplicate entry 'MKT-88213' for key 'uq_market'
|
|
Duplicate entry 'AA-1' for key 'uq_market'
|
|
Duplicate entry 'X-99471' for key 'uq_market'
|
|
```
|
|
|
|
Ein anderer Unique-Key (`uq_orders`) bleibt dagegen eine eigene Gruppe — der
|
|
Schlüsselname enthält keine Ziffern und zählt damit zur Identität des Fehlers.
|
|
|
|
### Bekannte, harmlose Fehler
|
|
|
|
Manche Fehler treten betriebsbedingt auf und sind belanglos. Dafür gibt es
|
|
Ignore-Regeln, die im WebUI unter **Bugtracker → Ignore-Regeln** gepflegt
|
|
werden. Greift eine Regel, wird der Fehler weiterhin erfasst und **hochgezählt**,
|
|
bleibt aber aus der Übersicht heraus und löst keine Benachrichtigung aus:
|
|
|
|
```json
|
|
{ "status": "success", "item_id": 42, "ignored": true,
|
|
"ignore_rule_id": 3, "occurrence_count": 3841, "rate_alerted": false,
|
|
"message": "Als bekannt eingestuft, gezaehlt, nicht gemeldet." }
|
|
```
|
|
|
|
Der Zähler ist dabei der eigentliche Zweck: Zu jeder Regel lässt sich eine
|
|
Alarmschwelle hinterlegen. Dass ein bekannter Fehler auftritt, ist normal —
|
|
dass er plötzlich hundertmal so oft auftritt, ist ein Signal. Wird die Schwelle
|
|
überschritten, meldet die Antwort `"rate_alerted": true` und ein Webhook
|
|
`error.rate_exceeded` wird ausgelöst.
|
|
|
|
---
|
|
|
|
## 9. Watchdog-Heartbeat
|
|
|
|
Läuft dein Agent als Dienst, melde dich regelmäßig:
|
|
|
|
```bash
|
|
curl -X POST https://dc.mhdf.de/api/watchdog/v1/ping \
|
|
-H "Authorization: Bearer $DC_TOKEN" \
|
|
-H "Content-Type: application/json" \
|
|
-d '{"source": "agent-worker-01", "status": "ok", "interval": 60,
|
|
"message": "Verarbeite Warteschlange", "metrics": {"queue": 3}}'
|
|
```
|
|
|
|
`interval` ist der erwartete Abstand in Sekunden. Bleibt der Heartbeat aus,
|
|
stuft der Evaluator den Monitor nach dem Doppelten auf `warning` und nach dem
|
|
Vierfachen auf `down`.
|
|
|
|
### Eigenen Gesundheitszustand mitsenden
|
|
|
|
Ein Heartbeat beweist nur, dass ein Thread läuft — nicht, dass die Anwendung
|
|
ihre Arbeit tut. Deshalb kann sie ihren Zustand selbst mitschicken:
|
|
|
|
```json
|
|
{ "source": "polytrader-worker",
|
|
"status": "warning",
|
|
"interval": 60,
|
|
"checks": {
|
|
"db": { "ok": true },
|
|
"market_feed": { "ok": false, "message": "Letzter Tick vor 14 min" },
|
|
"queue": { "ok": true, "value": 23 }
|
|
},
|
|
"metrics": { "cpu": 18, "ram": 42, "queue_depth": 23 } }
|
|
```
|
|
|
|
Das Deploymentcenter interpretiert die Namen der Prüfungen **nicht** — es liest
|
|
nur `ok` und `message`. Was „gesund" bedeutet, entscheidet jede Anwendung
|
|
selbst. Schlägt eine Prüfung fehl, wird ein als `ok` gemeldeter Heartbeat auf
|
|
`warning` herabgestuft.
|
|
|
|
Der Weg ist bewusst ausgehend: Es müssen keine Ports auf den Zielmaschinen
|
|
geöffnet werden.
|
|
|
|
### Metriken
|
|
|
|
Numerische Werte aus `metrics` landen im Verlauf und lassen sich abfragen:
|
|
|
|
```bash
|
|
# Welche Metriken liefert dieser Monitor?
|
|
curl "https://dc.mhdf.de/api/watchdog/v1/metrics?source=polytrader-worker" \
|
|
-H "Authorization: Bearer $DC_TOKEN"
|
|
|
|
# Verlauf einer Metrik, auf 15-Minuten-Fenster verdichtet
|
|
curl "https://dc.mhdf.de/api/watchdog/v1/metrics?source=polytrader-worker&metric=queue_depth&hours=24" \
|
|
-H "Authorization: Bearer $DC_TOKEN"
|
|
```
|
|
|
|
Die Antwort enthält zusätzlich `deviation` — den Vergleich des aktuellen Werts
|
|
mit dem Durchschnitt der letzten sieben Tage desselben Monitors. Damit lassen
|
|
sich Auffälligkeiten erkennen, ohne für jedes Projekt Schwellwerte zu pflegen.
|
|
|
|
Verschachtelte Werte werden flach abgelegt: `{"cpu":{"load":1.2}}` wird zu
|
|
`cpu.load`. Rohwerte werden 14 Tage aufbewahrt.
|
|
|
|
### Abhängigkeiten
|
|
|
|
Ist bei einem Monitor `parent_source` gesetzt und fällt der übergeordnete
|
|
Monitor aus, werden Alarme für die Kinder unterdrückt. Ihr Zustand bleibt im
|
|
Dashboard sichtbar — es entsteht nur nicht für jede VM eines ausgefallenen
|
|
Hypervisors eine eigene Meldung.
|
|
|
|
---
|
|
|
|
## 10. Verfügbarkeit prüfen
|
|
|
|
```bash
|
|
curl https://dc.mhdf.de/api/health -H "Authorization: Bearer $DC_TOKEN"
|
|
```
|
|
|
|
Meldet Datenbankzustand, ausstehende Migrationen, Bugtracker-Kennzahlen und
|
|
wann der Watchdog-Evaluator zuletzt lief.
|