SpyBara
Go Premium

self-hosted-environments-reference.md 2026-09-11 23:01 UTC to 2026-09-12 03:02 UTC

This page contains 342 additions and 0 deletions.

2026
Sat 12 03:02 Fri 18 23:58 Sat 19 23:57

Справочник самостоятельно размещаемых окружений

Полный справочник по самостоятельно размещаемому runner и orchestrator: флаги CLI, переменные окружения и метрики Prometheus.

Эта страница является справочником для двух процессов, которые вы запускаете в самостоятельно размещаемом окружении: runner, который выполняет Claude Code cloud sessions на ваших хостах, и опциональный orchestrator автомасштабирования, который запускает runners по мере поступления sessions в очередь. Каждый имеет свою таблицу флагов. Оба работают на хостах Linux или macOS, для которых значения по умолчанию, такие как /workspace и ~/.claude, предполагаются. Запустите claude self-hosted-runner --help для авторитетного списка на вашей установленной версии.

Серии метрик и несколько полей API по-прежнему используют pool для того, что эти страницы называют окружением; оба термина обозначают одно и то же. ID окружения — это поле pool_id с формой ccpool_...: везде, где эти страницы показывают идентификатор pool, он обозначает окружение. Флаги CLI и переменные окружения пишут его как environment, например --environment-secret-file; устаревшие написания pool по-прежнему работают, как описывает строка --environment-secret-file.

Флаги CLI Runner

Большинство флагов имеют соответствующую переменную окружения. Когда установлены оба, флаг имеет приоритет. Флаги длительности принимают минуты или секунды в CLI, но связанная переменная окружения всегда в миллисекундах, обозначаемая суффиксом _MS, и столбец Default показывает единицу флага: --exit-if-unused-min 10 эквивалентно SELF_HOSTED_RUNNER_IDLE_SHUTDOWN_MS=600000, а значение Helm вроде SELF_HOSTED_RUNNER_STARTUP_TIMEOUT_MS: "15" означает 15 миллисекунд, а не 15-минутное значение по умолчанию.

