Referência de ambientes auto-hospedados
Referência completa para o executor e orquestrador auto-hospedados: sinalizadores CLI, variáveis de ambiente e métricas Prometheus.
[!NOTE]
Ambientes auto-hospedados estão em beta pública em planos Team e Enterprise; um Proprietário os habilita ativando Permitir ambientes auto-hospedados na página de administração Ambientes na nuvem. Esta página é a referência de sinalizadores e métricas; consulte o guia de início rápido para configuração e Implantar em produção para as receitas de frota.
Esta página é a referência para os dois processos que você executa em um ambiente auto-hospedado: o executor, que executa sessões na nuvem do Claude Code em seus hosts, e o orquestrador de dimensionamento automático opcional, que inicia executores conforme as sessões são enfileiradas. Cada um tem sua própria tabela de sinalizadores. Ambos são executados em hosts Linux ou macOS, que os padrões como /workspace e ~/.claude assumem. Execute claude self-hosted-runner --help para a lista autoritativa em sua versão instalada.
Séries de métricas e alguns campos de API ainda usam pool para o que estas páginas chamam de ambiente; ambos os termos nomeiam a mesma coisa. O ID do ambiente é o campo pool_id, com a forma ccpool_...: onde quer que estas páginas mostrem um identificador pool, ele nomeia o ambiente. Sinalizadores CLI e variáveis de ambiente o escrevem como environment, como --environment-secret-file; as grafias pool descontinuadas ainda funcionam, como a linha --environment-secret-file descreve.
Sinalizadores CLI do executor
A maioria dos sinalizadores tem uma variável de ambiente correspondente. Quando ambos estão definidos, o sinalizador tem precedência. Sinalizadores de duração usam minutos ou segundos na CLI, mas a variável de ambiente emparelhada está sempre em milissegundos, indicada pelo sufixo _MS, e a coluna Padrão mostra a unidade do sinalizador: --exit-if-unused-min 10 é equivalente a SELF_HOSTED_RUNNER_IDLE_SHUTDOWN_MS=600000, e um valor Helm como SELF_HOSTED_RUNNER_STARTUP_TIMEOUT_MS: "15" significa 15 milissegundos, não o padrão de 15 minutos.
| Sinalizador | Var de ambiente | Padrão | Descrição |
|---|---|---|---|
--api-url <url> |
nenhum | https://api.anthropic.com |
URL base da API. Substitua apenas para testes. |
--base-dir <path> |
SELF_HOSTED_RUNNER_BASE_DIR |
/workspace; nenhum no Windows |
Diretório para checkouts de repositório e diretórios de trabalho por sessão. O executor precisa de acesso de escrita a este caminho ou seu pai. O executor cria o diretório na inicialização e sai com cannot create or write to base directory quando não consegue criar ou escrever nele. Antes da v2.1.225, o executor criava o diretório quando a primeira sessão começava, então um caminho inutilizável falhava nas sessões em vez da inicialização. No Windows, que não é um host executor suportado, não há padrão: o executor sai na inicialização a menos que você passe o sinalizador ou defina a variável. Use o mesmo valor em cada executor em um ambiente. Consulte Keep the base directory and capacity identical across runners. |
--capacity <n> |
nenhum | 1 |
Máximo de sessões simultâneas que este executor manipula. Todas as sessões pertencem ao mesmo proprietário bloqueado. Use o mesmo valor em cada executor em um ambiente; consulte Keep the base directory and capacity identical across runners. |
--client-label <label> |
SELF_HOSTED_RUNNER_CLIENT_LABEL |
nome do host | Rotule o executor que envia quando se registra. O executor também o relata como o rótulo client_label de claude_code_self_hosted_runner_info. Requer Claude Code v2.1.248 ou posterior. |
--configure-git |
SELF_HOSTED_RUNNER_CONFIGURE_GIT=1 |
desligado | Na inicialização, escreva identidade git global, habilite assinatura de commit Anthropic, ative negociação de push git e instale hooks de commit que anexam um trailer Co-authored-by:. A negociação de push requer Claude Code v2.1.257 ou posterior. Consulte Configure git. |
--confine-repo-settings <mode> |
SELF_HOSTED_RUNNER_CONFINE_REPO_SETTINGS |
warn |
Define o modo da proteção que sinaliza uma sessão quando as configurações confirmadas de um repositório tentam conceder acesso de escrita ou leitura fora do próprio workspace dessa sessão, definir variáveis de ambiente ou substituir a postura de sandbox ou hooks do operador, como sandbox.enabled: false ou disableAllHooks. O padrão warn registra a violação e ainda inicia a sessão, enforce recusa a sessão, e off desabilita a verificação. Consulte Harden your deployment. |
--debug-token-dir <path> |
SELF_HOSTED_RUNNER_DEBUG_TOKEN_DIR |
não definido | Escreva tokens ao vivo em disco para inspeção. Apenas depuração; não use em produção. |
--defer-shutdown-max-min <n> |
SELF_HOSTED_RUNNER_DEFER_SHUTDOWN_MAX_MS |
0 |
No primeiro SIGTERM ou SIGINT, continue servindo as sessões já anexadas em vez de drená-las, depois libere o que ainda estiver anexado N minutos depois e saia. Aumente o tempo limite de parada do seu host antes de definir isso. Consulte Defer the drain past the first signal. 0 desabilita. Requer Claude Code v2.1.238 ou posterior. |
--drain-grace-sec <n> |
SELF_HOSTED_RUNNER_DRAIN_GRACE_MS |
0 |
Até o executor receber um sinal de desligamento ou atingir seu tempo de aposentadoria, controla quando o executor sai após suas sessões ativas terminarem: 0 sai imediatamente sem pesquisar mais, e um valor positivo mantém o executor vivo e re-pesquisando a fila do proprietário bloqueado por muitos segundos primeiro, ao custo do isolamento de contêiner por sessão descrito na seção de endurecimento. Após um primeiro sinal que você adiou com --defer-shutdown-max-min, o executor sai assim que não mantém sessões, seja qual for o que você definir aqui. |
--drain-marker-file <path> |
SELF_HOSTED_RUNNER_DRAIN_MARKER_FILE |
não definido | Arquivo marcador que seu host escreve para anunciar uma drenagem graciosa antes de enviar SIGTERM. Quando o arquivo existe quando a drenagem começa, o executor relata sua saída para Anthropic como uma drenagem de host em vez de um sinal de desligamento simples. A drenagem em si, incluindo a espera --drain-wait-sec, funciona da mesma forma que sem o sinalizador. Nomeie um caminho em um sistema de arquivos local que as sessões não possam escrever. Requer Claude Code v2.1.271 ou posterior. |
--drain-wait-sec <n> |
SELF_HOSTED_RUNNER_DRAIN_WAIT_MS |
0 |
Uma vez que a drenagem começa, que é em SIGTERM a menos que você defina --defer-shutdown-max-min, aguarde até N segundos para que cada turno em voo da sessão e tarefas em segundo plano terminem antes de encerrar o filho. Durante esta espera, o executor conta uma tarefa em segundo plano que acabou de terminar como ainda em execução até o turno de acompanhamento que lê seu resultado começar, por no máximo a janela SELF_HOSTED_RUNNER_BG_RESULT_GRACE_MS. Aumente também seu timeout de parada. |
--environment-secret-file <path> |
SELF_HOSTED_RUNNER_ENVIRONMENT_SECRET |
obrigatório | Caminho para um arquivo contendo o segredo do ambiente, ou, para executores gerados pelo orquestrador, o JWT de ordem de trabalho de uso único. SELF_HOSTED_RUNNER_ENVIRONMENT_SECRET carrega o valor secreto diretamente, não um caminho de arquivo. O sinalizador --pool-secret-file mais antigo e a variável SELF_HOSTED_RUNNER_POOL_SECRET ainda funcionam e imprimem um aviso de descontinuação para stderr; compilações de executor do programa de visualização mais antigas que 2.1.216 reconhecem apenas esses nomes mais antigos. |
--exec-path <path> |
SELF_HOSTED_RUNNER_EXEC_PATH |
binário próprio | Binário ou script wrapper para gerar para cada sessão. Consulte Wrapper scripts. |
--exit-if-unused-min <n> |
SELF_HOSTED_RUNNER_IDLE_SHUTDOWN_MS |
0 |
Saia após N minutos de pesquisa sem trabalho nunca atribuído, para redução de escala do autoscaler. 0 desabilita. |
--git-host-rewrite <from>=<to> |
nenhum | não definido | Reescreva URLs de origem https://<from>/... para https://<to>/... antes de clonar, para DNS de horizonte dividido. Repetível; apenas sinalizador. |
--git-ssh-rewrite <host> |
nenhum | não definido | Reescreva URLs de origem https://<host>/... para git@<host>:... antes de clonar, para hosts git somente SSH. Repetível; apenas sinalizador. |
--health-port <port> |
SELF_HOSTED_RUNNER_HEALTH_PORT |
8080 |
Porta para o ouvinte /healthz e /metrics. Defina 0 para desabilitar. |
--hold-idle-file <path> |
SELF_HOSTED_RUNNER_HOLD_IDLE_FILE |
não definido | Arquivo que seu host continua alterando para manter uma sessão ociosa no executor. Consulte Keep an idle session while its processes run. Requer Claude Code v2.1.311 ou posterior. |
--hooks-dir <path> |
SELF_HOSTED_RUNNER_HOOKS_DIR |
não definido | Diretório de scripts de hook de ciclo de vida. Consulte Lifecycle hooks. |
--host-config-snapshot <mode> |
SELF_HOSTED_RUNNER_HOST_CONFIG_SNAPSHOT |
disk |
Onde o executor mantém o snapshot de inicialização do diretório de configuração do host que semeia cada sessão a partir de. disk copia o snapshot para um diretório de propriedade do executor sob --base-dir e, no início de cada sessão, verifica cada arquivo contra um resumo na memória. Se um arquivo na cópia foi modificado, a sessão falha e o executor recusa sessões até você reiniciá-lo. memory mantém todo o snapshot no heap, limitado a 64 MiB; acima do limite, as sessões começam sem configuração de host e mostram um aviso dizendo isso. Quando o executor não consegue escrever o snapshot de disco, ele registra a falha e usa memory para essa execução. Requer Claude Code v2.1.271 ou posterior. |
--kill-session-after-min <n> |
SELF_HOSTED_RUNNER_MAX_LIFETIME_MS |
0 |
Limite uma sessão a N minutos de tempo real, como um limite de segurança para sessões presas. Na v2.1.260 ou posterior, o executor libera uma sessão que atinge o limite para que possa retomar na próxima mensagem do usuário, e a encerra apenas se ainda estiver no executor quando a janela de graça SELF_HOSTED_RUNNER_MAX_LIFETIME_GRACE_MS terminar. Antes da v2.1.260, o executor encerrava a sessão no limite. Consulte Some sessions don't count as idle para os detalhes e como escolher um valor. 0 desabilita. |
--lock-to-account <id> |
SELF_HOSTED_RUNNER_LOCK_TO_ACCOUNT |
não definido | Pré-bloqueie o executor para uma conta específica na inicialização em vez de bloquear na primeira sessão. Aceita um endereço de email ou ID user_... na organização do ambiente. Um executor pré-bloqueado nunca pega sessões de canal Claude Tag, que não têm conta. |
--log-file <path> |
SELF_HOSTED_RUNNER_LOG_FILE |
não definido | Espelhe logs do executor para um arquivo além de stdout e stderr, criado com permissões 0600. Obrigatório para self-hosted-runner doctor rastrear logs localmente. |
--log-level <level> |
nenhum | info |
info ou debug |
--max-hold-min <n> |
SELF_HOSTED_RUNNER_MAX_HOLD_MS |
1440 |
Com --hold-idle-file, libere uma sessão mantida mesmo assim N minutos depois que ela ficou ociosa. Um valor igual ou inferior a --release-idle-session-min não mantém nada. 0 desativa a retenção. Requer Claude Code v2.1.311 ou posterior. |
--post-session-hook-timeout-sec <n> |
SELF_HOSTED_RUNNER_POST_SESSION_HOOK_TIMEOUT_MS |
60 |
Orçamento para o hook post-session no final de cada sessão, incluindo desligamento do executor |
--proxy-authorization-command <command> |
SELF_HOSTED_RUNNER_PROXY_AUTHORIZATION_COMMAND |
não definido | Comando shell que o executor executa para cada conexão com seu proxy de saída, usando seu stdout aparado como o valor do cabeçalho Proxy-Authorization. Requer HTTPS_PROXY ou HTTP_PROXY, e não pode ser combinado com --proxy-authorization-file. Consulte Authenticate to an egress proxy. Requer Claude Code v2.1.238 ou posterior. |
--proxy-authorization-file <path> |
SELF_HOSTED_RUNNER_PROXY_AUTHORIZATION_FILE |
não definido | Arquivo que o executor lê para cada conexão com seu proxy de saída, usando seu conteúdo aparado como o valor do cabeçalho Proxy-Authorization. Use este sinalizador para um token que outro processo rotaciona no lugar. Carrega os mesmos requisitos que --proxy-authorization-command, e não pode ser combinado com ele. Consulte Authenticate to an egress proxy. Requer Claude Code v2.1.238 ou posterior. |
--push-outcome-on-release |
SELF_HOSTED_RUNNER_PUSH_OUTCOME_ON_RELEASE |
desligado | Quando o próprio executor encerra uma sessão, como em uma drenagem ou em uma liberação por inatividade, o executor envia os branches principais da sessão que têm novos commits para origin antes de excluir o workspace. Melhor esforço; adiciona 30 segundos ao orçamento de desligamento. Requer git 2.29 ou mais recente para retomar a partir deles. Restrinja o acesso de envio a refs claude/*; consulte Sessões retomadas perdem trabalho não enviado. Os repositórios de um hook checkout não são enviados; faça snapshot deles a partir do hook post-session. |
--release-idle-session-min <n> |
SELF_HOSTED_RUNNER_SESSION_IDLE_MS |
0 |
Libere um slot de sessão após N minutos de inatividade uma vez que um turno termine ou a sessão aguarde a ação do usuário. Some sessions don't count as idle, então emparelhe com --kill-session-after-min. Uma tarefa em segundo plano concluída mantém a sessão ocupada por no máximo a janela SELF_HOSTED_RUNNER_BG_RESULT_GRACE_MS. Para atrasar uma liberação, defina --hold-idle-file. 0 desabilita. |
--remove-session-state [bool] |
SELF_HOSTED_RUNNER_REMOVE_SESSION_STATE |
desligado | Remova os diretórios por sessão de uma sessão sob <base-dir>/_sessions/ quando a sessão terminar neste executor, seja qual for o resultado. Reuse a pre-warmed checkout descreve o que eles contêm e quem pode lê-los quando permanecem. A remoção é melhor esforço: os diretórios por sessão permanecem no lugar quando o executor é morto ou atinge seu prazo de drenagem antes da limpeza ser executada. Com o sinalizador ativado, o log de depuração de uma sessão falhada ou interrompida não é mantido em disco. Requer Claude Code v2.1.268 ou posterior. |
--retire-at <epoch-seconds> |
SELF_HOSTED_RUNNER_RETIRE_AT |
não definido | Aposentar o executor em um timestamp Unix absoluto em segundos, para infraestrutura que mata o executor em um tempo conhecido; Runner lifecycle descreve a sequência de liberação e como dimensionar a margem. Valores antes de 2001 ou após o ano 5138 são rejeitados pelo sinalizador e ignorados pela variável de ambiente. |
--server-auto-mode-lists <mode> |
SELF_HOSTED_RUNNER_SERVER_AUTO_MODE_LISTS |
no-allow |
Quais das listas de regras do classificador do modo auto que o plano de controle envia com uma sessão podem chegar a essa sessão: all, no-allow ou none. Consulte Listas de regras do modo auto para saber o que cada valor aplica. Um valor inválido interrompe o executor na inicialização. Requer Claude Code v2.1.295 ou posterior. |
--session-stop-grace-sec <n> |
SELF_HOSTED_RUNNER_SESSION_STOP_GRACE_MS |
5 |
Quanto tempo aguardar para que o processo Claude saia limpo após uma sessão terminar, antes de forçar o encerramento. Aumente o valor se os hooks SessionEnd do próprio filho precisarem de mais tempo. |
--startup-timeout-min <n> |
SELF_HOSTED_RUNNER_STARTUP_TIMEOUT_MS |
15 |
Quanto tempo aguardar por um processo filho que não inicializou antes de liberar o slot da sessão. Consulte Timeout de inicialização da sessão para saber onde a contagem começa e quais sessões ela deixa em execução. 0 desabilita o timeout. |
--trust-workspace [bool] |
SELF_HOSTED_RUNNER_TRUST_WORKSPACE |
ativado | Semeie confiança persistida para cada caminho de repositório de sessão para que permissions.allow e additionalDirectories confirmados no repo sejam honrados. Defina false para descartar concessões de permissão confirmadas no repo e configure regras de permissão no settings.json da configuração do host em vez disso; configurações sandbox.* confirmadas no repositório ainda se aplicam de qualquer forma, é por isso que a proteção de configurações do repo as verifica independentemente deste sinalizador. |
--use-anthropic-git-proxy |
CLAUDE_RUNNER_USE_GIT_PROXY=1 |
desligado | Clone repositórios no github.com via proxy git da Anthropic em vez de autenticação git gerenciada pelo cliente. Requer --capacity 1 e git 2.32 ou mais recente; o executor recusa iniciar caso contrário. Também requer Claude Code v2.1.267 ou posterior. Substitui as flags de reescrita. |
A maioria dos sinalizadores de duração tem um máximo, escolhido para manter cada tempo limite dentro do teto do temporizador de 32 bits do tempo de execução de aproximadamente 24,85 dias. Os sinalizadores --*-min limitam a 10080 minutos, 7 dias; --drain-grace-sec a 604800 segundos, também 7 dias; e --drain-wait-sec a 86400 segundos, 24 horas. --session-stop-grace-sec e --post-session-hook-timeout-sec não têm limite. Exceder um limite se comporta diferentemente por superfície:
- Sinalizador: a inicialização falha com um erro.
- Variável de ambiente: o executor fixa o valor ao teto do temporizador em vez de rejeitá-lo.
Timeout de inicialização da sessão
Se uma sessão perdeu seu slot durante um turno como /code-review, atualize o executor e o binário filho para a v2.1.309 ou posterior. Da v2.1.299 até a v2.1.308, o executor liberava uma sessão, mesmo no meio de um turno, assim que o timeout de inicialização passava sem uma mensagem user ou assistant.
Com --startup-timeout-min <n>, o executor libera o slot de uma sessão quando seu filho não inicializou dentro de <n> minutos após a clonagem. Durante um turno que começa antes de o filho inicializar, a sessão mantém seu slot até que <n> minutos se passem sem nenhuma linha no canal de atividade do filho. Assim que o filho inicializa, o executor zera essa contagem e --release-idle-session-min governa a liberação. Para limitar uma sessão cujo filho está vivo, mas travado, defina --kill-session-after-min.
Listas de regras do modo auto
--server-auto-mode-lists permite que você decida quais regras do classificador do modo auto vindas de fora do executor chegam às sessões nos seus executores. O plano de controle da Anthropic pode enviar listas de regras com uma sessão e pedir ao executor que as aplique. Algumas entradas podem ser regras que um administrador da sua organização escreveu. As listas são environment, soft_deny e allow:
environment: uma entrada pode fazer o classificador permitir mais, assim como menos.soft_deny: uma entrada bloqueia uma ação, a menos que o usuário a tenha solicitado explicitamente ou uma exceçãoallowse aplique.allow: as exceções às entradassoft_deny.
O valor da flag escolhe quais listas o executor aplica:
no-allow: o padrão. Aplicaenvironmentesoft_denye retémallow. Uma entradaenvironmentainda pode fazer o classificador permitir mais, então o padrão não descarta todo afrouxamento.all: aplica as três listas.none: não aplica nenhuma delas. Escolhanonepara descartar todo afrouxamento vindo dessas listas. Isso também remove as restrições desoft_deny.
Nenhuma configuração do executor faz o plano de controle pedir ao executor que aplique as listas. Quando ele não pede, as sessões não recebem nenhuma lista, seja qual for o valor que você definir. Para ver o que aconteceu, inicie o executor com --log-level debug. Para cada sessão, o executor então registra em log uma linha contendo the server asked this runner to apply, ou uma contendo the server did not ask this runner to apply the auto mode lists it sends.
Sinalizadores CLI do orquestrador
O subcomando self-hosted-runner orchestrator, que gera executores sob demanda, aceita --api-url, --environment-secret-file, --hooks-dir, --health-port e --log-level com os mesmos padrões que o executor e, onde o sinalizador do executor tem um, a mesma variável de ambiente, exceto que --hooks-dir é obrigatório e deve conter um hook spawn-runner. Também usa seus próprios sinalizadores:
| Sinalizador | Padrão | Descrição |
|---|---|---|
--hook-concurrency <n> |
4 |
Máximo de hooks spawn-runner em execução em paralelo. Também limita quantas requisições de geração são reivindicadas por pesquisa. O orquestrador verifica novas requisições de geração somente depois que todos os hooks que iniciou tiverem terminado, portanto um hook lento atrasa os próximos hooks desse orquestrador. |
--hook-timeout <sec> |
60 |
Encerre a árvore de processos do hook após esse número de segundos. O tempo limite mais sua graça de morte de 5 segundos deve ficar abaixo de --expected-spawn-seconds; o orquestrador impõe isso na inicialização. |
--expected-spawn-seconds <sec> |
120 |
Tempo p99 esperado desde o momento em que o orquestrador recebe uma requisição de geração até o momento em que o executor se registra, incluindo qualquer espera por capacidade na sua plataforma. O servidor impõe um intervalo de 10 a 3600. Enviado em cada pesquisa como a concessão do lado do servidor: se nenhum executor se registrar antes de decorrido, a sessão é re-oferecida com um novo ID de pedido. Todas as réplicas devem compartilhar este valor. |
--min-idle <n> |
0 |
Mantenha pelo menos N slots de sessão ociosos livres gerando executores de espera de forma proativa. 0 desabilita pré-aquecimento. Emparelhe com o --exit-if-unused-min do executor para que executores de espera em excesso se recuperem. |
--shutdown-drain-sec <n> |
0 |
Ao receber SIGTERM, pare de pesquisar requisições de geração e dê aos hooks spawn-runner em execução e a qualquer pesquisa não respondida até esse número de segundos para terminar antes de interromper o que restar. Com 0, pare imediatamente. Máximo 3600, que o orquestrador impõe na inicialização. Para escolher um valor, consulte Dimensione --shutdown-drain-sec e o timeout de parada do orquestrador. Requer Claude Code v2.1.299 ou posterior. |
--debug-dir <path> |
não definido | Escreva a ordem de trabalho de cada solicitação de geração e stderr do hook em disco. Apenas depuração; nunca defina em produção. |
Sinalizadores do conector SCM
O conector SCM não está disponível, portanto deixe os sinalizadores nesta seção não definidos. Se você definir --scm-connector-host, a conexão não abre e o orquestrador continua tentando novamente. Os executores ainda iniciam conforme a fila de sessões.
O conector é uma conexão WebSocket permanente do orquestrador para o plano de controle da Anthropic. Ele foi projetado para permitir que fluxos pré-sessão hospedados, como o seletor de repositório e o resolvedor de branch ou ref, alcancem um host GitHub Enterprise Server que é apenas roteável de dentro de sua rede. Consulte Requisitos de rede na página GitHub Enterprise Server para saber o que esses fluxos precisam.
| Sinalizador | Padrão | Descrição |
|---|---|---|
--scm-connector-host <host[:port]> |
não definido | Nome do host GitHub Enterprise Server para encaminhar solicitações. A porta padrão é 443. |
--scm-connector-id <n> |
obrigatório com --scm-connector-host |
O ID numérico da conexão GitHub Enterprise Server da sua organização. |
--scm-connector-provider <slug> |
ghe |
Segmento de caminho identificando o provedor, correspondendo a ^[a-z0-9-]{1,32}$. |
--scm-connector-ca-file <path> |
não definido | Pacote CA extra, em formato PEM, para conexões TLS com o host GitHub Enterprise Server. |
--scm-connector-host-rewrite <from>=<to_host:to_port> |
não definido | Apenas para testes de ponta a ponta: redireciona a conexão TCP mantendo o cabeçalho Host e TLS SNI como --scm-connector-host. |
Em cada tentativa de conexão, o orquestrador envia seu segredo de ambiente existente e tenta novamente automaticamente com backoff exponencial, limitado a 30 segundos mais jitter.
Configurações somente por variável de ambiente
Estas configurações do runner são lidas apenas do ambiente e abrangem comportamentos que a maioria das implantações mantém no padrão:
| Variável de ambiente | Padrão | Descrição |
|---|---|---|
SELF_HOSTED_RUNNER_BG_RESULT_GRACE_MS |
30000 |
Por quanto tempo o runner considera uma sessão ocupada depois que uma tarefa em segundo plano termina enquanto o turno seguinte que lê o resultado ainda não começou. As linhas --drain-wait-sec e --release-idle-session-min descrevem onde essa retenção se aplica na drenagem e na liberação por inatividade, e Ciclo de vida do runner descreve onde ela se aplica na desativação por --retire-at. 0 ou um valor inutilizável volta ao padrão, portanto a retenção não pode ser desativada. Requer Claude Code v2.1.228 ou posterior. |
SELF_HOSTED_RUNNER_HOST_CONFIG_DIR |
~/.claude |
Diretório capturado no snapshot de inicialização do runner e copiado para o CLAUDE_CONFIG_DIR de cada sessão; alterações no disco entram em vigor após reiniciar o runner. Definir a variável também muda o local onde o runner lê .claude.json para a semeadura de MCP, portanto defini-la, inclusive com seu próprio valor padrão, realoca essa busca; aponte para um diretório vazio para desativar a semeadura por completo. |
SELF_HOSTED_RUNNER_MAX_LIFETIME_GRACE_MS |
900000 |
Por quanto tempo o runner aguarda, depois que uma sessão atinge seu limite de --kill-session-after-min, que um turno em execução termine ou que a liberação seja concluída, antes de encerrar a sessão |
SELF_HOSTED_RUNNER_POST_TURN_SETTLE_MS |
7000 |
Limite máximo de quanto tempo o runner considera uma sessão ocupada para a drenagem de --drain-wait-sec depois que um turno termina, enquanto o processo da sessão informa o fim do turno à Anthropic. 0 ou um valor inutilizável volta ao padrão, portanto a retenção não pode ser desativada. Requer Claude Code v2.1.275 ou posterior. |
SELF_HOSTED_RUNNER_SIGKILL_GRACE_MS |
30000 |
Por quanto tempo o runner aguarda que o sistema operacional entregue SIGKILL a um processo filho travado em I/O ininterruptível antes de ele próprio encerrar. Tem como valor mínimo --post-session-hook-timeout-sec mais 15 segundos, e mais 30 quando --push-outcome-on-release está definido, de modo que o mínimo efetivo é de 75 segundos com os valores padrão. |
CLAUDE_RUNNER_FETCH_DEPTH |
50 |
Profundidade do git fetch para clones novos. Defina um número inteiro positivo, ou full ou 0 para um fetch completo. Para um clone que já está no workspace, consulte Reutilizar um checkout pré-aquecido. |
CLAUDE_RUNNER_FETCH_SERVER_PROGRESS_CAP_MS |
600000 |
Por quanto tempo em milissegundos, por tentativa, um git fetch pode aguardar seus primeiros dados enquanto os próprios números de progresso do servidor git continuam aumentando, como quando o servidor prepara o pack para um repositório grande. 0 ou off desativa a espera: esse fetch é então interrompido após dois minutos sem dados. Qualquer outro número inteiro é restringido ao intervalo entre 120000 e 1800000, de 2 a 30 minutos. Requer Claude Code v2.1.295 ou posterior. |
CLAUDE_RUNNER_SKIP_GIT_VERIFY |
não definida | Quando 1, ignora a verificação da presença de .git após a execução de um hook checkout. Defina isso quando seu hook materializar uma fonte que não seja git. |
FORCE_AUTOUPDATE_PLUGINS |
não definida | Quando 1, permite que os marketplaces de plugins sejam atualizados automaticamente mesmo com o binário fixado |
CLAUDE_CODE_DISABLE_ARTIFACT |
não definida | Quando 1, desativa a ferramenta Artifact nas sessões independentemente da configuração de administrador da organização e remove o requisito de saída para *.frame.claudeusercontent.com |
Telemetria
Filhos de sessão enviam telemetria operacional para Anthropic a menos que você a desative. Nenhum código ou conteúdo de repositório é enviado. Defina variáveis de telemetria no processo do executor; o executor as re-afirma após aplicar variáveis de ambiente fornecidas pelo servidor, então a configuração do operador sempre tem precedência.
Um controle é específico para ambientes auto-hospedados: CLAUDE_CODE_BYOC_ENABLE_DATADOG=1 opta por métricas operacionais Datadog, que estão desligadas por padrão em ambientes auto-hospedados. Os controles gerais de telemetria Claude Code, DISABLE_TELEMETRY, DO_NOT_TRACK, DISABLE_ERROR_REPORTING e CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC, se aplicam a filhos de sessão conforme documentado na referência de variável de ambiente. DISABLE_GROWTHBOOK é relacionado mas diferente: definir DISABLE_GROWTHBOOK=1 desabilita a busca de sinalizador de recurso, e a telemetria permanece ativada a menos que DISABLE_TELEMETRY também esteja definido.
CLAUDE_CODE_ENABLE_TELEMETRY não está relacionado: habilita a exportação OpenTelemetry para seu próprio coletor, conforme descrito em Monitoring, e não controla a análise da Anthropic.
Ponto de extremidade de saúde
O executor serve GET /healthz na porta de saúde configurada assim que se registra e conclui suas verificações de inicialização. A partir daí, a resposta é 200 OK sempre que o processo está vivo, seja qual for o estado do loop de pesquisa, então uma sonda HTTP neste endpoint detecta apenas um processo morto. O corpo JSON descreve o estado atual:
{
"status": "ok",
"runner_id": "ccrunner_...",
"active_sessions": 2,
"last_poll_at": "2026-03-31T18:04:11.220Z",
"last_poll_age_ms": 842
}
Configure alertas com base em last_poll_age_ms, mas não o use em uma sonda de vivacidade; mantenha essa sonda no código de status HTTP. O valor é o tempo desde a última pesquisa bem-sucedida, portanto ele também aumenta enquanto o executor não consegue alcançar a Anthropic. Tanto last_poll_at quanto last_poll_age_ms são null até a primeira pesquisa ser bem-sucedida. Para detectar pesquisas que falham desde o início, configure também alertas em claude_code_self_hosted_runner_poll_errors_total, listada em métricas do Prometheus.
O próprio /healthz do orquestrador, em sua porta de saúde, sempre retorna 200. O corpo carrega um campo connected relatando se a pesquisa mais recente foi bem-sucedida, mais contagens de fila de geração por estado em queue_counts. Para ver por que connected é false, leia o campo de nível superior last_error, que cada pesquisa bem-sucedida redefine para null. Controle prontidão e alertas em connected em vez do código de status.
Quando o conector SCM está configurado, o corpo /healthz do orquestrador também carrega scm_connector_connected e um objeto scm_connector com connected, last_connected_at, last_error, reconnects e requests_forwarded. Ambos os campos são null quando --scm-connector-host não está definido.
Métricas do Prometheus
Cada executor serve métricas do Prometheus em GET /metrics na mesma porta que /healthz. Principais séries:
| Série | Observações |
|---|---|
claude_code_self_hosted_runner_info{runner_id,version,client_label} |
Sempre 1; útil para inventário da frota e detecção de divergência de versões |
claude_code_self_hosted_runner_capacity |
--capacity configurado |
claude_code_self_hosted_runner_active_sessions |
Sessões em execução no momento |
claude_code_self_hosted_runner_locked_account{email} |
Presente assim que o executor tiver sido bloqueado para um usuário e um token de sessão contendo uma claim act.email tiver sido emitido. A série fica ausente em um executor bloqueado para um agente Claude Tag, cujos tokens de sessão não contêm act.email. O valor do rótulo é o e-mail da conta; se o seu armazenamento de métricas for amplamente legível, descarte ou aplique hash ao rótulo no momento da coleta, por exemplo com metric_relabel_configs do Prometheus. |
claude_code_self_hosted_runner_last_poll_age_seconds |
Segundos desde o último polling bem-sucedido. Alerte se for superior a 60. |
claude_code_self_hosted_runner_poll_errors_total{error_kind} |
Falhas cumulativas de PollWork por tipo: transport, timeout, 5xx, 429 ou 4xx. Todas as cinco séries estão presentes desde o início do processo; alerte em rate(...[5m]) > 0. |
claude_code_self_hosted_runner_sessions_started_total{client_platform} |
Processos filhos de sessão iniciados ao longo da vida útil do executor, uma série por origem de sessão, como web_claude_ai, ios, android, desktop_app ou claude_code_cli, ou unknown quando o servidor não enviou nenhuma. Sessões do Slack têm claude_in_slack ou claude-in-slack, dependendo de qual integração do Slack as criou, portanto capture ambas com um seletor de regex como {client_platform=~"claude[-_]in[-_]slack"}. Use sum() para o total da frota. |
claude_code_self_hosted_runner_sessions_completed_total{client_platform} |
Sessões que terminaram de forma limpa, rotuladas da mesma forma. Mais abrangente do que uma simples saída limpa: consulte semântica dos contadores do ciclo de vida da sessão para saber o que é contado. |
claude_code_self_hosted_runner_sessions_failed_total{client_platform} |
Sessões que terminaram em falha, rotuladas da mesma forma. Mesma ressalva: consulte semântica dos contadores do ciclo de vida da sessão. |
claude_code_self_hosted_runner_sessions_interrupted_total{client_platform} |
Sessões que o executor encerrou por um motivo operacional, e não por um resultado da sessão, rotuladas da mesma forma. Consulte semântica dos contadores do ciclo de vida da sessão. |
claude_code_self_hosted_runner_initializing_sessions |
Sessões atualmente na fase de inicialização, desde a atribuição até o evento de inicialização do processo filho |
claude_code_self_hosted_runner_session_init_duration_seconds |
Histograma das durações de inicialização de sessão |
claude_code_self_hosted_runner_session_init_errors_total |
Sessões que falharam antes de chegar à inicialização: uma falha de hook de checkout, preparação do git, problema de token ou uma falha do processo filho antes da inicialização |
claude_code_self_hosted_runner_session_start_hook_errors_total |
Hooks SessionStart que relataram um resultado de erro, um por execução de hook com falha |
claude_code_self_hosted_runner_session_idle_seconds{session_id,client_platform} |
Gauge por sessão dos segundos desde que a sessão ficou ociosa. Útil para encerrar sessões presas em um prompt de permissão não respondido. |
O orquestrador serve suas próprias séries em GET /metrics na mesma porta que seu /healthz:
| Série | Observações |
|---|---|
claude_code_self_hosted_orchestrator_info{version,pool_id,orchestrator_uuid,hostname} |
Sempre 1 |
claude_code_self_hosted_orchestrator_connected |
1 quando o polling mais recente foi bem-sucedido; cai para 0 após qualquer polling com falha, qualquer que seja o tipo de falha |
claude_code_self_hosted_orchestrator_last_poll_age_seconds |
Segundos desde a última tentativa de polling, com sucesso ou falha, diferentemente da métrica de nome idêntico do executor, que mede desde o último sucesso; combine com connected para detectar pollings com falha. O loop de polling do orquestrador aguarda a execução de hooks, então alerte acima de --hook-timeout mais uma margem, cerca de 90 segundos com os padrões, em vez de um valor fixo de 60. |
claude_code_self_hosted_orchestrator_poll_errors_total{error_kind} |
Falhas cumulativas de PollSpawnHints por tipo: transport, timeout, 5xx, 429 ou 4xx. Todas as cinco séries estão presentes desde o início do processo; alerte em rate(...[5m]) > 0. |
claude_code_self_hosted_orchestrator_queue_pending_sessions |
Requisições de inicialização que podem ser reivindicadas agora |
claude_code_self_hosted_orchestrator_queue_backing_off_sessions |
Requisições de inicialização em backoff de retry após uma falha de hook que permite nova tentativa |
claude_code_self_hosted_orchestrator_queue_circuit_broken_sessions |
Sessões impedidas de serem iniciadas. Cada uma permanece bloqueada até que um usuário envie uma nova mensagem a ela ou que um Owner tente novamente a partir da guia Activity do ambiente. A contagem pode permanecer acima de zero depois que você corrigir a causa. Alerte se for superior a zero. |
claude_code_self_hosted_orchestrator_pool_pending_sessions |
Total de sessões aguardando um executor para este ambiente. Agregado de todo o ambiente, idêntico em todas as instâncias do orquestrador: use MAX em vez de SUM entre as instâncias. |
claude_code_self_hosted_orchestrator_pool_active_sessions |
Sessões atualmente atribuídas a um executor ativo neste ambiente. Agregado de todo o ambiente, idêntico em todas as instâncias do orquestrador: use MAX em vez de SUM entre as instâncias. |
claude_code_self_hosted_orchestrator_spawn_hooks_total{result} |
Resultados cumulativos do hook spawn-runner: ok, retryable, non_retryable. Conta invocações de hook do orquestrador, não processos filhos de sessão que os executores iniciam: não é comparável a sessions_started_total, pois capacidade acima de um, pools pré-aquecidos e executores iniciados novamente para a mesma sessão fazem os dois divergirem. |
claude_code_self_hosted_orchestrator_spawn_hook_duration_seconds |
Histograma das durações de hooks |
claude_code_self_hosted_orchestrator_warm_hints_dispatched_total |
Requisições de inicialização em standby despachadas desde o início do processo |
claude_code_self_hosted_orchestrator_session_queue_wait_seconds |
Histograma dos segundos que cada sessão aguardou na fila antes de o orquestrador reivindicá-la para inicialização, registrado a partir do timestamp de espera na fila que o plano de controle envia com a requisição de inicialização de cada sessão. Use para alertas de tempo de fila p50/p99. Inicializações de pré-aquecimento não são amostradas. |
claude_code_self_hosted_orchestrator_clock_skew_seconds |
Desvio de relógio local menos servidor; diagnóstico, presente assim que medido |
claude_code_self_hosted_orchestrator_scm_connector_connected |
1 quando o WebSocket do conector SCM está aberto; 0 enquanto está discando ou em backoff. Ausente quando --scm-connector-host não está definido. |
claude_code_self_hosted_orchestrator_scm_connector_requests_forwarded_total |
Requisições HTTP cumulativas encaminhadas via proxy para o host SCM configurado desde o início do processo. Ausente quando --scm-connector-host não está definido. |
Para autoscaling, escolha a série que corresponde ao seu estilo de escalonamento e aplique um filtro antes que ela alimente o escalonador:
- Escalonamento por profundidade da fila: alimente seu escalonador HPA ou KEDA com
claude_code_self_hosted_orchestrator_pool_pending_sessions, não comqueue_pending_sessions. - Escalonamento por capacidade: escalone com base na razão entre
active_sessionsecapacitydo executor. - Filtre por
connected: filtre a consulta comclaude_code_self_hosted_orchestrator_connected == 1por instância, para que o valor desatualizado de uma réplica desconectada não alimente o escalonador.
Durante uma interrupção total do polling, com todas as réplicas desconectadas, a consulta filtrada não retorna dados. O HPA mantém a contagem atual de réplicas quando uma métrica está ausente, mas o escalonador Prometheus do KEDA, com seu padrão ignoreNullValues: "true", lê o resultado vazio como zero e reduz a escala; defina ignoreNullValues: "false" no ScaledObject, opcionalmente com um piso de réplicas de fallback.
O PodMonitor do Prometheus Operator a seguir abrange ambos os processos. Ele seleciona pods pelo rótulo app.kubernetes.io/part-of: claude-code-self-hosted-runner e pela porta nomeada health que a receita do Kubernetes define; ajuste os namespaces para corresponder à sua implantação:
# Exemplo de PodMonitor do Prometheus Operator para o executor auto-hospedado
# + orquestrador do Claude Code. Ajuste o namespace e os seletores de rótulos para
# corresponder à sua implantação. Tanto o executor quanto o orquestrador servem /metrics
# em sua --health-port (padrão 8080).
apiVersion: monitoring.coreos.com/v1
kind: PodMonitor
metadata:
name: claude-code-self-hosted-runner
namespace: monitoring
spec:
namespaceSelector:
matchNames:
- claude-runners
selector:
matchExpressions:
# Corresponde ao Deployment do executor da receita do Kubernetes, além de
# quaisquer Jobs de executor sob demanda e pods do orquestrador que você rotule
# da mesma forma e aos quais atribua uma containerPort nomeada 'health'.
- key: app.kubernetes.io/part-of
operator: In
values: [claude-code-self-hosted-runner]
podMetricsEndpoints:
- port: health
path: /metrics
interval: 30s
Exemplos de regras de alerta
Estes exemplos de regras de alerta são um ponto de partida; ajuste os limites para o tamanho da sua frota:
# Exemplos de regras de alerta do Prometheus para o executor auto-hospedado
# + orquestrador do Claude Code. Ajuste os limites para o tamanho da sua frota e 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: sum by (namespace) (increase(claude_code_self_hosted_runner_session_init_errors_total[10m])) > 3
for: 5m
labels: {severity: warning}
annotations:
summary: "Sessions are failing before init (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: sum by (namespace) (increase(claude_code_self_hosted_runner_session_start_hook_errors_total[10m])) > 3
for: 5m
labels: {severity: warning}
annotations:
summary: "SessionStart hooks are failing"
- 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: 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
for: 1m
labels: {severity: critical}
annotations:
summary: "Sessions blocked from spawning: {{ $value }}. Read each one's error in the Activity tab, fix the cause, then select Retry"
- 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"
Alertar sobre executores perdidos e sessões em espera
Para ser alertado quando executores forem perdidos, sessões estiverem aguardando ou o orquestrador estiver fora do ar, carregue estas regras de alerta do Prometheus junto com os exemplos de regras de alerta:
- Frota fixa:
ClaudeRunnersBelowFloor - Executores sob demanda:
ClaudeOrchestratorSessionsWaiting,ClaudeOrchestratorQueueWaitHigheClaudeOrchestratorAbsent
Alertar quando uma frota fixa perde executores
ClaudeRunnersBelowFloor dispara quando restam menos executores registrados e coletados do que o piso por 10 minutos:
groups:
# Apenas frotas fixas. Com executores sob demanda, a contagem acompanha a demanda,
# então ClaudeRunnersBelowFloor dispararia sempre que a demanda estivesse baixa.
- name: claude-code-self-hosted-fixed-fleet-capacity
rules:
- alert: ClaudeRunnersBelowFloor
expr: (count(claude_code_self_hosted_runner_info{namespace="claude-runners"}) or vector(0)) < 2
for: 10m
labels: {severity: critical, namespace: claude-runners}
annotations:
summary: "Runners registered and scraped: {{ $value }}, below the floor. Check the runner workloads first, then the scrape targets if all are running."
- Piso: defina o
2emexprcomo cerca de metade da sua contagem de réplicas, arredondada para cima. Com três réplicas, mantenha2, e o alerta dispara quando resta um executor ou nenhum. - Namespace: substitua
claude-runnersno matcher e emlabels, e copie o alerta para cada namespace adicional. Se seus alvos não tiverem rótulonamespace, remova o matcher e o rótulo, ou o alerta lerá 0 e disparará. ClaudeRunnerPollStaleeClaudeRunnerPollErrors: mantenha-os carregados a partir dos exemplos de regras de alerta, porqueClaudeRunnersBelowFloorainda conta um executor que não consegue fazer polling
Alertar quando sessões aguardam executores sob demanda
ClaudeOrchestratorSessionsWaiting dispara quando o número de sessões aguardando um executor permanece acima de 0 por 10 minutos. ClaudeOrchestratorQueueWaitHigh dispara quando mais de 1% das esperas na fila nos últimos 10 minutos excederam 160 segundos, e isso se mantém por 5 minutos:
groups:
# Apenas executores sob demanda. Não precisa de edição para o namespace.
- name: claude-code-self-hosted-on-demand-capacity
rules:
- alert: ClaudeOrchestratorSessionsWaiting
expr: |
max by (namespace) (
claude_code_self_hosted_orchestrator_pool_pending_sessions
and on (instance)
max_over_time(claude_code_self_hosted_orchestrator_connected[2m]) == 1
) > 0
for: 10m
labels: {severity: warning}
annotations:
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."
- alert: ClaudeOrchestratorQueueWaitHigh
expr: |
histogram_quantile(0.99, sum by (namespace, le) (
rate(claude_code_self_hosted_orchestrator_session_queue_wait_seconds_bucket[10m])
)) > 160
for: 5m
labels: {severity: warning}
annotations:
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."
- Limite: se alguma sessão estiver sempre aguardando, aumente o
> 0emClaudeOrchestratorSessionsWaitingpara acima do número que você costuma ver ClaudeOrchestratorDisconnected: mantenha-o carregado a partir dos exemplos de regras de alerta, porqueClaudeOrchestratorSessionsWaitingpara de disparar cerca de 2 minutos depois que o último orquestrador no namespace se desconecta
Alertar quando o orquestrador está fora do ar
Para saber quando o próprio orquestrador está fora do ar, carregue ClaudeOrchestratorAbsent. Ele dispara quando nenhum orquestrador no namespace foi coletado por 5 minutos:
groups:
# Apenas executores sob demanda. Substitua claude-runners pelo namespace do orquestrador.
- name: claude-code-self-hosted-on-demand-orchestrator
rules:
- alert: ClaudeOrchestratorAbsent
expr: absent(claude_code_self_hosted_orchestrator_connected{namespace="claude-runners"})
for: 5m
labels: {severity: critical}
annotations:
summary: "No orchestrator has been scraped for 5 minutes. If it's down, no on-demand runner starts, and sessions wait. Check the orchestrator workload first, then its scrape target if it's running."
- Namespace: substitua
claude-runnerspelo namespace do orquestrador e copie o alerta para cada namespace adicional que executa um orquestrador. Se seus alvos não tiverem rótulonamespace, remova o matcher, ou o alerta disparará após 5 minutos e permanecerá ativo. - Servidores Prometheus que não coletam o orquestrador: deixe o alerta de fora dos arquivos de regras deles, porque em um servidor desse tipo ele dispara após 5 minutos e permanece ativo
- Não dependa dos outros alertas do orquestrador: eles leem métricas que o próprio orquestrador serve.
ClaudeOrchestratorSessionsWaiting,ClaudeOrchestratorQueueWaitHighe os exemplos de regras de alerta do orquestrador param de disparar em cerca de 10 minutos após o orquestrador ficar fora do ar.
Repassar métricas dos processos filhos de sessão
Cada sessão é executada em seu próprio processo filho com suas próprias métricas do OpenTelemetry; com --capacity acima de um, o executor reescreve a forma como essas métricas dos processos filhos são expostas. Definir OTEL_METRICS_EXPORTER=prometheus no host do executor e CLAUDE_CODE_ENABLE_TELEMETRY=1 no ambiente da sessão, por exemplo a partir do seu script wrapper ou do próprio ambiente do executor, que as sessões herdam, reexpõe os instrumentos de counter e gauge de cada processo filho no próprio endpoint /metrics do executor, junto com as séries do executor. O executor reescreve o exportador do processo filho para enviar via OTLP a um receptor somente de loopback na porta de health, marca cada série com os rótulos session_id e client_platform e remove as séries de uma sessão quando essa sessão termina. Histogramas não são repassados, e uma métrica de processo filho cujo nome colidiria com o prefixo próprio do executor é descartada.
Com o padrão --capacity 1, a reescrita não se aplica: o processo filho da sessão vincula seu próprio endpoint do Prometheus na porta 9464, como de costume.
Unir as métricas de uma sessão às do executor
Para ver quanto as sessões ociosas custaram, una a claude_code_self_hosted_runner_session_idle_seconds do executor à métrica de custo do Claude Code em ccr_session_id. A métrica do executor não tem esse rótulo, então atribua um a ela com label_replace, como nesta consulta:
sum by (ccr_session_id) (claude_code_cost_usage_total)
and on (ccr_session_id)
label_replace(
claude_code_self_hosted_runner_session_idle_seconds > 600,
"ccr_session_id", "cse_$1", "session_id", "session_(.*)"
)
A consulta retorna um resultado por sessão ociosa há mais de dez minutos: o custo em dólares americanos que seu processo do Claude Code contabilizou até agora. Para unir outra métrica do Claude Code, substitua claude_code_cost_usage_total na consulta. A consulta funciona com qualquer --capacity.
session_id: na porta 9464, esse rótulo nas métricas do Claude Code contém o própriosession.iddo Claude Code, que não corresponde a nenhuma série do executor. Uma união por ele não retorna nada, então una porccr_session_id.- As métricas do Claude Code não têm
ccr_session_id: verifique seOTEL_METRICS_INCLUDE_SESSION_IDnão está definido comofalse
Semântica dos contadores do ciclo de vida da sessão
Os contadores sessions_started_total, sessions_completed_total, sessions_failed_total e sessions_interrupted_total classificam cada sessão pela forma como ela terminou. Cada processo filho de sessão iniciado incrementa sessions_started_total no momento da inicialização, e exatamente um dos outros três é incrementado na saída, então sessions_started_total menos a soma dos outros três é igual ao número de processos filhos de sessão em execução no momento.
completed: a sessão terminou de forma limpa. Isso abrange o processo filho saindo por conta própria com código0, a sessão sendo arquivada ou excluída enquanto o processo filho ainda estava conectado, e o executor devolvendo o slot de forma limpa: liberando a sessão no timeout de ociosidade, no horário de aposentadoria ou no limite de--kill-session-after-min; um timeout de inicialização; ou uma desatribuição do lado do servidor que o loop de polling percebeu antes de o processo filho sair. Incrementasessions_completed_total.failed: o processo filho saiu por conta própria com um código diferente de zero, seja uma falha ou uma falha de configuração após a inicialização. Incrementasessions_failed_total.interrupted: o executor encerrou o processo filho por um motivo operacional que não é nem um sucesso da sessão nem uma falha do executor, como um drain, ou o encerramento de uma sessão que ainda estava no executor quando a janela de tolerânciaSELF_HOSTED_RUNNER_MAX_LIFETIME_GRACE_MSapós seu limite de--kill-session-after-minterminou. Um reinício gradual do Kubernetes enviandoSIGTERMé um exemplo de drain. Incrementasessions_interrupted_total.
Antes da v2.1.260, o executor encerrava toda sessão que atingia seu limite de --kill-session-after-min e a contava em sessions_interrupted_total.
O CLAUDE_RUNNER_EXIT_REASON do hook post-session classifica as devoluções limpas de forma diferente. O hook as relata como interrupted, porque o executor interrompeu o processo filho: uma liberação, um timeout de inicialização, uma desatribuição do servidor e um arquivamento ou exclusão que o polling percebeu primeiro. Esses contadores registram os mesmos eventos como completed, porque o slot foi devolvido de forma limpa.
Se você reconciliar os recebimentos do hook diretamente com sessions_completed_total, contará menos conclusões do que as reais. Use o hook para garantias por sessão e os contadores para taxas agregadas.
Em um ambiente de uso único, --capacity 1 com o padrão --drain-grace-sec 0, cada processo do executor sai momentos depois que sua única sessão termina. sessions_completed_total, sessions_failed_total e sessions_interrupted_total são incrementados apenas no fim da sessão, logo antes dessa saída, então uma coleta do Prometheus a cada 15 a 60 segundos raramente captura o incremento antes que as séries do executor desapareçam; esses três contadores de fim de sessão são os contadores terminais aos quais o restante desta seção se refere. sessions_started_total é incrementado na inicialização e permanece visível durante toda a vida da sessão, então aparece de forma confiável, mas em um ambiente de uso único ele se aproxima mais de "sessões em execução no momento" do que de uma contagem cumulativa.
Use as séries desta tabela para o objetivo correspondente em vez dos contadores terminais:
| Objetivo | Use |
|---|---|
| Throughput | claude_code_self_hosted_orchestrator_spawn_hooks_total{result="ok"}, um counter no orquestrador de longa duração que é incrementado uma vez por hook spawn-runner bem-sucedido e permanece significativo sob rate(). Ele conta invocações de hook em vez de sessões, então pré-aquecimento e inicializações repetidas para a mesma sessão o fazem divergir das contagens de sessão. |
| Utilização | sum(claude_code_self_hosted_runner_active_sessions) em relação a sum(claude_code_self_hosted_runner_capacity), ambos gauges válidos em cada coleta, independentemente da vida útil do executor |
| Backlog | claude_code_self_hosted_orchestrator_pool_pending_sessions para a profundidade da fila, e claude_code_self_hosted_orchestrator_queue_circuit_broken_sessions, alertando se for superior a zero |
| Falhas | claude_code_self_hosted_runner_sessions_failed_total, na base do melhor esforço: falhas reais após a inicialização o incrementam, e rate() é significativo em executores que sobrevivem às suas sessões com --drain-grace-sec acima de 0. Um ambiente de uso único tem o mesmo problema de janela de coleta que os outros contadores terminais, então trate qualquer valor diferente de zero que você observar como algo que vale a pena investigar. Falhas antes da inicialização, como uma falha de hook de checkout, preparação do git ou um problema de token, aparecem apenas em session_init_errors_total. |
As linhas orchestrator_* existem apenas em ambientes que executam o orquestrador sob demanda. Em uma frota fixa cujos executores sobrevivem às suas sessões, com --drain-grace-sec acima de 0, use sum(rate(claude_code_self_hosted_runner_sessions_started_total[5m])) para throughput; em uma frota de uso único, essa série tem o mesmo problema de janela de coleta que os contadores terminais, então dependa da contagem de sessões enfileiradas. Verifique o backlog na guia Activity do ambiente, na página de administração Cloud environments: os executores não exportam uma série de profundidade de fila.
Para relatórios de resultado por sessão, use o hook post-session: ele dispara em todo fim de sessão em que um processo filho foi iniciado, exceto em um encerramento abrupto do executor, como uma preempção de VM, conforme o contrato do próprio hook.
Próximos passos
- Self-hosted environments: o ambiente, executor e modelo de sessão; o guia de início rápido e Deploy to production contêm configuração e operações
- Customize sessions: scripts wrapper, hooks de ciclo de vida e executores sob demanda
- Verify session identity: o token de sessão, suas reivindicações e como verificá-lo