SpyBara
Go Premium

self-hosted-environments-reference.md 2026-11-11 22:59 UTC to 2026-11-12 21:00 UTC

No changes for this document in this history range.

2026
Tue 3 23:58 Thu 5 23:03 Mon 9 23:02 Tue 10 21:57 Wed 11 22:59

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ção allow se aplique.
  • allow: as exceções às entradas soft_deny.

O valor da flag escolhe quais listas o executor aplica:

  • no-allow: o padrão. Aplica environment e soft_deny e retém allow. Uma entrada environment ainda 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. Escolha none para descartar todo afrouxamento vindo dessas listas. Isso também remove as restrições de soft_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_DISABLE_RENEWAL_WARNING não definida Quando 1, o runner não publica The server has refused to renew this session's access to the model em uma sessão. Após cada recusa, ele aguarda até a próxima renovação agendada para solicitar novamente. Requer Claude Code v2.1.319 ou posterior.
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. CLAUDE_CODE_DISABLE_FEATURE_FLAGS é relacionado mas diferente: definir CLAUDE_CODE_DISABLE_FEATURE_FLAGS=1 desabilita a busca de sinalizador de recurso, e a telemetria permanece ativada a menos que DISABLE_TELEMETRY também esteja definido. CLAUDE_CODE_DISABLE_FEATURE_FLAGS requer Claude Code v2.1.319 ou posterior.

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 com queue_pending_sessions.
  • Escalonamento por capacidade: escalone com base na razão entre active_sessions e capacity do executor.
  • Filtre por connected: filtre a consulta com claude_code_self_hosted_orchestrator_connected == 1 por 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:

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 2 em expr como cerca de metade da sua contagem de réplicas, arredondada para cima. Com três réplicas, mantenha 2, e o alerta dispara quando resta um executor ou nenhum.
  • Namespace: substitua claude-runners no matcher e em labels, e copie o alerta para cada namespace adicional. Se seus alvos não tiverem rótulo namespace, remova o matcher e o rótulo, ou o alerta lerá 0 e disparará.
  • ClaudeRunnerPollStale e ClaudeRunnerPollErrors: mantenha-os carregados a partir dos exemplos de regras de alerta, porque ClaudeRunnersBelowFloor ainda 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 > 0 em ClaudeOrchestratorSessionsWaiting para acima do número que você costuma ver
  • ClaudeOrchestratorDisconnected: mantenha-o carregado a partir dos exemplos de regras de alerta, porque ClaudeOrchestratorSessionsWaiting para 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-runners pelo namespace do orquestrador e copie o alerta para cada namespace adicional que executa um orquestrador. Se seus alvos não tiverem rótulo namespace, 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, ClaudeOrchestratorQueueWaitHigh e 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óprio session.id do Claude Code, que não corresponde a nenhuma série do executor. Uma união por ele não retorna nada, então una por ccr_session_id.
  • As métricas do Claude Code não têm ccr_session_id: verifique se OTEL_METRICS_INCLUDE_SESSION_ID não está definido como false

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ódigo 0, 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. Incrementa sessions_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. Incrementa sessions_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ância SELF_HOSTED_RUNNER_MAX_LIFETIME_GRACE_MS após seu limite de --kill-session-after-min terminou. Um reinício gradual do Kubernetes enviando SIGTERM é um exemplo de drain. Incrementa sessions_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