83 83
84| Flag | Standard | Beschreibung |84| Flag | Standard | Beschreibung |
85| :- | :- | :- |85| :- | :- | :- |
86| `--hook-concurrency <n>` | `4` | Maximale `spawn-runner` Hooks, die parallel laufen. Begrenzt auch, wie viele Spawn-Anfragen pro Abfrage beansprucht werden. |86| `--hook-concurrency <n>` | `4` | Maximale `spawn-runner` Hooks, die parallel laufen. Begrenzt auch, wie viele Spawn-Anfragen pro Abfrage beansprucht werden. Der Orchestrator sucht erst dann nach neuen Spawn-Anfragen, wenn jeder von ihm gestartete Hook beendet ist, sodass ein langsamer Hook die nächsten Hooks dieses Orchestrators verzögert. |
87| `--hook-timeout <sec>` | `60` | Beenden Sie den Prozessbaum des Hooks nach dieser vielen Sekunden. Das Timeout plus seine 5-Sekunden-Kill-Gnadenfrist müssen unter `--expected-spawn-seconds` bleiben; der Orchestrator erzwingt dies beim Start. |87| `--hook-timeout <sec>` | `60` | Beenden Sie den Prozessbaum des Hooks nach dieser vielen Sekunden. Das Timeout plus seine 5-Sekunden-Kill-Gnadenfrist müssen unter `--expected-spawn-seconds` bleiben; der Orchestrator erzwingt dies beim Start. |
88| `--expected-spawn-seconds <sec>` | `120` | Erwartete p99-Zeit vom Empfang einer Spawn-Anfrage durch den Orchestrator bis zur Registrierung des Runners, einschließlich einer etwaigen Wartezeit auf Kapazität auf Ihrer Plattform. Der Server erzwingt einen Bereich von 10 bis 3600. Wird bei jeder Abfrage als Server-seitige Lease gesendet: Wenn sich kein Runner registriert, bevor sie verstreicht, wird die Sitzung mit einer frischen Bestellungs-ID erneut angeboten. Alle Replikas müssen diesen Wert teilen. |88| `--expected-spawn-seconds <sec>` | `120` | Erwartete p99-Zeit vom Empfang einer Spawn-Anfrage durch den Orchestrator bis zur Registrierung des Runners, einschließlich einer etwaigen Wartezeit auf Kapazität auf Ihrer Plattform. Der Server erzwingt einen Bereich von 10 bis 3600. Wird bei jeder Abfrage als Server-seitige Lease gesendet: Wenn sich kein Runner registriert, bevor sie verstreicht, wird die Sitzung mit einer frischen Bestellungs-ID erneut angeboten. Alle Replikas müssen diesen Wert teilen. |
89| `--min-idle <n>` | `0` | Halten Sie mindestens N untätige Session-Slots frei, indem Sie proaktiv Standby-Runner erzeugen. `0` deaktiviert Vorwärmung. Koppeln Sie mit dem `--exit-if-unused-min` des Runners, sodass überschüssige Standby-Runner sich selbst zurückfordern. |89| `--min-idle <n>` | `0` | Halten Sie mindestens N untätige Session-Slots frei, indem Sie proaktiv Standby-Runner erzeugen. `0` deaktiviert Vorwärmung. Koppeln Sie mit dem `--exit-if-unused-min` des Runners, sodass überschüssige Standby-Runner sich selbst zurückfordern. |
116| `SELF_HOSTED_RUNNER_MAX_LIFETIME_GRACE_MS` | `900000` | Wie lange der Runner wartet, nachdem eine Sitzung ihr `--kill-session-after-min` Limit erreicht hat, damit ein laufender Zug beendet wird oder die Freigabe abgeschlossen wird, bevor die Sitzung beendet wird |116| `SELF_HOSTED_RUNNER_MAX_LIFETIME_GRACE_MS` | `900000` | Wie lange der Runner wartet, nachdem eine Sitzung ihr `--kill-session-after-min` Limit erreicht hat, damit ein laufender Zug beendet wird oder die Freigabe abgeschlossen wird, bevor die Sitzung beendet wird |
117| `SELF_HOSTED_RUNNER_POST_TURN_SETTLE_MS` | `7000` | Obergrenze für die Zeit, die der Runner eine Sitzung als beschäftigt für die `--drain-wait-sec` Entleerung nach Abschluss eines Zugs zählt, während der Prozess der Sitzung das Ende des Zugs an Anthropic meldet. `0` oder ein unbrauchbarer Wert fällt auf den Standard zurück, sodass die Sperre nicht ausgeschaltet werden kann. Erfordert Claude Code v2.1.275 oder später. |117| `SELF_HOSTED_RUNNER_POST_TURN_SETTLE_MS` | `7000` | Obergrenze für die Zeit, die der Runner eine Sitzung als beschäftigt für die `--drain-wait-sec` Entleerung nach Abschluss eines Zugs zählt, während der Prozess der Sitzung das Ende des Zugs an Anthropic meldet. `0` oder ein unbrauchbarer Wert fällt auf den Standard zurück, sodass die Sperre nicht ausgeschaltet werden kann. Erfordert Claude Code v2.1.275 oder später. |
118| `SELF_HOSTED_RUNNER_SIGKILL_GRACE_MS` | `30000` | Wie lange der Runner wartet, bis das Betriebssystem `SIGKILL` an ein Kind sendet, das in nicht unterbrechbarem I/O steckt, bevor es sich selbst beendet. Auf `--post-session-hook-timeout-sec` plus 15 Sekunden begrenzt, und 30 weitere, wenn `--push-outcome-on-release` gesetzt ist, sodass das effektive Minimum 75 Sekunden bei Standardwerten ist. |118| `SELF_HOSTED_RUNNER_SIGKILL_GRACE_MS` | `30000` | Wie lange der Runner wartet, bis das Betriebssystem `SIGKILL` an ein Kind sendet, das in nicht unterbrechbarem I/O steckt, bevor es sich selbst beendet. Auf `--post-session-hook-timeout-sec` plus 15 Sekunden begrenzt, und 30 weitere, wenn `--push-outcome-on-release` gesetzt ist, sodass das effektive Minimum 75 Sekunden bei Standardwerten ist. |
119| `CLAUDE_RUNNER_FETCH_DEPTH` | `50` | Git-Fetch-Tiefe für frische Klone. Setzen Sie eine positive Ganzzahl oder `full` oder `0` für einen vollständigen Fetch. Repositories, die bereits im Arbeitsbereich vorhanden sind, behalten ihre bestehende Tiefe. |119| `CLAUDE_RUNNER_FETCH_DEPTH` | `50` | Git-Fetch-Tiefe für frische Klone. Setzen Sie eine positive Ganzzahl oder `full` oder `0` für einen vollständigen Fetch. Informationen zu einem Klon, der sich bereits im Arbeitsbereich befindet, finden Sie unter [Einen vorgewärmten Checkout wiederverwenden](https://code.claude.com/docs/de/self-hosted-environments-deploy.md#reuse-a-pre-warmed-checkout). |
120| `CLAUDE_RUNNER_FETCH_SERVER_PROGRESS_CAP_MS` | `600000` | Wie lange in Millisekunden pro Versuch ein Git-Fetch auf seine ersten Daten warten darf, während die eigenen Fortschrittszahlen des Git-Servers weiter steigen, etwa wenn der Server das Pack für ein großes Repository vorbereitet. `0` oder `off` schaltet das Warten aus: Ein solcher Fetch wird dann nach zwei Minuten ohne Daten abgebrochen. Jede andere Ganzzahl wird auf einen Wert zwischen `120000` und `1800000` begrenzt, also 2 bis 30 Minuten. Erfordert Claude Code v2.1.295 oder später. |120| `CLAUDE_RUNNER_FETCH_SERVER_PROGRESS_CAP_MS` | `600000` | Wie lange in Millisekunden pro Versuch ein Git-Fetch auf seine ersten Daten warten darf, während die eigenen Fortschrittszahlen des Git-Servers weiter steigen, etwa wenn der Server das Pack für ein großes Repository vorbereitet. `0` oder `off` schaltet das Warten aus: Ein solcher Fetch wird dann nach zwei Minuten ohne Daten abgebrochen. Jede andere Ganzzahl wird auf einen Wert zwischen `120000` und `1800000` begrenzt, also 2 bis 30 Minuten. Erfordert Claude Code v2.1.295 oder später. |
121| `CLAUDE_RUNNER_SKIP_GIT_VERIFY` | nicht gesetzt | Wenn `1`, überspringen Sie die `.git` Präsenzprüfung, nachdem ein `checkout` Hook ausgeführt wird. Setzen Sie dies, wenn Ihr Hook eine Nicht-Git-Quelle materialisiert. |121| `CLAUDE_RUNNER_SKIP_GIT_VERIFY` | nicht gesetzt | Wenn `1`, überspringen Sie die `.git` Präsenzprüfung, nachdem ein `checkout` Hook ausgeführt wird. Setzen Sie dies, wenn Ihr Hook eine Nicht-Git-Quelle materialisiert. |
122| `FORCE_AUTOUPDATE_PLUGINS` | nicht gesetzt | Wenn `1`, lassen Sie Plugin-Marktplätze automatisch aktualisieren, obwohl die Binärdatei angeheftet ist |122| `FORCE_AUTOUPDATE_PLUGINS` | nicht gesetzt | Wenn `1`, lassen Sie Plugin-Marktplätze automatisch aktualisieren, obwohl die Binärdatei angeheftet ist |
152 152
153## Prometheus-Metriken153## Prometheus-Metriken
154 154
155Jeder Runner bedient Prometheus-Metriken bei `GET /metrics` auf demselben Port wie `/healthz`. Wichtige Reihen:155Jeder Runner stellt Prometheus-Metriken unter `GET /metrics` auf demselben Port wie `/healthz` bereit. Wichtige Serien:
156 156
157| Reihe | Notizen |157| Serie | Hinweise |
158| :- | :- |158| :- | :- |
159| `claude_code_self_hosted_runner_info{runner_id,version,client_label}` | Immer `1`; nützlich für Fleet-Inventar und Versions-Drift-Erkennung |159| `claude_code_self_hosted_runner_info{runner_id,version,client_label}` | Immer `1`; nützlich für die Inventarisierung der Flotte und die Erkennung von Versionsabweichungen |
160| `claude_code_self_hosted_runner_capacity` | Konfiguriert `--capacity` |160| `claude_code_self_hosted_runner_capacity` | Konfigurierter Wert von `--capacity` |
161| `claude_code_self_hosted_runner_active_sessions` | Sitzungen, die derzeit laufen |161| `claude_code_self_hosted_runner_active_sessions` | Aktuell laufende Sitzungen |
162| `claude_code_self_hosted_runner_locked_account{email}` | Vorhanden, sobald sich der Runner auf einen Benutzer gesperrt hat und ein Session-Token mit einem `act.email` Anspruch ausgestellt wurde. Die Reihe fehlt auf einem Runner, der auf einen Claude Tag-Agent gesperrt ist, dessen Session-Tokens keinen `act.email` Anspruch tragen. Der Labelwert ist die Konto-E-Mail; wenn Ihr Metrik-Store weit lesbar ist, löschen oder hashen Sie das Label zum Scrape-Zeitpunkt, zum Beispiel mit Prometheus `metric_relabel_configs`. |162| `claude_code_self_hosted_runner_locked_account{email}` | Vorhanden, sobald der Runner an einen Benutzer gebunden wurde und ein Sitzungs-Token mit einem `act.email`-Claim ausgestellt wurde. Auf einem Runner, der an einen Claude Tag-Agenten gebunden ist, fehlt die Serie, da dessen Sitzungs-Token kein `act.email` enthalten. Der Labelwert ist die E-Mail-Adresse des Kontos; wenn Ihr Metrikspeicher allgemein lesbar ist, verwerfen oder hashen Sie das Label beim Scrapen, zum Beispiel mit Prometheus `metric_relabel_configs`. |
163| `claude_code_self_hosted_runner_last_poll_age_seconds` | Sekunden seit der letzten erfolgreichen Abfrage. Warnung, wenn über 60. |163| `claude_code_self_hosted_runner_last_poll_age_seconds` | Sekunden seit dem letzten erfolgreichen Poll. Alarmieren Sie bei einem Wert über 60. |
164| `claude_code_self_hosted_runner_poll_errors_total{error_kind}` | Kumulative PollWork-Fehler nach Art: `transport`, `timeout`, `5xx`, `429` oder `4xx`. Alle fünf Reihen sind vom Prozessstart vorhanden; Warnung bei `rate(...[5m]) > 0`. |164| `claude_code_self_hosted_runner_poll_errors_total{error_kind}` | Kumulierte PollWork-Fehler nach Art: `transport`, `timeout`, `5xx`, `429` oder `4xx`. Alle fünf Serien sind ab Prozessstart vorhanden; alarmieren Sie bei `rate(...[5m]) > 0`. |
165| `claude_code_self_hosted_runner_sessions_started_total{client_platform}` | Session-Kindprozesse, die über die Lebensdauer des Runners erzeugt wurden, eine Reihe pro Session-Ursprung wie `web_claude_ai`, `ios`, `android`, `desktop_app` oder `claude_code_cli`, oder `unknown`, wenn der Server einen nicht gesendet hat. Slack-Sitzungen tragen entweder `claude_in_slack` oder `claude-in-slack`, je nachdem, welche Slack-Integration sie erstellt hat, also passen Sie beide mit einem Regex-Selektor wie `{client_platform=~"claude[-_]in[-_]slack"}` an. Verwenden Sie `sum()` für die Fleet-Summe. |165| `claude_code_self_hosted_runner_sessions_started_total{client_platform}` | Über die Lebensdauer des Runners gestartete Kindprozesse von Sitzungen, eine Serie pro Sitzungsursprung wie `web_claude_ai`, `ios`, `android`, `desktop_app` oder `claude_code_cli`, oder `unknown`, wenn der Server keinen Ursprung gesendet hat. Slack-Sitzungen tragen je nach der Slack-Integration, die sie erstellt hat, entweder `claude_in_slack` oder `claude-in-slack`; erfassen Sie daher beide mit einem Regex-Selektor wie `{client_platform=~"claude[-_]in[-_]slack"}`. Verwenden Sie `sum()` für die Gesamtsumme der Flotte. |
166| `claude_code_self_hosted_runner_sessions_completed_total{client_platform}` | Sitzungen, die sauber endeten, mit denselben Labels. Breiter als ein einfacher sauberer Ausstieg: siehe [Session-Lebenszyklus-Zähler-Semantik](#session-lifecycle-counter-semantics) für das, was zählt. |166| `claude_code_self_hosted_runner_sessions_completed_total{client_platform}` | Sitzungen, die sauber beendet wurden, gleich gelabelt. Weiter gefasst als ein einfacher sauberer Exit: Was hier zählt, finden Sie unter [Semantik der Zähler für den Sitzungslebenszyklus](#session-lifecycle-counter-semantics). |
167| `claude_code_self_hosted_runner_sessions_failed_total{client_platform}` | Sitzungen, die in Fehler endeten, mit denselben Labels. Gleicher Vorbehalt: siehe [Session-Lebenszyklus-Zähler-Semantik](#session-lifecycle-counter-semantics). |167| `claude_code_self_hosted_runner_sessions_failed_total{client_platform}` | Sitzungen, die mit einem Fehler endeten, gleich gelabelt. Gleicher Vorbehalt: siehe [Semantik der Zähler für den Sitzungslebenszyklus](#session-lifecycle-counter-semantics). |
168| `claude_code_self_hosted_runner_sessions_interrupted_total{client_platform}` | Sitzungen, die der Runner aus operativen Gründen beendete, anstatt aus einem Session-Ergebnis oder Runner-Fehler, mit denselben Labels. Siehe [Session-Lebenszyklus-Zähler-Semantik](#session-lifecycle-counter-semantics). |168| `claude_code_self_hosted_runner_sessions_interrupted_total{client_platform}` | Sitzungen, die der Runner aus einem betrieblichen Grund statt wegen eines Sitzungsergebnisses beendet hat, gleich gelabelt. Siehe [Semantik der Zähler für den Sitzungslebenszyklus](#session-lifecycle-counter-semantics). |
169| `claude_code_self_hosted_runner_initializing_sessions` | Sitzungen, die sich derzeit in der Init-Phase befinden, von der Zuweisung bis zum Init-Ereignis des Kindes |169| `claude_code_self_hosted_runner_initializing_sessions` | Sitzungen, die sich aktuell in der Init-Phase befinden, von der Zuweisung bis zum Init-Ereignis des Kindprozesses |
170| `claude_code_self_hosted_runner_session_init_duration_seconds` | Histogramm der Session-Init-Dauern |170| `claude_code_self_hosted_runner_session_init_duration_seconds` | Histogramm der Init-Dauern von Sitzungen |
171| `claude_code_self_hosted_runner_session_init_errors_total` | Sitzungen, die vor Erreichen von Init fehlschlugen: ein Checkout-Hook-Fehler, Git-Vorbereitung, Token-Problem oder ein Pre-Init-Kind-Crash |171| `claude_code_self_hosted_runner_session_init_errors_total` | Sitzungen, die vor Erreichen von Init fehlgeschlagen sind: ein Fehler im Checkout-Hook, bei der Git-Vorbereitung, ein Token-Problem oder ein Absturz des Kindprozesses vor Init |
172| `claude_code_self_hosted_runner_session_start_hook_errors_total` | `SessionStart` Hooks, die ein Fehler-Ergebnis meldeten, einer pro fehlgeschlagener Hook-Ausführung |172| `claude_code_self_hosted_runner_session_start_hook_errors_total` | `SessionStart`-Hooks, die ein Fehlerergebnis gemeldet haben, einer pro fehlgeschlagener Hook-Ausführung |
173| `claude_code_self_hosted_runner_session_idle_seconds{session_id,client_platform}` | Pro-Session-Gauge von Sekunden, seit die Sitzung untätig wurde. Nützlich zum Beenden von Sitzungen, die auf einer unbeantworteten Berechtigungsaufforderung stecken. |173| `claude_code_self_hosted_runner_session_idle_seconds{session_id,client_platform}` | Gauge pro Sitzung mit den Sekunden, seit die Sitzung inaktiv wurde. Nützlich, um Sitzungen zu beenden, die an einer unbeantworteten Berechtigungsabfrage hängen. |
174 174
175Der Orchestrator bedient seine eigenen Reihen bei `GET /metrics` auf demselben Port wie sein `/healthz`:175Der Orchestrator stellt seine eigenen Serien unter `GET /metrics` auf demselben Port wie sein `/healthz` bereit:
176 176
177| Reihe | Notizen |177| Serie | Hinweise |
178| :- | :- |178| :- | :- |
179| `claude_code_self_hosted_orchestrator_info{version,pool_id,orchestrator_uuid,hostname}` | Immer `1` |179| `claude_code_self_hosted_orchestrator_info{version,pool_id,orchestrator_uuid,hostname}` | Immer `1` |
180| `claude_code_self_hosted_orchestrator_connected` | `1`, wenn die letzte Abfrage erfolgreich war; fällt auf `0` nach jeder fehlgeschlagenen Abfrage, unabhängig von der Fehlerart |180| `claude_code_self_hosted_orchestrator_connected` | `1`, wenn der letzte Poll erfolgreich war; fällt nach jedem fehlgeschlagenen Poll auf `0`, unabhängig von der Art des Fehlers |
181| `claude_code_self_hosted_orchestrator_last_poll_age_seconds` | Sekunden seit dem letzten Abfrageversuch, Erfolg oder Fehler, anders als die identisch benannte Metrik des Runners, die seit dem letzten Erfolg misst; koppeln Sie mit `connected`, um fehlgeschlagene Abfragen zu erfassen. Die Abfrageschleife des Orchestrators wartet auf Hook-Ausführung, also Warnung über `--hook-timeout` plus eine Marge, etwa 90 Sekunden bei Standardwerten, anstatt einer flachen 60. |181| `claude_code_self_hosted_orchestrator_last_poll_age_seconds` | Sekunden seit dem letzten Poll-Versuch, ob erfolgreich oder fehlgeschlagen – anders als die gleichnamige Metrik des Runners, die ab dem letzten Erfolg misst; kombinieren Sie sie mit `connected`, um fehlschlagende Polls zu erkennen. Die Poll-Schleife des Orchestrators wartet auf die Hook-Ausführung; alarmieren Sie daher oberhalb von `--hook-timeout` plus einer Marge, bei Standardwerten etwa 90 Sekunden, statt pauschal bei 60. |
182| `claude_code_self_hosted_orchestrator_poll_errors_total{error_kind}` | Kumulative PollSpawnHints-Fehler nach Art: `transport`, `timeout`, `5xx`, `429` oder `4xx`. Alle fünf Reihen sind vom Prozessstart vorhanden; Warnung bei `rate(...[5m]) > 0`. |182| `claude_code_self_hosted_orchestrator_poll_errors_total{error_kind}` | Kumulierte PollSpawnHints-Fehler nach Art: `transport`, `timeout`, `5xx`, `429` oder `4xx`. Alle fünf Serien sind ab Prozessstart vorhanden; alarmieren Sie bei `rate(...[5m]) > 0`. |
183| `claude_code_self_hosted_orchestrator_queue_pending_sessions` | Spawn-Anfragen, die jetzt beanspruchbar sind |183| `claude_code_self_hosted_orchestrator_queue_pending_sessions` | Spawn-Anfragen, die aktuell übernommen werden können |
184| `claude_code_self_hosted_orchestrator_queue_backing_off_sessions` | Spawn-Anfragen in Retry-Backoff nach einem wiederholbaren Hook-Fehler |184| `claude_code_self_hosted_orchestrator_queue_backing_off_sessions` | Spawn-Anfragen im Backoff für Wiederholungsversuche nach einem wiederholbaren Hook-Fehler |
185| `claude_code_self_hosted_orchestrator_queue_circuit_broken_sessions` | Sitzungen, deren Erzeugung blockiert ist. Jede bleibt blockiert, bis ein Benutzer ihr eine neue Nachricht sendet oder ein Owner sie über die Registerkarte **Aktivität** der Umgebung erneut versucht. Der Wert kann über Null bleiben, nachdem Sie die Ursache behoben haben. Warnung, wenn über Null. |185| `claude_code_self_hosted_orchestrator_queue_circuit_broken_sessions` | Sitzungen, deren Start blockiert ist. Jede bleibt blockiert, bis ein Benutzer ihr eine neue Nachricht sendet oder ein Owner sie über den Tab **Activity** der Umgebung erneut versucht. Der Wert kann über null bleiben, nachdem Sie die Ursache behoben haben. Alarmieren Sie bei einem Wert über null. |
186| `claude_code_self_hosted_orchestrator_pool_pending_sessions` | Gesamtsitzungen, die auf einen Runner für diese Umgebung warten. Umgebungsweites Aggregat, identisch auf jeder Orchestrator-Instanz: Verwenden Sie `MAX` statt `SUM` über Instanzen. |186| `claude_code_self_hosted_orchestrator_pool_pending_sessions` | Gesamtzahl der Sitzungen, die in dieser Umgebung auf einen Runner warten. Umgebungsweites Aggregat, identisch auf jeder Orchestrator-Instanz: Verwenden Sie über Instanzen hinweg `MAX` statt `SUM`. |
187| `claude_code_self_hosted_orchestrator_pool_active_sessions` | Sitzungen, die derzeit einem lebenden Runner in dieser Umgebung zugewiesen sind. Umgebungsweites Aggregat, identisch auf jeder Orchestrator-Instanz: Verwenden Sie `MAX` statt `SUM` über Instanzen. |187| `claude_code_self_hosted_orchestrator_pool_active_sessions` | Sitzungen, die aktuell einem aktiven Runner in dieser Umgebung zugewiesen sind. Umgebungsweites Aggregat, identisch auf jeder Orchestrator-Instanz: Verwenden Sie über Instanzen hinweg `MAX` statt `SUM`. |
188| `claude_code_self_hosted_orchestrator_spawn_hooks_total{result}` | Kumulative `spawn-runner` Hook-Ergebnisse: `ok`, `retryable`, `non_retryable`. Zählt Orchestrator-Hook-Aufrufe, nicht Session-Kinder, die die Runner erzeugen: nicht vergleichbar mit `sessions_started_total`, da Kapazität über eins, warme Pools und Runner, die erneut für dieselbe Sitzung erzeugt werden, die beiden divergieren. |188| `claude_code_self_hosted_orchestrator_spawn_hooks_total{result}` | Kumulierte Ergebnisse des `spawn-runner`-Hooks: `ok`, `retryable`, `non_retryable`. Zählt Hook-Aufrufe des Orchestrators, nicht die von den Runnern gestarteten Kindprozesse von Sitzungen: nicht vergleichbar mit `sessions_started_total`, da eine Kapazität über eins, Warm-Pools und für dieselbe Sitzung erneut gestartete Runner die beiden Werte auseinanderlaufen lassen. |
189| `claude_code_self_hosted_orchestrator_spawn_hook_duration_seconds` | Histogramm der Hook-Dauern |189| `claude_code_self_hosted_orchestrator_spawn_hook_duration_seconds` | Histogramm der Hook-Dauern |
190| `claude_code_self_hosted_orchestrator_warm_hints_dispatched_total` | Standby-Spawn-Anfragen, die seit Prozessstart versendet wurden |190| `claude_code_self_hosted_orchestrator_warm_hints_dispatched_total` | Seit Prozessstart versendete Standby-Spawn-Anfragen |
191| `claude_code_self_hosted_orchestrator_session_queue_wait_seconds` | Histogramm von Sekunden, die jede Sitzung in der Warteschlange wartete, bevor der Orchestrator sie zum Erzeugen beanspruchte, aufgezeichnet vom Queue-Wait-Zeitstempel, den die Kontrolleben mit jeder Spawn-Anfrage der Sitzung sendet. Verwenden Sie für p50/p99 Queue-Zeit-Warnungen. Vorwärm-Spawns werden nicht gesampelt. |191| `claude_code_self_hosted_orchestrator_session_queue_wait_seconds` | Histogramm der Sekunden, die jede Sitzung in der Warteschlange gewartet hat, bevor der Orchestrator sie zum Starten übernommen hat, erfasst anhand des Wartezeit-Zeitstempels, den die Steuerungsebene mit der Spawn-Anfrage jeder Sitzung sendet. Verwenden Sie es für Alarme auf p50/p99 der Wartezeit. Starts zum Vorwärmen werden nicht erfasst. |
192| `claude_code_self_hosted_orchestrator_clock_skew_seconds` | Lokale-minus-Server-Uhr-Skew; diagnostisch, vorhanden, sobald gemessen |192| `claude_code_self_hosted_orchestrator_clock_skew_seconds` | Uhrenabweichung lokal minus Server; diagnostisch, vorhanden, sobald gemessen |
193| `claude_code_self_hosted_orchestrator_scm_connector_connected` | `1`, wenn der [SCM-Connector](#scm-connector-flags) WebSocket offen ist; `0` während Wählen oder Backoff. Fehlt, wenn `--scm-connector-host` nicht gesetzt ist. |193| `claude_code_self_hosted_orchestrator_scm_connector_connected` | `1`, wenn der WebSocket des [SCM-Konnektors](#scm-connector-flags) geöffnet ist; `0` während des Verbindungsaufbaus oder im Backoff. Fehlt, wenn `--scm-connector-host` nicht gesetzt ist. |
194| `claude_code_self_hosted_orchestrator_scm_connector_requests_forwarded_total` | Kumulative HTTP-Anfragen, die seit Prozessstart zum konfigurierten SCM-Host weitergeleitet wurden. Fehlt, wenn `--scm-connector-host` nicht gesetzt ist. |194| `claude_code_self_hosted_orchestrator_scm_connector_requests_forwarded_total` | Kumulierte HTTP-Anfragen, die seit Prozessstart an den konfigurierten SCM-Host weitergeleitet wurden. Fehlt, wenn `--scm-connector-host` nicht gesetzt ist. |
195 195
196Für Autoscaling wählen Sie die Reihe, die zu Ihrem Skalierungsstil passt, und gaten Sie sie, bevor sie den Scaler speist:196Wählen Sie für das Autoscaling die Serie, die zu Ihrer Skalierungsart passt, und filtern Sie sie, bevor sie in den Scaler eingespeist wird:
197 197
198* **Queue-Tiefe-Skalierung**: Speisen Sie `claude_code_self_hosted_orchestrator_pool_pending_sessions` in Ihren HPA- oder KEDA-Scaler, nicht `queue_pending_sessions`.198* **Skalierung nach Warteschlangentiefe**: Speisen Sie `claude_code_self_hosted_orchestrator_pool_pending_sessions` in Ihren HPA- oder KEDA-Scaler ein, nicht `queue_pending_sessions`.
199* **Kapazitäts-Skalierung**: Skalieren Sie auf das Verhältnis der `active_sessions` des Runners zu `capacity`.199* **Skalierung nach Kapazität**: Skalieren Sie anhand des Verhältnisses von `active_sessions` zu `capacity` des Runners.
200* **Gate auf `connected`**: Filtern Sie die Abfrage mit `claude_code_self_hosted_orchestrator_connected == 1` pro Instanz, sodass der veraltete Wert eines getrennten Replikas nicht den Scaler speist.200* **Filtern nach `connected`**: Filtern Sie die Abfrage pro Instanz mit `claude_code_self_hosted_orchestrator_connected == 1`, damit der veraltete Wert eines getrennten Replikats nicht in den Scaler gelangt.
201 201
202Während eines vollständigen Abfrageausfalls, jedes Replikat getrennt, gibt die gated-Abfrage keine Daten zurück. HPA hält die aktuelle Replikaanzahl bei einer fehlenden Metrik, aber KADAs Prometheus-Scaler bei seinem Standard `ignoreNullValues: "true"` liest das leere Ergebnis als Null und skaliert ein; setzen Sie `ignoreNullValues: "false"` auf dem ScaledObject, optional mit einem `fallback` Replikafloor.202Bei einem vollständigen Poll-Ausfall, bei dem alle Replikate getrennt sind, liefert die gefilterte Abfrage keine Daten. HPA behält bei einer fehlenden Metrik die aktuelle Replikatanzahl bei, der Prometheus-Scaler von KEDA liest das leere Ergebnis bei seinem Standardwert `ignoreNullValues: "true"` jedoch als null und skaliert herunter; setzen Sie `ignoreNullValues: "false"` im ScaledObject, optional mit einer `fallback`-Untergrenze für Replikate.
203 203
204Der folgende Prometheus Operator `PodMonitor` deckt beide Prozesse ab. Er wählt Pods nach dem Label `app.kubernetes.io/part-of: claude-code-self-hosted-runner` und dem benannten Port `health`, den das [Kubernetes-Rezept](https://code.claude.com/docs/de/self-hosted-environments-deploy.md#kubernetes) setzt; passen Sie die Namespaces an Ihre Bereitstellung an:204Der folgende `PodMonitor` für den Prometheus Operator deckt beide Prozesse ab. Er wählt Pods anhand des Labels `app.kubernetes.io/part-of: claude-code-self-hosted-runner` und des benannten Ports `health` aus, die das [Kubernetes-Rezept](https://code.claude.com/docs/de/self-hosted-environments-deploy.md#kubernetes) festlegt; passen Sie die Namespaces an Ihr Deployment an:
205 205
206```yaml theme={null}206```yaml theme={null}
207# Beispiel Prometheus Operator PodMonitor für den Claude Code Self-Hosted207# Example Prometheus Operator PodMonitor for the Claude Code self-hosted
208# Runner + Orchestrator. Passen Sie die Namespace- und Label-Selektoren an Ihre208# runner + orchestrator. Adjust the namespace and label selectors to match
209# Bereitstellung an. Sowohl der Runner als auch der Orchestrator bedienen /metrics auf209# your deployment. Both the runner and the orchestrator serve /metrics on
210# ihrem --health-port (Standard 8080).210# their --health-port (default 8080).
211apiVersion: monitoring.coreos.com/v1211apiVersion: monitoring.coreos.com/v1
212kind: PodMonitor212kind: PodMonitor
213metadata:213metadata:
219 - claude-runners219 - claude-runners
220 selector:220 selector:
221 matchExpressions:221 matchExpressions:
222 # Passt die Runner-Bereitstellung aus dem Kubernetes-Rezept sowie alle222 # Matches the runner Deployment from the Kubernetes recipe, plus any
223 # On-Demand-Runner-Jobs und Orchestrator-Pods an, die Sie gleich beschriften223 # on-demand runner Jobs and orchestrator pods you label the same way
224 # und einen benannten 'health' containerPort geben.224 # and give a named 'health' containerPort.
225 - key: app.kubernetes.io/part-of225 - key: app.kubernetes.io/part-of
226 operator: In226 operator: In
227 values: [claude-code-self-hosted-runner]227 values: [claude-code-self-hosted-runner]
231 interval: 30s231 interval: 30s
232```232```
233 233
234Diese Beispiel-Warnregeln sind ein Ausgangspunkt; stimmen Sie die Schwellwerte für Ihre Fleet-Größe ab:234### Beispiel-Alarmregeln
235
236Diese Beispiel-Alarmregeln sind ein Ausgangspunkt; passen Sie die Schwellenwerte an die Größe Ihrer Flotte an:
235 237
236```yaml theme={null}238```yaml theme={null}
237# Beispiel Prometheus-Warnregeln für den Claude Code Self-Hosted Runner239# Example Prometheus alert rules for the Claude Code self-hosted runner
238# + Orchestrator. Stimmen Sie die Schwellwerte für Ihre Fleet-Größe und SLOs ab.240# + orchestrator. Tune thresholds for your fleet size and SLOs.
239groups:241groups:
240 - name: claude-code-self-hosted-runner242 - name: claude-code-self-hosted-runner
241 rules:243 rules:
244 for: 2m246 for: 2m
245 labels: {severity: warning}247 labels: {severity: warning}
246 annotations:248 annotations:
247 summary: "Runner {{ $labels.pod }} hat nicht in >60s abgefragt"249 summary: "Runner {{ $labels.pod }} has not polled in >60s"
248 - alert: ClaudeRunnerVersionDrift250 - alert: ClaudeRunnerVersionDrift
249 expr: count(count by (version) (claude_code_self_hosted_runner_info)) > 1251 expr: count(count by (version) (claude_code_self_hosted_runner_info)) > 1
250 for: 30m252 for: 30m
251 labels: {severity: info}253 labels: {severity: info}
252 annotations:254 annotations:
253 summary: "Runner führen gemischte Versionen aus"255 summary: "Runners are running mixed versions"
254 - alert: ClaudeRunnerInitErrorsHigh256 - alert: ClaudeRunnerInitErrorsHigh
255 expr: increase(claude_code_self_hosted_runner_session_init_errors_total[10m]) > 3257 expr: sum by (namespace) (increase(claude_code_self_hosted_runner_session_init_errors_total[10m])) > 3
256 for: 5m258 for: 5m
257 labels: {severity: warning}259 labels: {severity: warning}
258 annotations:260 annotations:
259 summary: "Runner {{ $labels.pod }}: >3 Session-Init-Fehler in 10m (Checkout-Hook / Git / Token / Pre-Init-Kind-Crash)"261 summary: "Sessions are failing before init (checkout hook / git / token / pre-init crash)"
260 - alert: ClaudeRunnerPollErrors262 - alert: ClaudeRunnerPollErrors
261 expr: sum by (pod) (rate(claude_code_self_hosted_runner_poll_errors_total[5m])) > 0263 expr: sum by (pod) (rate(claude_code_self_hosted_runner_poll_errors_total[5m])) > 0
262 for: 2m264 for: 2m
263 labels: {severity: warning}265 labels: {severity: warning}
264 annotations:266 annotations:
265 summary: "Runner {{ $labels.pod }}: PollWork fehlgeschlagen ({{ $value | humanize }}/s über 5m)"267 summary: "Runner {{ $labels.pod }}: PollWork failing ({{ $value | humanize }}/s over 5m)"
266 - alert: ClaudeRunnerSessionStartHookErrors268 - alert: ClaudeRunnerSessionStartHookErrors
267 expr: increase(claude_code_self_hosted_runner_session_start_hook_errors_total[10m]) > 3269 expr: sum by (namespace) (increase(claude_code_self_hosted_runner_session_start_hook_errors_total[10m])) > 3
268 for: 5m270 for: 5m
269 labels: {severity: warning}271 labels: {severity: warning}
270 annotations:272 annotations:
271 summary: "Runner {{ $labels.pod }}: >3 SessionStart-Hook-Fehler in 10m"273 summary: "SessionStart hooks are failing"
272 274
273 - name: claude-code-self-hosted-orchestrator275 - name: claude-code-self-hosted-orchestrator
274 rules:276 rules:
277 for: 2m279 for: 2m
278 labels: {severity: critical}280 labels: {severity: critical}
279 annotations:281 annotations:
280 summary: "Orchestrator {{ $labels.pod }} kann die Anthropic-Kontrollebene nicht erreichen"282 summary: "Orchestrator {{ $labels.pod }} cannot reach the Anthropic control plane"
281 - alert: ClaudeOrchestratorPollStale283 - alert: ClaudeOrchestratorPollStale
282 expr: claude_code_self_hosted_orchestrator_last_poll_age_seconds > 90284 expr: claude_code_self_hosted_orchestrator_last_poll_age_seconds > 90
283 for: 2m285 for: 2m
284 labels: {severity: warning}286 labels: {severity: warning}
285 annotations:287 annotations:
286 summary: "Orchestrator {{ $labels.pod }} hat nicht in >90s abgefragt (Abfrageschleife wartet auf Hook-Ausführung)"288 summary: "Orchestrator {{ $labels.pod }} has not polled in >90s (poll loop waits on hook execution)"
287 - alert: ClaudeOrchestratorCircuitBroken289 - alert: ClaudeOrchestratorCircuitBroken
288 expr: claude_code_self_hosted_orchestrator_queue_circuit_broken_sessions > 0290 expr: max by (namespace) (claude_code_self_hosted_orchestrator_queue_circuit_broken_sessions and on (instance) max_over_time(claude_code_self_hosted_orchestrator_connected[2m]) == 1) > 0
289 for: 1m291 for: 1m
290 labels: {severity: critical}292 labels: {severity: critical}
291 annotations:293 annotations:
292 summary: "Sitzungen mit blockierter Erzeugung: {{ $value }}. Lesen Sie den Fehler jeder Sitzung auf der Registerkarte Aktivität, beheben Sie die Ursache und wählen Sie dann Retry"294 summary: "Sessions blocked from spawning: {{ $value }}. Read each one's error in the Activity tab, fix the cause, then select Retry"
293 - alert: ClaudeOrchestratorPollErrors295 - alert: ClaudeOrchestratorPollErrors
294 expr: sum by (pod) (rate(claude_code_self_hosted_orchestrator_poll_errors_total[5m])) > 0296 expr: sum by (pod) (rate(claude_code_self_hosted_orchestrator_poll_errors_total[5m])) > 0
295 for: 2m297 for: 2m
296 labels: {severity: warning}298 labels: {severity: warning}
297 annotations:299 annotations:
298 summary: "Orchestrator {{ $labels.pod }}: PollSpawnHints fehlgeschlagen ({{ $value | humanize }}/s über 5m)"300 summary: "Orchestrator {{ $labels.pod }}: PollSpawnHints failing ({{ $value | humanize }}/s over 5m)"
299 - alert: ClaudeOrchestratorSpawnHookFailing301 - alert: ClaudeOrchestratorSpawnHookFailing
300 expr: sum by (pod) (increase(claude_code_self_hosted_orchestrator_spawn_hooks_total{result!="ok"}[5m])) > 3302 expr: sum by (pod) (increase(claude_code_self_hosted_orchestrator_spawn_hooks_total{result!="ok"}[5m])) > 3
301 for: 5m303 for: 5m
302 labels: {severity: warning}304 labels: {severity: warning}
303 annotations:305 annotations:
304 summary: "Orchestrator {{ $labels.pod }}: >3 spawn-runner Hook-Fehler in 5m"306 summary: "Orchestrator {{ $labels.pod }}: >3 spawn-runner hook failures in 5m"
305```307```
306 308
307### Durchlauf-Session-Kind-Metriken309### Bei verlorenen Runnern und wartenden Sitzungen alarmieren
310
311Laden Sie bei einer [festen Flotte](https://code.claude.com/docs/de/self-hosted-environments-deploy.md#scale-the-fleet) `ClaudeRunnersBelowFloor`. Laden Sie bei [On-Demand-Runnern](https://code.claude.com/docs/de/self-hosted-environments-configuration.md#on-demand-runners) stattdessen `ClaudeOrchestratorSessionsWaiting` und `ClaudeOrchestratorQueueWaitHigh`.
312
313#### Alarmieren, wenn eine feste Flotte Runner verliert
314
315`ClaudeRunnersBelowFloor` wird ausgelöst, wenn 10 Minuten lang weniger registrierte und gescrapte Runner als die Untergrenze übrig sind:
316
317```yaml theme={null}
318groups:
319 # Fixed fleets only. With on-demand runners the count follows demand,
320 # so ClaudeRunnersBelowFloor would fire whenever demand is low.
321 - name: claude-code-self-hosted-fixed-fleet-capacity
322 rules:
323 - alert: ClaudeRunnersBelowFloor
324 expr: (count(claude_code_self_hosted_runner_info{namespace="claude-runners"}) or vector(0)) < 2
325 for: 10m
326 labels: {severity: critical, namespace: claude-runners}
327 annotations:
328 summary: "Runners registered and scraped: {{ $value }}, below the floor. Check the runner workloads first, then the scrape targets if all are running."
329```
330
331* **Untergrenze**: Setzen Sie die `2` in `expr` auf etwa die Hälfte Ihrer Replikatanzahl, aufgerundet. Behalten Sie bei drei Replikaten `2` bei; der Alarm wird dann ausgelöst, wenn nur noch ein Runner oder keiner übrig ist.
332* **Namespace**: Ersetzen Sie `claude-runners` im Matcher und in `labels`, und kopieren Sie den Alarm für jeden weiteren Namespace. Wenn Ihre Ziele kein `namespace`-Label haben, entfernen Sie den Matcher und das Label, da der Alarm sonst 0 liest und ausgelöst wird.
333* **`ClaudeRunnerPollStale` und `ClaudeRunnerPollErrors`**: Lassen Sie diese aus den [Beispiel-Alarmregeln](#sample-alert-rules) geladen, da `ClaudeRunnersBelowFloor` einen Runner, der nicht pollen kann, weiterhin mitzählt
334
335#### Alarmieren, wenn Sitzungen auf On-Demand-Runner warten
336
337`ClaudeOrchestratorSessionsWaiting` wird ausgelöst, wenn die Anzahl der Sitzungen, die auf einen Runner warten, 10 Minuten lang über 0 bleibt. `ClaudeOrchestratorQueueWaitHigh` wird ausgelöst, wenn mehr als 1 % der Wartezeiten in der Warteschlange in den letzten 10 Minuten 160 Sekunden überschritten haben und dies 5 Minuten lang anhält:
338
339```yaml theme={null}
340groups:
341 # On-demand runners only. Needs no edit for the namespace.
342 - name: claude-code-self-hosted-on-demand-capacity
343 rules:
344 - alert: ClaudeOrchestratorSessionsWaiting
345 expr: |
346 max by (namespace) (
347 claude_code_self_hosted_orchestrator_pool_pending_sessions
348 and on (instance)
349 max_over_time(claude_code_self_hosted_orchestrator_connected[2m]) == 1
350 ) > 0
351 for: 10m
352 labels: {severity: warning}
353 annotations:
354 summary: "Sessions waiting for a runner: {{ $value }}, above the threshold for 10 minutes. Check claude_code_self_hosted_orchestrator_spawn_hooks_total by result, then runner workloads that don't start."
355 - alert: ClaudeOrchestratorQueueWaitHigh
356 expr: |
357 histogram_quantile(0.99, sum by (namespace, le) (
358 rate(claude_code_self_hosted_orchestrator_session_queue_wait_seconds_bucket[10m])
359 )) > 160
360 for: 5m
361 labels: {severity: warning}
362 annotations:
363 summary: "Over 1% of queue waits in the last 10 minutes exceeded 160 seconds. Check whether ClaudeOrchestratorDisconnected is firing, then claude_code_self_hosted_orchestrator_spawn_hooks_total by result and claude_code_self_hosted_orchestrator_spawn_hook_duration_seconds."
364```
365
366* **Schwellenwert**: Wenn ständig irgendeine Sitzung wartet, erhöhen Sie das `> 0` in `ClaudeOrchestratorSessionsWaiting` über die Anzahl, die Sie üblicherweise sehen
367* **`ClaudeOrchestratorDisconnected`**: Lassen Sie diesen Alarm aus den [Beispiel-Alarmregeln](#sample-alert-rules) geladen, da `ClaudeOrchestratorSessionsWaiting` etwa 2 Minuten, nachdem der letzte Orchestrator im Namespace die Verbindung verloren hat, nicht mehr ausgelöst wird
368
369### Metriken der Sitzungs-Kindprozesse durchreichen
308 370
309Jede Sitzung läuft in ihrem eigenen Kind-Prozess mit ihren eigenen OpenTelemetry-Metriken; bei `--capacity` über eins schreibt der Runner um, wie diese Kind-Metriken verfügbar gemacht werden. Das Setzen von `OTEL_METRICS_EXPORTER=prometheus` auf dem Runner-Host und `CLAUDE_CODE_ENABLE_TELEMETRY=1` in der Umgebung der Sitzung, zum Beispiel aus Ihrem [Wrapper-Skript](https://code.claude.com/docs/de/self-hosted-environments-configuration.md#wrapper-scripts) oder der Umgebung des Runners selbst, die Sitzungen erben, macht die Zähler- und Gauge-Instrumente jedes Kindes auf dem `/metrics` Endpunkt des Runners erneut verfügbar, neben den Reihen des Runners. Der Runner schreibt den Exporter des Kindes um, um über OTLP zu einem Loopback-only-Receiver auf dem Health-Port zu pushen, markiert jede Reihe mit `session_id`- und `client_platform`-Labels und entfernt die Reihen einer Sitzung, wenn diese Sitzung endet. Histogramme gehen nicht durch, und eine Kind-Metrik, deren Name mit dem eigenen Präfix des Runners kollidieren würde, wird gelöscht.371Jede Sitzung läuft in ihrem eigenen Kindprozess mit eigenen OpenTelemetry-Metriken; bei einem `--capacity`-Wert über eins schreibt der Runner um, wie diese Metriken der Kindprozesse bereitgestellt werden. Wenn Sie `OTEL_METRICS_EXPORTER=prometheus` auf dem Runner-Host und `CLAUDE_CODE_ENABLE_TELEMETRY=1` in der Umgebung der Sitzung setzen, zum Beispiel über Ihr [Wrapper-Skript](https://code.claude.com/docs/de/self-hosted-environments-configuration.md#wrapper-scripts) oder die eigene Umgebung des Runners, die Sitzungen erben, werden die Counter- und Gauge-Instrumente jedes Kindprozesses zusätzlich auf dem eigenen `/metrics`-Endpunkt des Runners neben den Serien des Runners bereitgestellt. Der Runner schreibt den Exporter des Kindprozesses so um, dass er per OTLP an einen nur über Loopback erreichbaren Empfänger auf dem Health-Port sendet, versieht jede Serie mit den Labels `session_id` und `client_platform` und entfernt die Serien einer Sitzung, wenn diese Sitzung endet. Histogramme werden nicht durchgereicht, und eine Metrik des Kindprozesses, deren Name mit dem eigenen Präfix des Runners kollidieren würde, wird verworfen.
310 372
311Bei der Standard `--capacity 1` gilt die Umschreibung nicht: Das Kind des Kindes bindet seinen eigenen Prometheus-Endpunkt auf Port 9464 wie üblich.373Beim Standardwert `--capacity 1` greift diese Umschreibung nicht: Der Kindprozess der Sitzung bindet wie gewohnt seinen eigenen Prometheus-Endpunkt an Port 9464.
312 374
313#### Metriken einer Sitzung mit denen des Runners verknüpfen375#### Metriken einer Sitzung mit denen des Runners verknüpfen
314 376
315Um die eigenen Metriken einer Sitzung neben `claude_code_self_hosted_runner_session_idle_seconds` zu stellen, verknüpfen Sie sie über die `session_id` des Runners:377Um die eigenen Metriken einer Sitzung neben `claude_code_self_hosted_runner_session_idle_seconds` zu stellen, verknüpfen Sie sie über die `session_id` des Runners:
316 378
317* **Bei `--capacity` über eins**: Verknüpfen Sie direkt. Auf dem `/metrics` des Runners tragen die Reihen der Sitzung dieselbe `session_id` wie diese Metrik, in der Form `session_...`.379* **Bei `--capacity` über eins**: Verknüpfen Sie direkt. Auf dem `/metrics` des Runners tragen die Serien der Sitzung dieselbe `session_id` wie diese Metrik, in der Form `session_...`.
318* **Bei `--capacity 1`**: Verknüpfen Sie über eine konvertierte `ccr_session_id`. Standardmäßig trägt jede Claude Code-Metrik auf Port 9464 dieses Label, das die Sitzungs-ID in der Form `cse_...` enthält. Ersetzen Sie in einem neuen Label das Präfix `cse_` durch `session_`, um die `session_id` des Runners zu erhalten. Die eigene `session_id` der Metrik enthält die eigene [`session.id`](https://code.claude.com/docs/de/monitoring-usage#standard-attributes) von Claude Code, die zu keiner Runner-Reihe passt.380* **Bei `--capacity 1`**: Verknüpfen Sie über eine umgewandelte `ccr_session_id`. Standardmäßig trägt jede Claude Code-Metrik auf Port 9464 dieses Label, das die Sitzungs-ID in der Form `cse_...` enthält. Ersetzen Sie in einem neuen Label das Präfix `cse_` durch `session_`, um die `session_id` des Runners zu erhalten. Die eigene `session_id` der Metrik enthält die eigene [`session.id`](https://code.claude.com/docs/de/monitoring-usage#standard-attributes) von Claude Code, die zu keiner Serie des Runners passt.
319 381
320### Session-Lebenszyklus-Zähler-Semantik382### Semantik der Zähler für den Sitzungslebenszyklus
321 383
322Die Zähler `sessions_started_total`, `sessions_completed_total`, `sessions_failed_total` und `sessions_interrupted_total` klassifizieren jede Sitzung danach, wie sie endete. Jedes erzeugte Session-Kind erhöht `sessions_started_total` zum Spawn-Zeitpunkt, und genau einer der anderen drei erhöht sich beim Beenden, sodass `sessions_started_total` minus die Summe der anderen drei der Anzahl der derzeit laufenden Session-Kinder entspricht.384Die Zähler `sessions_started_total`, `sessions_completed_total`, `sessions_failed_total` und `sessions_interrupted_total` klassifizieren jede Sitzung danach, wie sie beendet wurde. Jeder gestartete Kindprozess einer Sitzung erhöht `sessions_started_total` beim Start, und genau einer der anderen drei Zähler wird beim Beenden erhöht; `sessions_started_total` minus der Summe der anderen drei entspricht also der Anzahl der aktuell laufenden Kindprozesse von Sitzungen.
323 385
324* `completed`: Die Sitzung endete sauber. Dies deckt das Kind ab, das auf eigene Faust mit Code `0` beendet wird, die Sitzung wird archiviert oder gelöscht, während das Kind noch verbunden war, und der Runner gibt den Slot sauber zurück: Freigabe der Sitzung beim Idle-Timeout, zur Retire-Zeit oder am `--kill-session-after-min` Limit; ein Startup-Timeout; oder ein serverseitiges Deassign, das die Abfrageschleife bemerkte, bevor das Kind beendet wurde. Erhöht `sessions_completed_total`.386* `completed`: Die Sitzung wurde sauber beendet. Dazu gehört, dass der Kindprozess sich selbst mit Code `0` beendet, dass die Sitzung archiviert oder gelöscht wird, während der Kindprozess noch verbunden war, und dass der Runner den Slot sauber zurückgibt: durch Freigabe der Sitzung beim Inaktivitäts-Timeout, zum Ausmusterungszeitpunkt oder beim Limit `--kill-session-after-min`; durch einen Start-Timeout; oder durch eine serverseitige Aufhebung der Zuweisung, die die Poll-Schleife bemerkt hat, bevor der Kindprozess beendet wurde. Erhöht `sessions_completed_total`.
325* `failed`: Das Kind beendete sich auf eigene Faust mit einem Nicht-Null-Code, entweder ein Crash oder ein Setup-Fehler nach dem Erzeugen. Erhöht `sessions_failed_total`.387* `failed`: Der Kindprozess hat sich selbst mit einem Code ungleich null beendet, entweder durch einen Absturz oder einen Einrichtungsfehler nach dem Start. Erhöht `sessions_failed_total`.
326* `interrupted`: Der Runner beendete das Kind aus operativen Gründen, die weder ein Session-Erfolg noch ein Runner-Fehler sind, wie eine Entleerung oder die Beendigung einer Sitzung, die sich noch auf dem Runner befand, wenn das [`SELF_HOSTED_RUNNER_MAX_LIFETIME_GRACE_MS`](#environment-variable-only-settings) Kulanzfenster nach seinem `--kill-session-after-min` Limit endete. Ein Kubernetes-Rolling-Restart, der `SIGTERM` sendet, ist ein Beispiel für eine Entleerung. Erhöht `sessions_interrupted_total`.388* `interrupted`: Der Runner hat den Kindprozess aus einem betrieblichen Grund beendet, der weder ein Erfolg der Sitzung noch ein Fehler des Runners ist, etwa ein Drain oder das Beenden einer Sitzung, die sich noch auf dem Runner befand, als das Kulanzfenster [`SELF_HOSTED_RUNNER_MAX_LIFETIME_GRACE_MS`](#environment-variable-only-settings) nach ihrem Limit `--kill-session-after-min` endete. Ein rollierender Kubernetes-Neustart, der `SIGTERM` sendet, ist ein Beispiel für einen Drain. Erhöht `sessions_interrupted_total`.
327 389
328Vor v2.1.260 beendete der Runner jede Sitzung, die ihr `--kill-session-after-min` Limit erreichte, und zählte sie in `sessions_interrupted_total`.390Vor v2.1.260 beendete der Runner jede Sitzung, die ihr Limit `--kill-session-after-min` erreichte, und zählte sie in `sessions_interrupted_total`.
329 391
330Der [`post-session` Hook](https://code.claude.com/docs/de/self-hosted-environments-configuration#post-session) `CLAUDE_RUNNER_EXIT_REASON` klassifiziert saubere Übergaben unterschiedlich. Der Hook meldet diese als `interrupted`, da der Runner das Kind stoppte: eine Freigabe, ein Startup-Timeout, ein Server-Deassign sowie ein Archivieren oder Löschen, das die Abfrage zuerst bemerkte. Diese Zähler zeichnen die gleichen Ereignisse als `completed` auf, da der Slot sauber zurückgegeben wurde.392Die Variable `CLAUDE_RUNNER_EXIT_REASON` des [`post-session`-Hooks](https://code.claude.com/docs/de/self-hosted-environments-configuration#post-session) klassifiziert saubere Übergaben anders. Der Hook meldet diese als `interrupted`, weil der Runner den Kindprozess gestoppt hat: eine Freigabe, einen Start-Timeout, eine serverseitige Aufhebung der Zuweisung sowie ein Archivieren oder Löschen, das der Poll zuerst bemerkt hat. Diese Zähler erfassen dieselben Ereignisse als `completed`, weil der Slot sauber zurückgegeben wurde.
331 393
332Wenn Sie Hook-Quittungen direkt gegen `sessions_completed_total` abstimmen, unterzählen Sie Abschlüsse. Verwenden Sie den Hook für Pro-Session-Garantien und die Zähler für Aggregatraten.394Wenn Sie Hook-Empfangsbestätigungen direkt mit `sessions_completed_total` abgleichen, zählen Sie zu wenige abgeschlossene Sitzungen. Verwenden Sie den Hook für Garantien pro Sitzung und die Zähler für aggregierte Raten.
333 395
334In einer One-Shot-Umgebung, `--capacity 1` mit dem Standard `--drain-grace-sec 0`, beendet sich jeder Runner-Prozess Momente nach seiner einen Sitzung endet. `sessions_completed_total`, `sessions_failed_total` und `sessions_interrupted_total` erhöhen sich nur beim Session-Ende, direkt bevor dieser Ausstieg, sodass ein Prometheus-Scrape alle 15 bis 60 Sekunden die Erhöhung selten erfasst, bevor die Reihen des Runners verschwinden; diese drei End-of-Session-Zähler sind die Terminal-Zähler, auf die sich der Rest dieses Abschnitts bezieht. `sessions_started_total` erhöht sich beim Erzeugen und bleibt für die Lebensdauer der Sitzung sichtbar, sodass es zuverlässig angezeigt wird, aber in einer One-Shot-Umgebung liest es näher an "Sitzungen, die derzeit laufen" als an einer kumulativen Anzahl.396In einer One-Shot-Umgebung, also `--capacity 1` mit dem Standardwert `--drain-grace-sec 0`, wird jeder Runner-Prozess kurz nach dem Ende seiner einen Sitzung beendet. `sessions_completed_total`, `sessions_failed_total` und `sessions_interrupted_total` werden erst am Sitzungsende erhöht, unmittelbar vor diesem Beenden; ein Prometheus-Scrape alle 15 bis 60 Sekunden erfasst die Erhöhung daher selten, bevor die Serie des Runners verschwindet. Diese drei Zähler für das Sitzungsende sind die Endzähler, auf die sich der Rest dieses Abschnitts bezieht. `sessions_started_total` wird beim Start erhöht und bleibt während der gesamten Lebensdauer der Sitzung sichtbar, sodass er zuverlässig erscheint; in einer One-Shot-Umgebung entspricht er jedoch eher „aktuell laufenden Sitzungen“ als einer kumulierten Zählung.
335 397
336Verwenden Sie die Reihe in dieser Tabelle für das entsprechende Ziel statt der Terminal-Zähler:398Verwenden Sie für das jeweilige Ziel die Serien in dieser Tabelle statt der Endzähler:
337 399
338| Ziel | Verwenden |400| Ziel | Verwenden |
339| :- | :- |401| :- | :- |
340| Durchsatz | `claude_code_self_hosted_orchestrator_spawn_hooks_total{result="ok"}`, ein Zähler auf dem langlebigen Orchestrator, der sich einmal pro erfolgreichem `spawn-runner` Hook erhöht und unter `rate()` aussagekräftig bleibt. Er zählt Hook-Aufrufe statt Sitzungen, sodass Vorwärmung und wiederholte Spawns für dieselbe Sitzung ihn von Session-Zählungen divergieren. |402| Durchsatz | `claude_code_self_hosted_orchestrator_spawn_hooks_total{result="ok"}`, ein Zähler auf dem langlebigen Orchestrator, der pro erfolgreichem `spawn-runner`-Hook einmal erhöht wird und unter `rate()` aussagekräftig bleibt. Er zählt Hook-Aufrufe statt Sitzungen, sodass Vorwärmen und wiederholte Starts für dieselbe Sitzung ihn von den Sitzungszahlen abweichen lassen. |
341| Auslastung | `sum(claude_code_self_hosted_runner_active_sessions)` gegen `sum(claude_code_self_hosted_runner_capacity)`, beide Gauges gültig bei jedem Scrape unabhängig von der Runner-Lebensdauer |403| Auslastung | `sum(claude_code_self_hosted_runner_active_sessions)` im Verhältnis zu `sum(claude_code_self_hosted_runner_capacity)`, beides Gauges, die bei jedem Scrape unabhängig von der Lebensdauer des Runners gültig sind |
342| Rückstand | `claude_code_self_hosted_orchestrator_pool_pending_sessions` für Queue-Tiefe und `claude_code_self_hosted_orchestrator_queue_circuit_broken_sessions`, Warnung, wenn über Null |404| Rückstau | `claude_code_self_hosted_orchestrator_pool_pending_sessions` für die Warteschlangentiefe und `claude_code_self_hosted_orchestrator_queue_circuit_broken_sessions` mit einem Alarm bei einem Wert über null |
343| Fehler | `claude_code_self_hosted_runner_sessions_failed_total`, Best-Effort: echte Crashes nach dem Erzeugen erhöhen ihn, und `rate()` ist aussagekräftig auf Runnern, die ihre Sitzungen mit `--drain-grace-sec` über `0` überleben. Eine One-Shot-Umgebung hat das gleiche Scrape-Fenster-Problem wie die anderen Terminal-Zähler, also behandeln Sie jeden Nicht-Null-Wert, den Sie sehen, als wert, untersucht zu werden. Fehler vor dem Erzeugen, wie ein Checkout-Hook-Fehler, Git-Vorbereitung oder ein Token-Problem, erscheinen nur in `session_init_errors_total`. |405| Fehler | `claude_code_self_hosted_runner_sessions_failed_total`, nach bestem Bemühen: Echte Abstürze nach dem Start erhöhen ihn, und `rate()` ist auf Runnern aussagekräftig, die ihre Sitzungen mit einem `--drain-grace-sec`-Wert über `0` überdauern. Eine One-Shot-Umgebung hat dasselbe Problem mit dem Scrape-Fenster wie die anderen Endzähler; betrachten Sie daher jeden Wert ungleich null, den Sie sehen, als untersuchungswürdig. Fehler vor dem Start, etwa ein Fehler im Checkout-Hook, bei der Git-Vorbereitung oder ein Token-Problem, erscheinen nur in `session_init_errors_total`. |
344 406
345Die `orchestrator_*` Zeilen existieren nur auf Umgebungen, die den [On-Demand-Orchestrator](https://code.claude.com/docs/de/self-hosted-environments-configuration.md#on-demand-runners) ausführen. In einer festen Fleet, deren Runner ihre Sitzungen mit `--drain-grace-sec` über `0` überleben, verwenden Sie `sum(rate(claude_code_self_hosted_runner_sessions_started_total[5m]))` für Durchsatz; in einer One-Shot-Fleet hat diese Reihe das gleiche Scrape-Fenster-Problem wie die Terminal-Zähler, also verlassen Sie sich stattdessen auf die Zählung der Sitzungen in der Warteschlange. Überprüfen Sie den Rückstand auf der Registerkarte **Aktivität** der Umgebung, auf der [**Cloud-Umgebungen**-Administratorseite](https://claude.ai/admin-settings/cloud-environments): Die Runner exportieren keine Queue-Tiefe-Reihe.407Die `orchestrator_*`-Zeilen gibt es nur in Umgebungen, in denen der [On-Demand-Orchestrator](https://code.claude.com/docs/de/self-hosted-environments-configuration.md#on-demand-runners) läuft. Verwenden Sie bei einer festen Flotte, deren Runner ihre Sitzungen mit einem `--drain-grace-sec`-Wert über `0` überdauern, `sum(rate(claude_code_self_hosted_runner_sessions_started_total[5m]))` für den Durchsatz; bei einer One-Shot-Flotte hat diese Serie dasselbe Problem mit dem Scrape-Fenster wie die Endzähler, verlassen Sie sich daher stattdessen auf die Anzahl der wartenden Sitzungen. Prüfen Sie den Rückstau im Tab **Activity** der Umgebung auf der [Admin-Seite **Cloud environments**](https://claude.ai/admin-settings/cloud-environments): Die Runner exportieren keine Serie für die Warteschlangentiefe.
346 408
347Für Pro-Session-Ergebnis-Berichterstattung verwenden Sie stattdessen den [`post-session` Hook](https://code.claude.com/docs/de/self-hosted-environments-configuration#post-session): Er wird bei jedem Session-Ende ausgelöst, wo ein Kind-Prozess erzeugt wurde, abgesehen von abruptem Runner-Beendigung wie eine VM-Preemption, pro dem [eigenen Vertrag des Hooks](https://code.claude.com/docs/de/self-hosted-environments-configuration.md#post-session).409Verwenden Sie für die Berichterstattung über Ergebnisse pro Sitzung stattdessen den [`post-session`-Hook](https://code.claude.com/docs/de/self-hosted-environments-configuration#post-session): Er wird bei jedem Sitzungsende ausgelöst, bei dem ein Kindprozess gestartet wurde, abgesehen von einem abrupten Beenden des Runners wie einer VM-Preemption, gemäß dem [eigenen Vertrag des Hooks](https://code.claude.com/docs/de/self-hosted-environments-configuration.md#post-session).
348 410
349## Nächste Schritte411## Nächste Schritte
350 412