* * * * * /usr/bin/php = e(DC_ROOT) ?>/cli/tick.php --quiet
* * * * * curl -fsS -H "Authorization: Bearer <SHARED_KEY>" = e($baseUrl) ?>/api/watchdog/v1/evaluate > /dev/null
🛡️ Watchdog System-Hierarchie & Monitore
| Hierarchie / Entity Source | Typ | Status | Version | Letzte Meldung | Zuletzt Gesehen |
|---|---|---|---|---|---|
|
= $m['is_last'] ? '└─' : '├─' ?>
|
= htmlspecialchars($m['type']) ?> |
● = strtoupper($m['state']) ?> |
= htmlspecialchars((string)$m['app_version']) ?>
–
|
= htmlspecialchars($m['last_message'] ?? '-') ?> | = htmlspecialchars($m['last_seen_utc'] ?? 'Nie') ?> |
📁 Neues Projekt anlegen / Bearbeiten
Projekte Übersicht & Verwaltung
| ID | Slug | Projekt Name | Cache TTL | Verknüpfte Lizenzen | Verknüpfte Releases | Aktionen |
|---|---|---|---|---|---|---|
| = $p['id'] ?> | = htmlspecialchars($p['slug']) ?> |
= htmlspecialchars($p['name']) ?> | = $p['default_cache_ttl_hours'] ?> h (= round($p['default_cache_ttl_hours']/24, 1) ?> Tage) | = $licCount ?> Lizenzen | = $relCount ?> Releases |
⚠️ Projekt unwiderruflich löschen
Sind Sie sicher, dass Sie das Projekt löschen möchten?
Bitte geben Sie zur Sicherheitsbestätigung den Projekt-Slug ein:
✏️ Monitor & Icon bearbeiten
🔑 Neuen Lizenzschlüssel generieren
Erstellte Lizenzschlüssel
| Projekt | Lizenzschlüssel | Kunde | Aktivierungen | Status | Ablaufdatum | Aktionen |
|---|---|---|---|---|---|---|
| Noch keine Lizenzen angelegt. | ||||||
| = e($l['product_name']) ?> | = e($l['license_key']) ?> |
= e($l['customer_name'] ?? '—') ?>
= e($l['customer_email']) ?>
|
= $used ?> / = $max ?> | = e(strtoupper((string)$l['status'])) ?> | = !empty($l['expires_at']) ? e(dc_dt((string)$l['expires_at'], 'd.m.Y')) : 'Unbefristet' ?> | |
🖥️ Aktivierte Hardware
| Projekt | Lizenzschlüssel | Hardware-ID / Quelle | Plattform | Hostname | Zuletzt gesehen | Status | Aktionen |
|---|---|---|---|---|---|---|---|
| Noch keine Aktivierungen. | |||||||
| = e($a['product_name']) ?> | = e($a['license_key']) ?> |
= e($a['hardware_id']) ?>
Quelle: = e($a['hwid_source']) ?>
|
= e(strtoupper((string)($a['platform'] ?? 'WIN'))) ?> · v= (int)($a['hwid_version'] ?? 1) ?> | = e($a['hostname'] ?? '—') ?> | = e(dc_ago($a['last_seen'] ?? null)) ?> | = !empty($a['is_blocked']) ? 'GESPERRT' : 'AKTIV' ?> |
|
💾 Offline-Lizenzdatei (.lic)
Für Systeme ohne Internetzugang. Die Datei wird serverseitig erzeugt und mit
HMAC-SHA256 über den Schlüssel aus security.license_key signiert.
Am schnellsten geht es über den 📥 .lic-Knopf direkt in der Lizenzliste.
Diese Vorschau dient nur der Ansicht. Die gültige, signierte Datei liefert der 📥 .lic-Knopf in der Lizenzliste.
📜 Audit-Protokoll
| ID | Zeitpunkt | Akteur | Aktion | Details |
|---|---|---|---|---|
| Noch keine Einträge. | ||||
| = (int)$log['id'] ?> | = e(dc_dt((string)$log['created_at'])) ?> | = e($log['actor']) ?> |
= e($log['action']) ?> | = e($log['details'] ?? '—') ?> |
💻 Endpunkte & Anbindung
/validate trägt den Lizenzzustand im Feld
status auf oberster Ebene (valid, revoked,
expired, not_found, activation_limit) —
bewusst ohne den Umschlag der übrigen API, weil bereits ausgelieferte Clients
dieses Format erwarten.
Fertige Anbindung für .NET: Deploymentcenter.Client
(LicenseClient, HardwareId, verschlüsselter Offline-Cache).
Ausführlich in docs/LICENSE_INTEGRATION_GUIDE.md.
📁 Gruppen-Übersicht
🌳 Watchdog System-Hierarchie
| Name | Typ | Status | Version | Zuletzt gesehen | Kurz-Info / Message | Aktionen |
|---|---|---|---|---|---|---|
|
= $m['is_last'] ? '└─' : '├─' ?>
|
= htmlspecialchars($m['type']) ?> |
= strtoupper($m['state']) ?> |
= htmlspecialchars((string)$m['app_version']) ?>
–
|
= htmlspecialchars($m['last_seen_utc'] ?? 'Nie') ?> | = htmlspecialchars($m['last_message'] ?? '-') ?> |
🖥️ Monitor Anlegen
📜 Chronologisches Event-Log
| Zeitpunkt (UTC) | Source | Kind | Severity | Nachricht |
|---|---|---|---|---|
| = htmlspecialchars($e['at_utc']) ?> | = htmlspecialchars($e['source']) ?> | = htmlspecialchars($e['kind']) ?> |
= strtoupper($e['severity']) ?> | = htmlspecialchars($e['message'] ?? '-') ?> |
Neuen Agent-Token erstellen
Agent Tokens
| Token ID | Bezeichnung | Gebundene Source | Token Value | Status | Aktion |
|---|---|---|---|---|---|
= htmlspecialchars($tok['token_id']) ?> |
= htmlspecialchars($tok['name']) ?> | = htmlspecialchars($tok['monitor_source'] ?? 'Alle Sources') ?> |
= htmlspecialchars($masked) ?>
|
= $tok['revoked'] ? 'WIDERUFEN' : 'AKTIV' ?> |
📦 Veröffentlichte Software Releases
| Projekt | Kanal | Plattform | Version | Git Commit | Größe | Release Notes | Download & SHA256 | Datum |
|---|---|---|---|---|---|---|---|---|
| = htmlspecialchars($r['product_slug']) ?> | = strtoupper(htmlspecialchars($r['channel'] ?? 'prod')) ?> |
= htmlspecialchars($platformLabel) ?>
|
v= htmlspecialchars($r['version']) ?>
KRITISCH
UNSIGNIERT
|
= htmlspecialchars($r['git_commit'] ?? 'n/a') ?> |
= $sizeFormatted ?> | = htmlspecialchars($r['release_notes'] ?? '-') ?> |
⬇️ Download Package
SHA: = htmlspecialchars(substr($r['sha256_hash'], 0, 12)) ?>...
|
= htmlspecialchars($r['created_at']) ?> |
Neues Software-Release veröffentlichen
🤖 Aktive Agenten
🐛 Bugs, Features & Ideen = (int)$bugtrackerTotal ?> Treffer
| ID / Typ | Umgebung | Projekt & Titel | Build | Schweregrad | Anzahl | Status | Aktionen |
|---|---|---|---|---|---|---|---|
| Keine Einträge für diese Filterkombination. | |||||||
| #= (int)$item['id'] ?> = $typeBadge ?> |
= $envBadge ?> |
= e((string)$item['title']) ?>
Projekt:
= e((string)$item['project_slug']) ?>
Von: = e((string)$item['created_by']) ?>
= e(dc_ago($item['last_seen_at'] ?? null)) ?>
🔒 = e((string)$item['claimed_by']) ?>
📲 = e((string)$item['push_id']) ?>
🤖 = e((string)$item['target_agent']) ?>
📄 = e((string)$item['file_path']) ?>= !empty($item['line_no']) ? ':' . (int)$item['line_no'] : '' ?>
🏷️ = e((string)$item['tags']) ?>
|
= e((string)($item['build_version'] ?? 'unbekannt')) ?> |
= $sevBadge ?> | = (int)$item['occurrence_count'] ?>x | = $statusBadge ?> |
|
➕ Bug, Feature Request oder Idee Erfassen
⚡ Fehler-Stream = (int)$errorTotal ?> Gruppen
| Klasse | Fehler | Projekt / Umgebung | Build | Anzahl | Zuletzt | Aktionen |
|---|---|---|---|---|---|---|
|
Keine Fehler für diese Filterkombination.
Stummgeschaltete Einträge sind ausgeblendet — über „Nur stummgeschaltete“ sichtbar. |
||||||
| = $levelBadge ?> |
= e(mb_strimwidth((string)$item['title'], 0, 90, '…')) ?>
🔇 stummgeschaltet= !empty($item['ignore_rule_id']) ? ' (Regel #' . (int)$item['ignore_rule_id'] . ')' : '' ?>
1): ?>
📈 = $windowCount ?>× in dieser Stunde
📄 = e((string)$item['file_path']) ?>= !empty($item['line_no']) ? ':' . (int)$item['line_no'] : '' ?>
|
= e((string)$item['project_slug']) ?>
= e(strtoupper((string)$item['environment'])) ?>
|
= e((string)($item['build_version'] ?? '—')) ?> |
= number_format((int)$item['occurrence_count'], 0, ',', '.') ?>× | = e(dc_ago($item['last_seen_at'] ?? null)) ?> |
|
🔇 Bekannte, harmlose Fehler
Ein Treffer bedeutet nicht „wegwerfen“: Der Fehler wird weiterhin erfasst und hochgezählt, bleibt aber aus der Übersicht heraus und löst keine Benachrichtigung aus. Der Zähler ist dabei der eigentliche Gewinn — dass ein bekannter Fehler auftritt, ist normal; dass er plötzlich hundertmal so oft auftritt, ist ein Signal. Dafür ist die Alarmschwelle da.
Bestehende Regeln
| # | Projekt | Muster | Begründung | Alarmschwelle | Treffer | Status | Aktionen |
|---|---|---|---|---|---|---|---|
| Noch keine Regeln angelegt. | |||||||
| = (int)$rule['id'] ?> |
ALLE
= e((string)$rule['project_slug']) ?>
|
= e((string)$rule['pattern']) ?>
= e((string)$rule['match_type']) ?>
|
= e(mb_strimwidth((string)$rule['reason'], 0, 160, '…')) ?> | = (int)$rule['alert_on_rate'] ?>/h — |
= number_format((int)$rule['match_count'], 0, ',', '.') ?>
= (int)($rule['item_count'] ?? 0) ?> Item(s)
· = e(dc_ago((string)$rule['last_match_at'])) ?>
|
= $enabled ? 'AKTIV' : 'INAKTIV' ?> |
|
💻 Anbindung
Ein Aufruf, den man in den globalen Exception-Handler hängt. Titel und Dringlichkeit leitet der Server ab, die Regeln oben greifen automatisch.
👑 Master-Tokens (Selbst-Provisionierung für Client-Apps & Host-Skripte)
| Token ID | Bezeichnung | Typ / Identität | Projekt / Lizenz | Rechte (Scopes) | Sub-Tokens | Token Key | Aktionen |
|---|---|---|---|---|---|---|---|
= htmlspecialchars($mTok['token_id']) ?> |
= htmlspecialchars($mTok['name']) ?> |
= strtoupper($mTok['owner_type']) ?> = htmlspecialchars($mTok['owner_identity'] ?? '-') ?> |
= htmlspecialchars($mTok['project_slug'] ?? '-') ?>
= !empty($mTok['license_key']) ? ' Lic: ' . htmlspecialchars($mTok['license_key']) . '' : '' ?> |
= htmlspecialchars($sc) ?> | = (int)($mTok['sub_token_count'] ?? 0) ?> Sub-Tokens |
= htmlspecialchars($masked) ?>
|
WIDERUFEN
|
🔑 Aktive Sub-Tokens (Per Provisioning API Erstellt)
| Token ID | Parent Master ID | Bezeichnung / Client | Umgebung | Scopes | Token Key | Zuletzt Genutzt | Status | Aktionen |
|---|---|---|---|---|---|---|---|---|
= htmlspecialchars($sTok['token_id']) ?> |
= htmlspecialchars($sTok['parent_token_id'] ?? '-') ?> |
= htmlspecialchars($sTok['name']) ?> | = strtoupper($sTok['environment']) ?> | = htmlspecialchars($sc) ?> |
= htmlspecialchars($sMasked) ?>
|
= $sTok['last_used_at'] ? htmlspecialchars($sTok['last_used_at']) : 'Noch nie' ?> | = $sTok['revoked'] ? 'WIDERUFEN' : 'AKTIV' ?> |
|
➕ Neuen Master-Token Erstellen
⚙️ Server & Umgebung
🩺 Systemzustand
| Prüfung | Zustand | Hinweis |
|---|---|---|
| Watchdog-Evaluator | = $evaluatorStale ? 'INAKTIV' : 'AKTIV' ?> | Letzter Lauf: = e(dc_dt((string)$evaluatorLastRun)) ?> (= e(dc_ago((string)$evaluatorLastRun)) ?>) Noch nie gelaufen — ohne ihn bleiben ausgefallene Monitore „up“. |
| Log-Verzeichnis beschreibbar | = $logWritable ? 'OK' : 'PRÜFEN' ?> | var/log/ — Fehlerprotokolle |
| Konfiguration ausserhalb Git | OK | config/config.php ist per .gitignore ausgeschlossen |
📖 API-Dokumentation
Die Schnittstelle beschreibt sich selbst. Der frühere fest im Quelltext hinterlegte Textblock ist durch eine maschinenlesbare OpenAPI-Beschreibung ersetzt — ein Agent kann sie abrufen und sich daran orientieren, ohne dass eine Prompt-Vorlage gepflegt werden muss.
🗄️ Datenbank-Migration
Führt ausstehende Migrationen aus. Bereits angewendete Versionen werden in
dc_migrations vermerkt und übersprungen.