Флаг Переменная окружения По умолчанию Описание
--api-url <url> none https://api.anthropic.com URL базы API. Переопределяйте только для тестирования.
--base-dir <path> SELF_HOSTED_RUNNER_BASE_DIR /workspace; none на Windows Каталог для проверок репозитория и рабочих каталогов для каждого сеанса. Runner должен иметь доступ на запись к этому пути или его родительскому каталогу. Runner создает каталог при запуске и выходит с cannot create or write to base directory когда не может создать или записать в него. До v2.1.225 runner создавал каталог при запуске первого сеанса, поэтому неиспользуемый путь приводил к сбою сеансов, а не запуска. На Windows, который не является поддерживаемым хостом runner, нет значения по умолчанию: runner выходит при запуске, если вы не передадите флаг или не установите переменную. Используйте одно и то же значение на каждом runner в среде. См. Keep the base directory and capacity identical across runners.
--capacity <n> none 1 Максимальное количество одновременных сеансов, которые обрабатывает этот runner. Все сеансы принадлежат одному заблокированному owner. Используйте одно и то же значение на каждом runner в среде; см. Keep the base directory and capacity identical across runners.
--client-label <label> SELF_HOSTED_RUNNER_CLIENT_LABEL имя хоста хоста Метка, которую runner отправляет при регистрации. Runner также сообщает её как метку client_label claude_code_self_hosted_runner_info. Требует Claude Code v2.1.248 или позже.
--configure-git SELF_HOSTED_RUNNER_CONFIGURE_GIT=1 off При запуске запишите глобальную идентификацию git, включите подписание коммитов Anthropic, включите переговоры git push и установите hooks коммитов, которые добавляют трейлер Co-authored-by:. Переговоры push требуют Claude Code v2.1.257 или позже. См. Configure git.
--confine-repo-settings <mode> SELF_HOSTED_RUNNER_CONFINE_REPO_SETTINGS warn Устанавливает режим защиты, которая помечает сеанс, когда параметры репозитория, зафиксированные в коммите, пытаются предоставить доступ на запись или чтение вне собственного рабочего пространства этого сеанса, установить переменные окружения или переопределить позицию sandbox или hooks оператора, например sandbox.enabled: false или disableAllHooks. По умолчанию warn регистрирует нарушение и все еще запускает сеанс, enforce отказывает в сеансе, а off отключает сканирование. См. Harden your deployment.
--debug-token-dir <path> SELF_HOSTED_RUNNER_DEBUG_TOKEN_DIR unset Запишите живые токены на диск для проверки. Только для отладки; не используйте в production.
--defer-shutdown-max-min <n> SELF_HOSTED_RUNNER_DEFER_SHUTDOWN_MAX_MS 0 При первом SIGTERM или SIGINT продолжайте обслуживать уже подключенные сеансы вместо их осушения, затем отпустите все еще подключенное через N минут и выйдите. Повысьте timeout остановки вашего хоста перед установкой этого. См. Defer the drain past the first signal. 0 отключает. Требует Claude Code v2.1.238 или позже.
--drain-grace-sec <n> SELF_HOSTED_RUNNER_DRAIN_GRACE_MS 0 До тех пор, пока runner не получит сигнал завершения или не достигнет времени выхода на пенсию, контролирует, когда runner выходит после завершения активных сеансов: 0 выходит немедленно без опроса на дополнительные, а положительное значение держит runner живым и повторно опрашивает очередь заблокированного owner в течение этого количества секунд, за счет изоляции контейнера для каждого сеанса, описанной в разделе hardening. После первого сигнала, который вы отложили с помощью --defer-shutdown-max-min, runner выходит, как только он не содержит сеансов, независимо от того, что вы установили здесь.
--drain-wait-sec <n> SELF_HOSTED_RUNNER_DRAIN_WAIT_MS 0 После начала осушения, которое происходит на SIGTERM, если вы не установили --defer-shutdown-max-min, ждите до N секунд для завершения текущего хода каждого сеанса и фоновых задач перед завершением дочернего процесса. Во время этого ожидания runner считает фоновую задачу, которая только что завершилась, все еще работающей до тех пор, пока не начнется следующий ход, который читает её результат, в течение максимум окна SELF_HOSTED_RUNNER_BG_RESULT_GRACE_MS.
--environment-secret-file <path> SELF_HOSTED_RUNNER_ENVIRONMENT_SECRET required Путь к файлу, содержащему секрет среды, или, для runner, порожденных orchestrator, одноразовый JWT работного заказа. SELF_HOSTED_RUNNER_ENVIRONMENT_SECRET несет значение секрета напрямую, а не путь к файлу. Старый флаг --pool-secret-file и переменная SELF_HOSTED_RUNNER_POOL_SECRET по-прежнему работают и выводят уведомление об устаревании в stderr; сборки runner программы предварительного просмотра старше 2.1.216 распознают только эти старые имена.
--exec-path <path> SELF_HOSTED_RUNNER_EXEC_PATH собственный бинарный файл Бинарный файл или скрипт-обертка для порождения для каждого сеанса. См. Wrapper scripts.
--exit-if-unused-min <n> SELF_HOSTED_RUNNER_IDLE_SHUTDOWN_MS 0 Выйдите после N минут опроса без назначенной работы, для масштабирования автомасштабера. 0 отключает.
--git-host-rewrite <from>=<to> none unset Переписать URL источников https://<from>/... на https://<to>/... перед клонированием для разделенного DNS горизонта. Повторяемо; только флаг.
--git-ssh-rewrite <host> none unset Переписать URL источников https://<host>/... на git@<host>:... перед клонированием для хостов git только с SSH. Повторяемо; только флаг.
--health-port <port> SELF_HOSTED_RUNNER_HEALTH_PORT 8080 Порт для слушателя /healthz и /metrics. Установите 0 для отключения.
--hooks-dir <path> SELF_HOSTED_RUNNER_HOOKS_DIR unset Каталог скриптов hooks жизненного цикла. См. Lifecycle hooks.
--kill-session-after-min <n> SELF_HOSTED_RUNNER_MAX_LIFETIME_MS 0 Ограничьте сеанс N минутами настенного времени как предел безопасности для зависших сеансов. На v2.1.260 или позже runner отпускает сеанс, который достигает лимита, чтобы он мог возобновиться при следующем сообщении пользователя, и завершает его только если он все еще на runner, когда окончится окно благодати SELF_HOSTED_RUNNER_MAX_LIFETIME_GRACE_MS. До v2.1.260 runner завершал сеанс на лимите. См. Some sessions don't count as idle для деталей и как выбрать значение. 0 отключает.
--lock-to-account <id> SELF_HOSTED_RUNNER_LOCK_TO_ACCOUNT unset Предварительно заблокируйте runner на конкретный аккаунт при запуске вместо блокировки при первом сеансе. Принимает адрес электронной почты или ID user_... в организации среды. Предварительно заблокированный runner никогда не подхватывает сеансы канала Claude Tag, у которых нет аккаунта.
--log-file <path> SELF_HOSTED_RUNNER_LOG_FILE unset Зеркалируйте логи runner в файл в дополнение к stdout и stderr, созданный с разрешениями 0600. Требуется для self-hosted-runner doctor для локального отслеживания логов.
--log-level <level> none info info или debug
--post-session-hook-timeout-sec <n> SELF_HOSTED_RUNNER_POST_SESSION_HOOK_TIMEOUT_MS 60 Бюджет для post-session hook при завершении каждого сеанса, включая завершение runner
--proxy-authorization-command <command> SELF_HOSTED_RUNNER_PROXY_AUTHORIZATION_COMMAND unset Команда shell, которую runner запускает для каждого подключения к вашему прокси выхода, используя его обрезанный stdout как значение заголовка Proxy-Authorization. Требует HTTPS_PROXY или HTTP_PROXY, и не может быть объединен с --proxy-authorization-file. См. Authenticate to an egress proxy. Требует Claude Code v2.1.238 или позже.
--proxy-authorization-file <path> SELF_HOSTED_RUNNER_PROXY_AUTHORIZATION_FILE unset Файл, который runner читает для каждого подключения к вашему прокси выхода, используя его обрезанное содержимое как значение заголовка Proxy-Authorization. Используйте этот флаг для токена, который другой процесс ротирует на месте. Несет те же требования, что и --proxy-authorization-command, и не может быть объединен с ним. См. Authenticate to an egress proxy. Требует Claude Code v2.1.238 или позже.
--push-outcome-on-release SELF_HOSTED_RUNNER_PUSH_OUTCOME_ON_RELEASE off При инициированном runner завершении сеанса, таком как осушение или отпуск при простое, отправьте отслеживаемые ветви результатов в origin перед удалением рабочего пространства, чтобы текущие коммиты пережили перезагрузку. Лучшее усилие; добавляет 30 секунд к бюджету завершения и требует git 2.29 или новее для возобновления с отправленной ветви. Ограничьте доступ на отправку к ссылкам claude/* перед включением; см. Resumed sessions lose unpushed work. Репозитории, проверенные через hook checkout жизненного цикла, не отправляются; снимите их с помощью post-session hook вместо этого.
--release-idle-session-min <n> SELF_HOSTED_RUNNER_SESSION_IDLE_MS 0 Отпустите слот сеанса после N минут неактивности после завершения хода или ожидания сеансом действия пользователя. Сеанс, который все еще находится в процессе хода, включая тот, который держит никогда не заканчивающуюся фоновую задачу или одобрение, запрошенное изнутри работающего вызова инструмента, не считается неактивным; объедините с --kill-session-after-min как жесткий упор. После завершения фоновой задачи сеанса runner считает сеанс занятым до тех пор, пока не начнется следующий ход, который читает результат, в течение максимум окна SELF_HOSTED_RUNNER_BG_RESULT_GRACE_MS. До тех пор, пока runner не получит сигнал завершения или не достигнет времени выхода на пенсию, отпуск, который оставляет runner без активных сеансов, запускает тот же путь выхода, что и нормальное осушение, управляемое --drain-grace-sec. После первого сигнала, который вы отложили с помощью --defer-shutdown-max-min, runner выходит, как только отпуск оставляет его без сеансов. 0 отключает.
--retire-at <epoch-seconds> SELF_HOSTED_RUNNER_RETIRE_AT unset Выведите runner на пенсию в абсолютный временной штамп Unix в секундах для инфраструктуры, которая убивает runner в известное время; Runner lifecycle описывает последовательность отпуска и как определить размер маржи. Значения до 2001 или после года 5138 отклоняются флагом и игнорируются переменной окружения.
--session-stop-grace-sec <n> SELF_HOSTED_RUNNER_SESSION_STOP_GRACE_MS 5 Как долго ждать чистого выхода процесса Claude после завершения сеанса перед принудительным завершением. Повысьте значение, если собственные hooks SessionEnd дочернего процесса нуждаются в большем времени.
--startup-timeout-min <n> SELF_HOSTED_RUNNER_STARTUP_TIMEOUT_MS 15 Отпустите слот сеанса, если дочерний процесс не сигнализировал об инициализации в течение N минут после порождения. Очищается сигналом инициализации дочернего процесса на канале активности, а не обычным выводом, после чего --release-idle-session-min берет верх. 0 отключает.
--trust-workspace [bool] SELF_HOSTED_RUNNER_TRUST_WORKSPACE on Посейте сохраняемое доверие для путей репозитория каждого сеанса, чтобы зафиксированные в репо permissions.allow и additionalDirectories были соблюдены. Установите false для отпуска зафиксированных в репо грантов разрешений и вместо этого настройте правила разрешения в settings.json конфигурации хоста; параметры sandbox.* зафиксированные в репо все еще применяются в любом случае, поэтому защита repo-settings сканирует их независимо от этого флага.
--use-anthropic-git-proxy CLAUDE_RUNNER_USE_GIT_PROXY=1 off Клонируйте через прокси git Anthropic вместо управляемой клиентом аутентификации git. Требует --capacity 1 и git 2.32 или новее; runner отказывается запускаться в противном случае. Заменяет флаги переписи.

Большинство флагов длительности имеют максимум, выбранный для сохранения каждого timeout в потолке 32-битного таймера runtime примерно 24,85 дня. Флаги --*-min ограничены 10080 минутами, 7 дней; --drain-grace-sec на 604800 секунд, также 7 дней; и --drain-wait-sec на 86400 секунд, 24 часа. --session-stop-grace-sec и --post-session-hook-timeout-sec не ограничены. Превышение лимита ведет себя по-разному в зависимости от поверхности:

  • Флаг: запуск не удается с ошибкой.
  • Переменная окружения: runner зажимает значение до потолка таймера вместо его отклонения.

Флаги CLI Orchestrator

Подкоманда self-hosted-runner orchestrator, которая порождает on-demand runners, принимает --api-url, --environment-secret-file, --hooks-dir, --health-port и --log-level с теми же значениями по умолчанию, что и runner и, где флаг runner имеет один, ту же переменную окружения, за исключением того, что --hooks-dir требуется и должен содержать hook spawn-runner. Он также принимает свои собственные флаги:

Флаг По умолчанию Описание
--hook-concurrency <n> 4 Максимум hooks spawn-runner, работающих параллельно. Также ограничивает, сколько запросов на порождение претендуют на опрос.
--hook-timeout <sec> 60 Завершите дерево процессов hook после этого количества секунд. Timeout плюс его 5-секундная благодать убийства должны оставаться ниже --expected-spawn-seconds; orchestrator обеспечивает это при запуске.
--expected-spawn-seconds <sec> 120 Ожидаемое время загрузки p99 для порожденных runner в диапазоне, обеспеченном сервером, от 10 до 3600. Отправляется при каждом опросе как аренда на стороне сервера; если ни один runner не регистрируется до его истечения, сеанс переоформляется с новым ID заказа. Все реплики должны совместно использовать это значение.
--min-idle <n> 0 Держите по крайней мере N свободных слотов сеанса в режиме ожидания, активно порождая резервные runner. 0 отключает предварительное прогревание. Объедините с --exit-if-unused-min runner, чтобы избыточные резервные runner восстановили себя.
--debug-dir <path> unset Запишите рабочий заказ каждого запроса на порождение и stderr hook на диск. Только для отладки; никогда не устанавливайте в production.

Флаги SCM connector

Orchestrator может держать постоянное подключение WebSocket к плоскости управления Anthropic, чтобы размещенные предсеансовые потоки, такие как средство выбора репозитория и средство разрешения ветви или ссылки, могли достичь хоста GitHub Enterprise Server, который маршрутизируется только изнутри вашей сети. Соединитель остается отключенным, если вы не установите --scm-connector-host.

Флаг По умолчанию Описание
--scm-connector-host <host[:port]> unset Имя хоста GitHub Enterprise Server для перенаправления запросов. Порт по умолчанию 443. Установка этого флага включает соединитель.
--scm-connector-id <n> required with --scm-connector-host Числовой ID подключения GitHub Enterprise Server вашей организации. Свяжитесь с командой вашего аккаунта Anthropic для значения при включении соединителя.
--scm-connector-provider <slug> ghe Сегмент пути, идентифицирующий поставщика, соответствующий ^[a-z0-9-]{1,32}$.
--scm-connector-ca-file <path> unset Дополнительный пакет CA в формате PEM для подключений TLS к хосту GitHub Enterprise Server.
--scm-connector-host-rewrite <from>=<to_host:to_port> unset Только для сквозного тестирования: перенаправляет подключение TCP, сохраняя заголовок Host и TLS SNI как --scm-connector-host.

Соединитель аутентифицируется с существующим секретом среды orchestrator и автоматически переподключается: с экспоненциальной задержкой при разорванном подключении или фиксированной 30-секундной задержкой, когда плоскость управления закрывает подключение, потому что другая реплика orchestrator уже его держит.

Параметры только для переменных окружения

Эти параметры runner читаются только из окружения и охватывают поведение, которое большинство развертываний оставляют по умолчанию:

Переменная окружения По умолчанию Описание
SELF_HOSTED_RUNNER_BG_RESULT_GRACE_MS 30000 Как долго runner считает сеанс занятым после завершения фоновой задачи, пока не начнется следующий ход, который читает результат. Строки --drain-wait-sec и --release-idle-session-min описывают, где применяется удержание при осушении и отпуске при простое, и Runner lifecycle описывает, где оно применяется при выходе на пенсию --retire-at. 0 или неиспользуемое значение возвращается к значению по умолчанию, поэтому удержание не может быть отключено. Требует Claude Code v2.1.228 или позже.
SELF_HOSTED_RUNNER_HOST_CONFIG_DIR ~/.claude Каталог, захваченный в снимок запуска runner и посеянный в CLAUDE_CONFIG_DIR каждого сеанса; изменения на диске применяются после перезагрузки runner. Установка переменной также перемещает, где runner читает .claude.json для MCP seeding, поэтому установка её, включая её собственное значение по умолчанию, перемещает этот поиск; укажите на пустой каталог для полного отключения посева.
SELF_HOSTED_RUNNER_MAX_LIFETIME_GRACE_MS 900000 Как долго runner ждет после того, как сеанс достигает своего лимита --kill-session-after-min, чтобы текущий ход завершился или отпуск завершился, перед завершением сеанса
SELF_HOSTED_RUNNER_SIGKILL_GRACE_MS 30000 Как долго runner ждет, пока ОС доставит SIGKILL дочернему процессу, застрявшему в неперерываемом I/O, перед выходом самого себя. Минимум --post-session-hook-timeout-sec плюс 15 секунд, и 30 больше, когда установлен --push-outcome-on-release, поэтому эффективный минимум составляет 75 секунд при значениях по умолчанию.
CLAUDE_RUNNER_FETCH_DEPTH 50 Глубина выборки Git для свежих клонов. Установите положительное целое число или full или 0 для полной выборки. Репозитории, уже присутствующие в рабочем пространстве, сохраняют свою существующую глубину.
CLAUDE_RUNNER_SKIP_GIT_VERIFY unset Когда 1, пропустите проверку наличия .git после запуска hook checkout. Установите это, когда ваш hook материализует источник, не являющийся git.
FORCE_AUTOUPDATE_PLUGINS unset Когда 1, позвольте маркетплейсам плагинов автоматически обновляться, несмотря на то, что бинарный файл закреплен
CLAUDE_CODE_DISABLE_ARTIFACT unset Когда 1, отключите инструмент Artifact в сеансах независимо от параметра администратора организации и отпустите требование выхода *.frame.claudeusercontent.com

Телеметрия

Дочерние процессы сеанса отправляют операционную телеметрию в Anthropic, если вы её не отключите. Никакой код или содержимое репозитория не отправляется. Установите переменные телеметрии на процесс runner; runner переустанавливает их после применения переменных окружения, предоставленных сервером, поэтому параметр оператора всегда имеет приоритет.

Один элемент управления специфичен для самостоятельно размещаемых сред: CLAUDE_CODE_BYOC_ENABLE_DATADOG=1 выбирает метрики операционной деятельности Datadog, которые по умолчанию отключены в самостоятельно размещаемых средах. Общие элементы управления телеметрией Claude Code, DISABLE_TELEMETRY, DO_NOT_TRACK, DISABLE_ERROR_REPORTING и CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC, применяются к дочерним процессам сеанса, как задокументировано в справочнике переменных окружения. DISABLE_GROWTHBOOK связан, но отличается: установка DISABLE_GROWTHBOOK=1 отключает выборку флагов функций, и телеметрия остается включенной, если также не установлен DISABLE_TELEMETRY.

CLAUDE_CODE_ENABLE_TELEMETRY не связан: он включает экспорт OpenTelemetry на ваш собственный сборщик, как описано в Monitoring, и не контролирует аналитику Anthropic.

Конечная точка здоровья

Runner служит GET /healthz на настроенном порту здоровья. Ответ 200 OK всякий раз, когда процесс живой, независимо от состояния цикла опроса, поэтому зонд HTTP на этой конечной точке обнаруживает только мертвый процесс. Тело JSON описывает текущее состояние:

{
  "status": "ok",
  "runner_id": "ccrunner_...",
  "active_sessions": 2,
  "last_poll_at": "2026-03-31T18:04:11.220Z",
  "last_poll_age_ms": 842
}

Используйте last_poll_age_ms как сигнал живости в пользовательских зондах; значение, которое растет без ограничений, указывает на то, что цикл опроса застрял. Оба last_poll_at и last_poll_age_ms равны null до завершения первого опроса.

Orchestrator служит своему собственному /healthz на его порту здоровья. Его конечная точка всегда возвращает 200, и тело несет поле connected, сообщающее, успешен ли последний опрос, плюс количество очереди порождения для каждого состояния в queue_counts. Ограничьте готовность и оповещение на connected вместо кода состояния.

Когда SCM connector настроен, тело /healthz orchestrator также несет scm_connector_connected и объект scm_connector с connected, last_connected_at, last_error, reconnects и requests_forwarded. Оба поля равны null, когда --scm-connector-host не установлен.

Метрики Prometheus

Каждый runner служит метрикам Prometheus в GET /metrics на том же порту, что и /healthz. Ключевые серии:

Серия Примечания
claude_code_self_hosted_runner_info{runner_id,version,client_label} Всегда 1; полезно для инвентаризации флота и обнаружения дрейфа версий
claude_code_self_hosted_runner_capacity Настроенный --capacity
claude_code_self_hosted_runner_active_sessions Сеансы, в настоящее время работающие
claude_code_self_hosted_runner_locked_account{email} Присутствует после того, как runner заблокировался на пользователя и был выдан токен сеанса, несущий претензию act.email. Серия отсутствует на runner, заблокированном на агента Claude Tag, чьи токены сеанса не несут act.email. Значение метки — это адрес электронной почты аккаунта; если ваше хранилище метрик широко читаемо, отпустите или хешируйте метку во время скребка, например с помощью Prometheus metric_relabel_configs.
claude_code_self_hosted_runner_last_poll_age_seconds Секунды с момента последнего успешного опроса. Оповещение, если более 60.
claude_code_self_hosted_runner_poll_errors_total{error_kind} Кумулятивные сбои PollWork по типу: transport, timeout, 5xx, 429 или 4xx. Все пять серий присутствуют с начала процесса; оповещение на rate(...[5m]) > 0.
claude_code_self_hosted_runner_sessions_started_total{client_platform} Дочерние процессы сеанса, порожденные за время жизни runner, одна серия на источник сеанса, такой как web_claude_ai, ios, android, desktop_app или claude_code_cli, или unknown, когда сервер не отправил один. Сеансы Slack несут либо claude_in_slack, либо claude-in-slack в зависимости от того, какая интеграция Slack их создала, поэтому совпадайте с обоими с помощью селектора regex, такого как {client_platform=~"claude[-_]in[-_]slack"}. Используйте sum() для общего количества флота.
claude_code_self_hosted_runner_sessions_completed_total{client_platform} Сеансы, которые завершились чисто, помеченные так же. Шире, чем простой чистый выход: см. session lifecycle counter semantics для того, что считается.
claude_code_self_hosted_runner_sessions_failed_total{client_platform} Сеансы, которые завершились в отказе, помеченные так же. Та же оговорка: см. session lifecycle counter semantics.
claude_code_self_hosted_runner_sessions_interrupted_total{client_platform} Сеансы, которые runner завершил по операционной причине, а не по результату сеанса, помеченные так же. См. session lifecycle counter semantics.
claude_code_self_hosted_runner_initializing_sessions Сеансы, в настоящее время находящиеся в фазе инициализации, от назначения до события инициализации дочернего процесса
claude_code_self_hosted_runner_session_init_duration_seconds Гистограмма длительности инициализации сеанса
claude_code_self_hosted_runner_session_init_errors_total Сеансы, которые не удалось инициализировать: сбой hook checkout, подготовка git, проблема с токеном или сбой дочернего процесса до инициализации
claude_code_self_hosted_runner_session_start_hook_errors_total Hooks SessionStart, которые сообщили об ошибке результата, один на каждое неудачное выполнение hook
claude_code_self_hosted_runner_session_idle_seconds{session_id,client_platform} Датчик для каждого сеанса секунд с момента простоя сеанса. Полезно для завершения сеансов, застрявших на неотвеченном запросе разрешения.

Orchestrator служит своим собственным сериям в GET /metrics на том же порту, что и его /healthz:

Серия Примечания
claude_code_self_hosted_orchestrator_info{version,pool_id,orchestrator_uuid,hostname} Всегда 1
claude_code_self_hosted_orchestrator_connected 1, когда последний опрос успешен; падает до 0 после любого неудачного опроса, независимо от типа сбоя
claude_code_self_hosted_orchestrator_last_poll_age_seconds Секунды с момента последней попытки опроса, успеха или сбоя, в отличие от идентично названной метрики runner, которая измеряет с момента последнего успеха; объедините с connected для перехвата неудачных опросов. Цикл опроса orchestrator ждет выполнения hook, поэтому оповещение выше --hook-timeout плюс маржа, около 90 секунд при значениях по умолчанию, вместо плоских 60.
claude_code_self_hosted_orchestrator_poll_errors_total{error_kind} Кумулятивные сбои PollSpawnHints по типу: transport, timeout, 5xx, 429 или 4xx. Все пять серий присутствуют с начала процесса; оповещение на rate(...[5m]) > 0.
claude_code_self_hosted_orchestrator_queue_pending_sessions Запросы на порождение, претендующие прямо сейчас
claude_code_self_hosted_orchestrator_queue_backing_off_sessions Запросы на порождение в отступлении повтора после повторяемого сбоя hook
claude_code_self_hosted_orchestrator_queue_circuit_broken_sessions Запросы на порождение, заблокированные до тех пор, пока Owner не повторит их с вкладки Activity среды; оповещение, если выше нуля
claude_code_self_hosted_orchestrator_pool_pending_sessions Всего сеансов, ожидающих runner для этой среды. Совокупность на уровне среды, идентичная на каждом экземпляре orchestrator: используйте MAX вместо SUM по экземплярам.
claude_code_self_hosted_orchestrator_pool_active_sessions Сеансы, в настоящее время назначенные живому runner в этой среде. Совокупность на уровне среды, идентичная на каждом экземпляре orchestrator: используйте MAX вместо SUM по экземплярам.
claude_code_self_hosted_orchestrator_spawn_hooks_total{result} Кумулятивные результаты hook spawn-runner: ok, retryable, non_retryable. Подсчитывает вызовы hook orchestrator, а не дочерние процессы сеанса, которые порождают runner: не сравнимо с sessions_started_total, так как емкость выше одного, теплые пулы и runner, порожденные снова для того же сеанса, все расходятся в двух.
claude_code_self_hosted_orchestrator_spawn_hook_duration_seconds Гистограмма длительности hook
claude_code_self_hosted_orchestrator_warm_hints_dispatched_total Запросы на порождение резервного копирования, отправленные с начала процесса
claude_code_self_hosted_orchestrator_session_queue_wait_seconds Гистограмма секунд, которые каждый сеанс ждал в очереди перед тем, как orchestrator претендовал на него для порождения, записанная из временной метки очереди ожидания, которую плоскость управления отправляет с каждым запросом на порождение сеанса. Используйте для оповещения времени очереди p50/p99. Порождения предварительного прогрева не отбираются.
claude_code_self_hosted_orchestrator_clock_skew_seconds Перекос часов локальный минус сервер; диагностический, присутствует один раз измеренный
claude_code_self_hosted_orchestrator_scm_connector_connected 1, когда WebSocket SCM connector открыт; 0 во время набора номера или отступления. Отсутствует, когда --scm-connector-host не установлен.
claude_code_self_hosted_orchestrator_scm_connector_requests_forwarded_total Кумулятивные HTTP запросы, проксированные на настроенный хост SCM с начала процесса. Отсутствует, когда --scm-connector-host не установлен.

Для автомасштабирования выберите серию, которая соответствует вашему стилю масштабирования, и ограничьте её перед подачей в масштабер:

  • Масштабирование глубины очереди: подайте claude_code_self_hosted_orchestrator_pool_pending_sessions в ваш HPA или KEDA масштабер, а не queue_pending_sessions.
  • Масштабирование емкости: масштабируйте по соотношению active_sessions runner к capacity.
  • Ограничение на connected: отфильтруйте запрос с помощью claude_code_self_hosted_orchestrator_connected == 1 на экземпляр, поэтому устаревшее значение отключенной реплики не подается в масштабер.

Во время полного отключения опроса каждая реплика отключена, гейтированный запрос не возвращает данные. HPA удерживает текущее количество реплик на отсутствующей метрике, но Prometheus масштабер KEDA при его значении по умолчанию ignoreNullValues: "true" читает пустой результат как ноль и масштабирует; установите ignoreNullValues: "false" на ScaledObject, опционально с полом реплики fallback.

Следующий Prometheus Operator PodMonitor охватывает оба процесса. Он выбирает pods по метке app.kubernetes.io/part-of: claude-code-self-hosted-runner и именованному порту health, который устанавливает рецепт Kubernetes; отрегулируйте пространства имен в соответствии с вашим развертыванием:

# Example Prometheus Operator PodMonitor for the Claude Code self-hosted
# runner + orchestrator. Adjust the namespace and label selectors to match
# your deployment. Both the runner and the orchestrator serve /metrics on
# their --health-port (default 8080).
apiVersion: monitoring.coreos.com/v1
kind: PodMonitor
metadata:
  name: claude-code-self-hosted-runner
  namespace: monitoring
spec:
  namespaceSelector:
    matchNames:
      - claude-runners
  selector:
    matchExpressions:
      # Matches the runner Deployment from the Kubernetes recipe, plus any
      # on-demand runner Jobs and orchestrator pods you label the same way
      # and give a named 'health' containerPort.
      - key: app.kubernetes.io/part-of
        operator: In
        values: [claude-code-self-hosted-runner]
  podMetricsEndpoints:
    - port: health
      path: /metrics
      interval: 30s

Эти примеры правил оповещения — это отправная точка; настройте пороги для размера вашего флота:

# Example Prometheus alert rules for the Claude Code self-hosted runner
# + orchestrator. Tune thresholds for your fleet size and SLOs.
groups:
  - name: claude-code-self-hosted-runner
    rules:
      - alert: ClaudeRunnerPollStale
        expr: claude_code_self_hosted_runner_last_poll_age_seconds > 60
        for: 2m
        labels: {severity: warning}
        annotations:
          summary: "Runner {{ $labels.pod }} has not polled in >60s"
      - alert: ClaudeRunnerVersionDrift
        expr: count(count by (version) (claude_code_self_hosted_runner_info)) > 1
        for: 30m
        labels: {severity: info}
        annotations:
          summary: "Runners are running mixed versions"
      - alert: ClaudeRunnerInitErrorsHigh
        expr: increase(claude_code_self_hosted_runner_session_init_errors_total[10m]) > 3
        for: 5m
        labels: {severity: warning}
        annotations:
          summary: "Runner {{ $labels.pod }}: >3 session init failures in 10m (checkout hook / git / token / pre-init crash)"
      - alert: ClaudeRunnerPollErrors
        expr: sum by (pod) (rate(claude_code_self_hosted_runner_poll_errors_total[5m])) > 0
        for: 2m
        labels: {severity: warning}
        annotations:
          summary: "Runner {{ $labels.pod }}: PollWork failing ({{ $value | humanize }}/s over 5m)"
      - alert: ClaudeRunnerSessionStartHookErrors
        expr: increase(claude_code_self_hosted_runner_session_start_hook_errors_total[10m]) > 3
        for: 5m
        labels: {severity: warning}
        annotations:
          summary: "Runner {{ $labels.pod }}: >3 SessionStart hook failures in 10m"

  - name: claude-code-self-hosted-orchestrator
    rules:
      - alert: ClaudeOrchestratorDisconnected
        expr: claude_code_self_hosted_orchestrator_connected == 0
        for: 2m
        labels: {severity: critical}
        annotations:
          summary: "Orchestrator {{ $labels.pod }} cannot reach the Anthropic control plane"
      - alert: ClaudeOrchestratorPollStale
        expr: claude_code_self_hosted_orchestrator_last_poll_age_seconds > 90
        for: 2m
        labels: {severity: warning}
        annotations:
          summary: "Orchestrator {{ $labels.pod }} has not polled in >90s (poll loop waits on hook execution)"
      - alert: ClaudeOrchestratorCircuitBroken
        expr: claude_code_self_hosted_orchestrator_queue_circuit_broken_sessions > 0
        for: 1m
        labels: {severity: critical}
        annotations:
          summary: "{{ $value }} sessions circuit-broken — spawn-runner hook is repeatedly non-retryable; fix infra then retry from the Activity tab"
      - alert: ClaudeOrchestratorPollErrors
        expr: sum by (pod) (rate(claude_code_self_hosted_orchestrator_poll_errors_total[5m])) > 0
        for: 2m
        labels: {severity: warning}
        annotations:
          summary: "Orchestrator {{ $labels.pod }}: PollSpawnHints failing ({{ $value | humanize }}/s over 5m)"
      - alert: ClaudeOrchestratorSpawnHookFailing
        expr: sum by (pod) (increase(claude_code_self_hosted_orchestrator_spawn_hooks_total{result!="ok"}[5m])) > 3
        for: 5m
        labels: {severity: warning}
        annotations:
          summary: "Orchestrator {{ $labels.pod }}: >3 spawn-runner hook failures in 5m"

Пропустить метрики дочернего процесса сеанса

Каждый сеанс работает в своем собственном дочернем процессе с собственными метриками OpenTelemetry; при --capacity выше одного runner переписывает, как эти метрики дочернего процесса выставляются. Установка OTEL_METRICS_EXPORTER=prometheus на хосте runner и CLAUDE_CODE_ENABLE_TELEMETRY=1 в окружении сеанса, например из вашего скрипта-обертки или собственного окружения runner, которое сеансы наследуют, переоткрывает счетчики и датчики каждого дочернего процесса на собственной конечной точке /metrics runner, наряду с сериями runner. Runner переписывает экспортер дочернего процесса для отправки по OTLP на приемник только для loopback на порту здоровья, помечает каждую серию метками session_id и client_platform и вытесняет серии сеанса при завершении этого сеанса. Гистограммы не проходят, и метрика дочернего процесса, чье имя будет конфликтовать с собственным префиксом runner, отпускается.

При значении по умолчанию --capacity 1 переписывание не применяется: дочерний процесс сеанса привязывает свою собственную конечную точку Prometheus на порту 9464 как обычно.

Семантика счетчика жизненного цикла сеанса

Счетчики sessions_started_total, sessions_completed_total, sessions_failed_total и sessions_interrupted_total классифицируют каждый сеанс по тому, как он завершился. Каждый порожденный дочерний процесс сеанса увеличивает sessions_started_total во время порождения, и ровно один из трех других увеличивается при выходе, поэтому sessions_started_total минус сумма трех других равна количеству дочерних процессов сеанса, в настоящее время работающих.

  • completed: сеанс завершился чисто. Это охватывает дочерний процесс, выходящий самостоятельно с кодом 0, сеанс, архивируемый или удаляемый, пока дочерний процесс был все еще подключен, и runner, передающий слот чисто: отпуск сеанса при timeout простоя, времени выхода на пенсию или лимите --kill-session-after-min; startup timeout; или деассайн на стороне сервера, который цикл опроса заметил перед выходом дочернего процесса. Увеличивает sessions_completed_total.
  • failed: дочерний процесс выходит самостоятельно с ненулевым кодом, либо сбой, либо сбой настройки после порождения. Увеличивает sessions_failed_total.
  • interrupted: runner завершил дочерний процесс по операционной причине, которая не является ни успехом сеанса, ни ошибкой runner, такой как осушение или завершение сеанса, который все еще был на runner, когда окончилось окно благодати SELF_HOSTED_RUNNER_MAX_LIFETIME_GRACE_MS после его лимита --kill-session-after-min. Перезагрузка Kubernetes, отправляющая SIGTERM, является одним примером осушения. Увеличивает sessions_interrupted_total.

До v2.1.260 runner завершал каждый сеанс, который достигал своего лимита --kill-session-after-min, и подсчитывал его в sessions_interrupted_total.

Hook post-session классифицирует чистые передачи по-другому через CLAUDE_RUNNER_EXIT_REASON. Hook сообщает об отпуске, startup timeout и деассайне сервера как interrupted, потому что runner остановил дочерний процесс. Эти счетчики записывают те же события, что и completed, потому что слот был передан чисто.

Если вы согласовываете квитанции hook непосредственно с sessions_completed_total, вы недосчитываетесь завершений. Используйте hook для гарантий для каждого сеанса и счетчики для совокупных ставок.

В одноразовой среде --capacity 1 с значением по умолчанию --drain-grace-sec 0 каждый процесс runner выходит через несколько мгновений после завершения его одного сеанса. sessions_completed_total, sessions_failed_total и sessions_interrupted_total увеличиваются только при завершении сеанса, прямо перед этим выходом, поэтому скребок Prometheus каждые 15-60 секунд редко ловит увеличение перед исчезновением серии runner; эти три счетчика конца сеанса — это терминальные счетчики, на которые ссылается остальная часть этого раздела. sessions_started_total увеличивается при порождении и остается видимым в течение жизни сеанса, поэтому он надежно показывается, но в одноразовой среде он читается ближе к "сеансам, в настоящее время работающим", чем к совокупному подсчету.

Используйте серию в этой таблице для соответствующей цели вместо терминальных счетчиков:

Цель Использование
Пропускная способность claude_code_self_hosted_orchestrator_spawn_hooks_total{result="ok"}, счетчик на долгоживущем orchestrator, который увеличивается один раз на успешный hook spawn-runner и остается значимым под rate(). Он подсчитывает вызовы hook, а не сеансы, поэтому предварительное прогревание и повторные порождения для того же сеанса расходятся в нем от подсчетов сеансов.
Использование sum(claude_code_self_hosted_runner_active_sessions) против sum(claude_code_self_hosted_runner_capacity), оба датчика действительны при каждом скребке независимо от времени жизни runner
Невыполненные заказы claude_code_self_hosted_orchestrator_pool_pending_sessions для глубины очереди и claude_code_self_hosted_orchestrator_queue_circuit_broken_sessions, оповещение, если выше нуля
Сбои claude_code_self_hosted_runner_sessions_failed_total, лучшее усилие: реальные сбои после порождения действительно увеличивают его, и rate() значим на runner, которые пережили свои сеансы с --drain-grace-sec выше 0. Одноразовая среда имеет ту же проблему окна скребка, что и другие терминальные счетчики, поэтому рассматривайте любое ненулевое значение, которое вы видите, как стоящее исследования. Сбои перед порождением, такие как сбой hook checkout, подготовка git или проблема с токеном, появляются только в session_init_errors_total.

Строки orchestrator_* существуют только в средах, работающих с on-demand orchestrator. На фиксированном флоте, чьи runner пережили свои сеансы, с --drain-grace-sec выше 0, используйте sum(rate(claude_code_self_hosted_runner_sessions_started_total[5m])) для пропускной способности; в одноразовом флоте эта серия имеет ту же проблему окна скребка, что и терминальные счетчики, поэтому полагайтесь на подсчет сеансов в очереди вместо этого. Проверьте невыполненные заказы на вкладке Activity среды, на странице администратора Cloud environments: runner не экспортируют серию глубины очереди.

Для отчетности результатов для каждого сеанса используйте вместо этого hook post-session: он срабатывает при каждом завершении сеанса, где был порожден дочерний процесс, кроме резкого завершения runner, такого как вытеснение VM, в соответствии с собственным контрактом hook.

Что дальше