/<org-slug>/…, e o stream de eventos é a página inicial da organização (/<org-slug>/). Os nomes de páginas neste guia (por exemplo, /sessions, /queries) referem-se a essas rotas com escopo de organização.
Visualizando Logs
O AgentEye não inclui uma pilha de logging ou monitoramento. Tanto o servidor quanto o painel escrevem logs estruturados no stdout, para que você possa lê-los diretamente comkubectl ou docker; nenhum agregador é necessário.
Kubernetes
Acompanhe os logs ao vivo do servidor e do painel:| Objetivo | Comando |
|---|---|
| Últimas 200 linhas (sem acompanhamento) | kubectl logs -n agenteye -l app=server --tail=200 --timestamps |
| Logs da falha anterior | kubectl logs -n agenteye <pod-name> --previous |
| Acompanhar todas as réplicas ao mesmo tempo | kubectl logs -n agenteye -l app=server --max-log-requests=10 -f |
| Postgres (StatefulSet) | kubectl logs -n agenteye postgres-0 -f |
Docker Compose
Correlacionando uma única requisição entre painel e servidor
Cada requisição do painel é marcada com umrequest_id e propagada ao servidor via cabeçalho x-request-id. O servidor o ecoa nos cabeçalhos de resposta e em cada linha de log emitida para aquela requisição. Para rastrear uma requisição de ponta a ponta:
- Capture o id do cabeçalho de resposta, por exemplo:
- Busque nos logs de ambos os pods esse id:
proxy passthrough, withAuth: authorized e upstream response do painel junto com o par http request received / http request completed do servidor, todos compartilhando o mesmo request_id.
Logs JSON e jq
Defina AE_LOG_JSON=1 no painel (ativado por padrão quando NODE_ENV=production) para emitir um objeto JSON por linha. Então filtre estruturalmente:
key=value de tracing que funcionam bem com grep sem jq:
Aumentando a verbosidade
| Componente | Variável de ambiente | Exemplo |
|---|---|---|
| Servidor | RUST_LOG | RUST_LOG=debug ou RUST_LOG=agenteye_server=debug,info |
| Painel | AE_LOG_LEVEL | AE_LOG_LEVEL=debug |
debug no servidor adiciona uma linha api key authenticated por autenticação. debug no painel adiciona linhas upstream request, session validated e proxy passthrough.
Retenção de logs
O stdout do container é efêmero; o kubelet rotaciona os arquivos de log (padrão ~10 MiB por container) e mantém uma quantidade pequena em disco. Uma vez que o pod é excluído, os logs são perdidos. Se você precisar de retenção mais longa ou busca entre pods, aponte seu cluster para um coletor de logs (Loki, CloudWatch, Cloud Logging, Datadog, etc.) que monitore/var/log/containers/. O AgentEye não exige nem prescreve nenhuma escolha específica.
Problemas de Autenticação
docker pull falha com “unauthorized”
Certifique-se de ter autenticado o Docker no GHCR com seu AGENTEYE_TOKEN:
read:packages na organização agenteye-enterprise. Entre em contato com support@exosphere.host se seu token não funcionar.
gh release download retorna 404 ou 401
- Confirme que
AGENTEYE_TOKENestá exportado no seu shell:echo $AGENTEYE_TOKEN - Confirme que você está usando
GITHUB_TOKEN=$AGENTEYE_TOKEN gh release download ...(a CLIghlêGITHUB_TOKEN) - O token precisa de
contents:reademagenteye-enterprise/releases
Problemas no Servidor
Servidor falha com “invalid port number”
OPOSTGRES_PASSWORD (ou outra credencial) contém caracteres especiais para URL (/, +, =) que quebram a análise de DATABASE_URL. Regenere a senha usando codificação hexadecimal:
.env para Docker Compose) e reinicie o servidor. Veja os passos completos em enterprise-docs/kubernetes-deployment.md § “PostgreSQL credentials”.
Servidor encerra imediatamente na inicialização
Verifique os logs do container:DATABASE_URLnão definido ou malformado: o servidor registrará o erro e encerrará.- Postgres inacessível: confirme que o container do Postgres ou banco de dados gerenciado está em execução e que o host/porta estão corretos.
- Migrações falharam: verifique os logs por erros SQL.
GET /health retorna não-200 ou expira
O servidor pode ainda estar executando migrações na primeira inicialização. Aguarde alguns segundos e tente novamente:
docker logs agenteye-server por erros.
GET /ready retorna 503
/ready é a sonda de prontidão: retorna 503 quando o servidor não consegue alcançar Postgres ou ClickHouse. O corpo identifica a dependência com falha:
down: o pod do ClickHouse/Postgres está Running? O CLICKHOUSE_URL / DATABASE_URL está correto e acessível? No Kubernetes, o pod fica como NotReady até que /ready se recupere; isso é esperado e é exatamente o sinal que o monitoramento de saúde alerta. Redis nunca é causa: é reportado, mas não falha a prontidão.
Coletor retorna 401 Unauthorized
A chave de API do coletor não tem permissãoevents:add, ou a chave foi desativada. Crie uma nova chave com a permissão correta:
Requisições autenticadas ficaram lentas de repente (~200ms em vez de ~5ms)
Este é o sintoma de o Redis estar fora do ar enquantoREDIS_URL está definido. Cada chamada ao cache expira após 100ms e recai no Postgres; nos caminhos de autenticação e OTP, a requisição faz duas dessas recaídas.
Confirme nos logs do servidor:
redis-cli -h <your-redis> pingpara confirmar que o Redis está acessível na rede do cluster.- Se o Redis ficou brevemente fora do ar e voltou, reinicie os pods do servidor. O
redis::aio::ConnectionManagernão reestabelece de forma confiável após a queda da conexão subjacente; uma reinicialização do pod retoma a nova conexão de forma limpa. O mesmo se aplica ao painel. - Se você não quer executar o Redis agora, remova
REDIS_URLdo deployment e reinicie. Ambos os serviços funcionam sem o cache (a correção é preservada; a latência volta à linha de base pré-Redis).
Servidor reporta OTP request rate-limited nos logs, mas o usuário diz que tentou apenas uma vez
Verifique se o Redis estava inacessível. O caminho de fallback usa SELECT COUNT(*) FROM otp_codes WHERE created_at > now() - interval '15 minutes', que vê linhas de OTP geradas anteriormente. Se o usuário ficou clicando em “Reenviar” por uma hora, a janela de 15 minutos ainda pode conter ≥5 códigos. Resolva aguardando a janela expirar ou execute DELETE FROM otp_codes WHERE user_id = $1 AND created_at > now() - interval '15 minutes' (console do operador).
Alterei ALLOWED_EMAILS / SESSION_TTL_SECS / OTP_TTL_SECS e reiniciei; nada mudou
Essas variáveis de ambiente são sementes apenas da primeira inicialização. Uma vez que a tabela settings tem uma linha para a chave correspondente, essa linha é a fonte de verdade; a variável de ambiente é lida uma vez na primeira inicialização e ignorada em todas as reinicializações subsequentes.
Para alterá-las após a primeira inicialização, faça login no painel e edite-as em /settings. A alteração se aplica em segundos em todas as réplicas; sem necessidade de reinicialização.
Se você precisar forçar uma re-semeação a partir do env (raro, tipicamente útil apenas em desenvolvimento), DELETE FROM settings WHERE key = '<key>' e reinicie o servidor. O bootstrap captará o valor atual da variável de ambiente na próxima inicialização. Editar via /settings é o caminho suportado em produção.
Problemas no Coletor
Coletor inicia, mas os eventos não aparecem no painel
- Confirme que o coletor está em execução:
systemctl status agenteye-collector(Linux) ou verifique o processo. - Confirme que
AGENTEYE_URLaponta parahttp(s)://your-server-host:8080/events(observe: o caminho/events). - Execute um flush único para ver a saída imediata:
- Verifique que o Python SDK está de fato escrevendo arquivos:
ls ${AGENTEYE_HOME:-~/.agenteye}/events/ - Se existirem arquivos em
${AGENTEYE_HOME:-~/.agenteye}/failed/, os uploads estão falhando. Verifique os logs do coletor pelo erro, provavelmente um 4xx (chave incorreta ou URL) ou problema de rede.
Arquivos estão acumulando em $AGENTEYE_HOME/events/ e não estão sendo enviados
- O coletor pode não estar em execução. Inicie-o:
agenteye-collector start; ele automaticamente faz o flush de eventos pré-existentes na inicialização. - Verifique a saúde do coletor:
agenteye-collector health - O coletor pode estar em execução, mas incapaz de alcançar o servidor. Verifique as regras de firewall entre os hosts do coletor e do servidor.
Arquivos em $AGENTEYE_HOME/failed/
Os arquivos são movidos para failed/ após todas as tentativas de retry serem esgotadas (padrão: 5 tentativas com backoff exponencial). Isso significa:
- O servidor retornou um erro 4xx (chave incorreta, URL errada ou problema de payload)
- O servidor estava inacessível durante toda a janela de retry
Coletor reporta network error em cada upload (falha no handshake TLS)
Se curl -k contra AGENTEYE_URL funciona, mas o binário do coletor falha em cada upload com error sending request for url (...), o servidor AgentEye está apresentando um certificado TLS que não foi assinado por uma CA de confiança pública.
O caminho de produção é o hostname ACME de ingestão configurado em deploy/base/certificates/domain.env (veja kubernetes-deployment.md Fases 3.1 / 4.2). Uma vez que INGEST_DOMAIN resolve para o LB público do Traefik e o cert-manager emitiu o certificado Let’s Encrypt, os coletores verificam o certificado do servidor contra o store de confiança do sistema sem necessidade de AGENTEYE_TLS_CA; remova-o da sua configuração do coletor se foi definido para um deployment antigo com certificado autoassinado.
Sintoma: o coletor funcionava ontem, falha hoje após uma lacuna de ~90 dias. Isso significa que o deployment ainda usa o emissor legado selfsigned para ingest-tls. O certificado de 90 dias foi rotacionado e o arquivo de CA fixado está desatualizado. Corrija permanentemente mudando o cluster para o emissor ACME (Fase 3.1 do guia de deployment). Desbloqueio de curto prazo: re-extraia o certificado atual do servidor e atualize AGENTEYE_TLS_CA:
AGENTEYE_TLS_CA adiciona uma âncora de confiança adicional; as raízes públicas padrão ainda são confiáveis.
Certificado ingest-tls está preso em Ready: False após o deploy
Events e o Order / Challenge referenciado. Causas comuns:
- DNS não resolvendo para o LB público. O validador HTTP-01 não consegue alcançar
INGEST_DOMAIN. Verifique comdig +short INGEST_DOMAIN; deve resolver para o mesmo endereço que oEXTERNAL-IPdo LoadBalancertraefik-public. O cert-manager retenta automaticamente quando o DNS se propaga; não é necessário excluir o Certificate. - Porta 80 bloqueada no load balancer / security group. HTTP-01 requer que a porta 80 seja acessível pelos validadores públicos do Let’s Encrypt. Se você tem um WAF ou SG restringindo
:80, abra-o (a configuração do Traefik redireciona para HTTPS, mas o Boulder segue o redirecionamento e aceita a resposta). dnsNamesnão substituídos. Sekubectl get certificate ingest-tls -n agenteye -o jsonpath='{.spec.dnsNames}'mostrarINGEST_DOMAIN_PLACEHOLDER, você pulou a etapa dodomain.env; crie-o a partir dedomain.env.examplee reaplique.- Rate limiting pelo Let’s Encrypt. Ordens repetidas com falha para o mesmo hostname ativam os limites de certificado duplicado ou validação falhada. Aguarde pelo menos uma hora antes de tentar novamente; verifique o status do Order pela mensagem exata de rate limit.
Certificado dashboard-tls está preso em Ready: False / o navegador ainda mostra um aviso
Mesmo fluxo de diagnóstico que ingest-tls acima (kubectl describe certificate dashboard-tls -n agenteye); as causas de DNS, porta 80, placeholder e rate limit se aplicam, mais duas específicas do painel:
DASHBOARD_DOMAINresolve para o LoadBalancer errado. Deve apontar para o LB do Traefik do painel, não o de ingestão pública. Executedig +shortno hostname e compare com o endereço do LB do painel.- A instância Traefik do painel não consegue servir o desafio. Deve ser instalada com o arquivo de valores do painel incluído, que habilita um provedor Ingress com escopo para o solver HTTP-01 do cert-manager. Sem ele, o solver é inacessível e o Order fica em
pendingpara sempre. Atualize a instância com os valores fornecidos; o desafio pendente então se completa por conta própria. - O LoadBalancer tinha restrição de IP. Os intervalos de origem se aplicam à porta 80 também, o que bloqueia os validadores do Let’s Encrypt — tanto na emissão inicial quanto em cada renovação de ~75 dias. Reabra o LB, ou coordene um solver DNS-01 com o suporte antes de restringi-lo.
A CLI ainda ignora a verificação TLS após o painel obter um certificado confiável
--insecure é persistido em cli.json no login. Uma vez que o painel serve um certificado de confiança pública, faça login novamente com agenteye --base-url https://<your-dashboard-domain> --secure login; a verificação é salva de volta como ativada e o aviso de inicialização desaparece.
Problemas no Painel
Não consigo desativar ou editar o usuário ADMIN_EMAIL
Por design. O usuário correspondente ao ADMIN_EMAIL é marcado como protegido em cada inicialização do servidor: o painel oculta o botão Desativar para aquela linha, e a API rejeita DELETE /users/:id e PUT /users/:id com 403 Forbidden. Um trigger do banco de dados também rejeita instruções UPDATE diretas que desativariam a linha protegida.
Para rotacionar o admin de bootstrap, altere ADMIN_EMAIL no seu ambiente e reinicie o servidor. O novo e-mail é inserido/atualizado como protegido. O admin anterior retém o sinalizador de proteção até ser limpo no banco de dados (normalmente está bem, pois o e-mail anterior ainda é um admin válido até você removê-lo explicitamente).
O painel não mostra eventos
- Confirme que a URL do servidor e a chave de API estão corretas nas variáveis de ambiente do painel (
AGENTEYE_SERVER_URL,AGENTEYE_API_KEY). - A chave de API do painel precisa da permissão
events:read. - Confirme que eventos foram realmente ingeridos:
curl http://your-server:8080/events -H "Authorization: Bearer $ADMIN_KEY"
/errors está vazio, mas /events mostra linhas vermelhas
Versões mais recentes do SDK emitem falhas como eventos agent_end / tool_result / hook_completed com outcome: "error" no payload, em vez de uma linha dedicada com event_type: "error". A página /errors agora corresponde a ambos: qualquer linha que o stream /events pinta de vermelho (tipo event_type='error' explícito, outcome/status no conjunto de falhas no payload, is_error: true, ou um campo error verdadeiro) aparece em /errors. Se você anteriormente via “no errors in this window” enquanto linhas vermelhas eram visíveis em /events, atualize o painel + servidor juntos (o filtro ampliado é errored=true em GET /events) e as duas visualizações concordarão.
/models, /tools ou /hooks está lento ou falha ao carregar em intervalos de tempo amplos
Sintoma: em uma tabela de eventos grande (milhões de linhas), abrir /models, /tools ou /hooks — ou ampliar o intervalo de tempo para 7d, 30d ou all — os gráficos giram e então mostram um erro de carregamento. O servidor registra um MEMORY_LIMIT_EXCEEDED do ClickHouse (Código 241) ou um timeout de consulta para a requisição latency_aggregate.
Causa: builds mais antigas calculavam os rollups de latência e distribuição dessas páginas com uma consulta que lia o payload completo de eventos brutos e emparelhava eventos de requisição/resposta com uma classificação e junção na memória. O pico de memória da consulta crescia portanto com o tamanho da janela, então em um tenant ocupado um intervalo amplo poderia exceder o teto de memória por consulta do ClickHouse.
Correção: atualize para um build que inclua essa correção. O rollup agora lê apenas as colunas compactas promovidas e emparelha eventos com uma agregação em streaming, então o pico de memória não escala mais com o payload bruto — intervalos amplos ficam bem dentro do teto de memória e retornam em uma fração do tempo. A melhoria é inteiramente do lado da consulta: aplica-se a todos os dados existentes no próximo carregamento de página, sem re-ingestão ou backfill.
Painel falha ao carregar / página em branco
Verifique os logs do container do painel:AGENTEYE_SERVER_URL ou AGENTEYE_API_KEY ausentes ou apontando para um servidor inacessível.
Analytics / telemetria do painel
O painel envia analytics de uso de produto anônimos para o PostHog por padrão, roteados pelo próprio caminho/ingest do painel (um proxy reverso para https://us.i.posthog.com). Enviá-los como first-party significa que bloqueadores de anúncios do navegador não os descartam. Isso é independente da funcionalidade principal do painel:
- O container do painel (não o navegador) é quem alcança o PostHog. Se seu acesso de saída para
https://us.i.posthog.comestiver bloqueado, a telemetria silenciosamente não opera; o painel funciona normalmente e nenhum erro é exibido aos usuários. - Nenhum dado de agente, sessão ou evento é incluído, apenas o uso da UI do painel.
- Para desativar a telemetria completamente, defina
AE_ANALYTICS_DISABLED=1no container do painel e reinicie. Veja Telemetry & privacy no guia de deployment.
Analytics / telemetria da CLI
A CLIagenteye envia analytics de uso anônimos para o PostHog por padrão: quais comandos são executados, status de sucesso/saída e duração. Isso é independente da funcionalidade da CLI:
- A máquina que executa a CLI alcança
https://us.i.posthog.comdiretamente. Se seu acesso de saída estiver bloqueado, a telemetria silenciosamente não opera (o envio tem limite de tempo, então nunca atrasa um comando) e a CLI funciona normalmente. - Nenhum dado de agente, sessão ou evento é incluído: argumentos de comandos e valores de flags (URL do painel, token, e-mail, ids de sessão, filtros de consulta) nunca são enviados.
- Para desativá-la, defina
AGENTEYE_ANALYTICS_DISABLED=1(ou o cross-toolDO_NOT_TRACK=1) no ambiente da CLI. Veja Telemetry & privacy no guia da CLI.
Problemas no Assistente de IA
Veja enterprise-docs/assistant.md para configuração completa.O botão do assistente não aparece
O botão fica oculto a menos que todos esses critérios sejam atendidos:- O usuário conectado tem a permissão
agent:use. AGENTEYE_AGENT_URLestá definido no painel e o serviçoagentestá acessível.- Um endpoint LLM está configurado no serviço
agent(ANTHROPIC_API_KEY, um gateway viaANTHROPIC_BASE_URL, ou Bedrock/Vertex). Com nenhum definido, o agente reporta “not configured” e o botão permanece oculto.
curl http://agent:9100/health deve retornar {"status":"ok","llm_configured":true,...}.
O assistente diz que não consegue ler algo
As ferramentas são controladas por usuário. Se um usuário não temevaluations:read (ou events:read, dashboards:read), as ferramentas correspondentes não são oferecidas e o assistente dirá que não consegue ler aquele dado. Conceda a permissão de leitura relevante.
”assistant not configured” (HTTP 503) ao enviar
O containeragent não tem endpoint LLM configurado, ou o AGENTEYE_AGENT_TOKEN do painel não corresponde ao do agente. Defina ambos e reinicie.
O container agent reinicia / fica sem memória sob carga
Cada conversa gera um processo filho de curta duração. Certifique-se de que o container executa com um processo init (a imagem usa tini; no Compose defina init: true) e forneça limites de memória adequados. Reduza AGENTEYE_AGENT_MAX_STEPS se necessário.
Problemas na CLI
agenteye falha ao iniciar com ModuleNotFoundError: No module named 'click'
Uma instalação nova da CLI agenteye na versão 0.1.6 pode travar na inicialização com:
click ser instalado indiretamente pelo typer; versões atuais do typer não o incluem mais, então um ambiente limpo acaba sem o pacote. Atualize para a versão 0.1.7 ou mais recente, que depende de click diretamente:
Problemas no Python SDK
Nenhum arquivo aparecendo em $AGENTEYE_HOME/events/
O SDK armazena eventos em buffer e faz flush a cada 500 ms por padrão. Se o processo encerrar antes do flush, os eventos podem ser perdidos. Chame agenteye.configure(flush_interval=0.1) para flush mais rápido em scripts de curta duração, ou garanta que seu processo execute por tempo suficiente para um ciclo de flush.
Se AGENTEYE_HOME estiver definido, verifique se o SDK está escrevendo em $AGENTEYE_HOME/events/ e não em ~/.agenteye/events/ (requer SDK ≥ 0.0.1b5).
ValueError: Reserved field names cannot be used as custom fields
Os nomes timestamp, type e environment são reservados e não podem ser usados como campos personalizados. Passá-los gera:
session_id e agent_id são parâmetros explícitos da chamada de evento, não campos personalizados; passar qualquer um deles novamente como campo personalizado gera TypeError.
Problemas no Monitoramento de Saúde
Nenhum alerta chegando no Slack (Robusta)
O alerta de saúde do Robusta é opt-in; não envia nada até ser instalado e apontado para um canal do Slack. Verifique o release e seu sink:api_key / slack_channel do Slack não foram definidos (ou o token foi revogado); o api_key é um token de relay em nuvem do Robusta (robusta integrations slack), mas o disableCloudRouting: true incluído precisa de um bot token do Slack auto-hospedado (xoxb-…), ou defina disableCloudRouting: false; o scope do sink exclui o namespace onde seus pods estão (os valores incluídos limitam a agenteye); ou nenhuma falha ocorreu ainda. Force um alerta de teste derrubando um pod:
Servidor continua alternando entre NotReady
A sonda de prontidão atinge /ready, que falha quando Postgres ou ClickHouse está inacessível. Se o servidor alterna entre NotReady, uma dependência está intermitentemente indisponível; verifique os pods do ClickHouse e Postgres e os valores CLICKHOUSE_URL / DATABASE_URL do servidor. Confirme o que /ready reporta:
/health, então a alternância de prontidão não reiniciará o pod.
Problemas no Monitoramento de Certificados
CronJob não está enviando notificações para o Slack
O CronJobcert-renewal-check requer uma URL de webhook do Slack armazenada em um Secret. Verifique se existe:
Certificado do cliente expirou antes de uma notificação ser recebida
O CronJob executa a cada 12 horas. Se não esteve em execução, verifique seu status:collector-mtls-secret.yaml regenerado nos clusters que executam seus coletores e reinicie-os:
Problemas de Backup
agenteye-backup falha com “No space left on device”
O CronJob agenteye-backup despeja Postgres + ClickHouse em um volume de rascunho emptyDir chamado backup-tmp (padrão 30Gi), depois transmite em streaming o arquivo tar diretamente para o S3 — o arquivo comprimido nunca é gravado de volta no rascunho, então o rascunho só precisa conter os dumps brutos, não dumps + uma segunda cópia de arquivo em disco. Um pod despejado / No space left on device portanto significa que os dumps brutos excedem o tamanho do rascunho (o dump de events do ClickHouse domina e cresce ao longo do tempo). Verifique os logs do job com falha:
sizeLimit do emptyDir backup-tmp do CronJob acima do total de dumps brutos, e certifique-se de que o armazenamento efêmero do nó pode realmente armazená-lo (sizeLimit é um limite, não uma reserva). Se os dumps ultrapassarem o disco de um único nó, substitua o emptyDir por um PVC (EBS/PD) para backup-tmp, ou comprima os dumps na fonte.
Versões mais antigas gravavam o.tar.gzno mesmo rascunho de20Gidos dumps, entãodumps + arquivoo estouravam e o pod era despejado antes do upload ser executado — o que parece uma falha do S3, mas na verdade é disco. A transmissão em streaming do upload remove esse problema de duplicação.
agenteye-backup falha ao instalar curl
O job executa na imagem postgres:16 e instala curl na inicialização para o dump HTTP do ClickHouse. Em um cluster sem acesso de saída aos mirrors de pacotes Debian, a etapa apt-get falha. Permita esse acesso de saída do pod de backup, ou inclua curl em uma imagem de backup espelhada/personalizada e referencie-a no seu overlay.
agenteye-backup executa, mas nada chega ao armazenamento de objetos
A base vem com um BACKUP_BUCKET real (ts-prod-agenteye/backups) e a ServiceAccount agenteye-backup. O job transmite em streaming o arquivo para o S3 (tar cz … | aws s3 cp - s3://…). Se o pod de backup não tem acesso de escrita ao bucket, o upload falha — e porque o script executa sob set -euo pipefail, uma falha em qualquer ponto desse pipe falha todo o job na etapa upload em vez de silenciosamente não fazer nada (o trap EXIT do pod registra backup FAILED during step: upload). Esta também é a etapa que você alcança após corrigir um despejo por espaço em disco, então se os backups eram anteriormente despejados na etapa de arquivo, verifique se o upload agora chega. Busque nos logs do job com falha o erro de acesso ao S3:
BACKUP_BUCKET para um bucket que você possui e anote a ServiceAccount agenteye-backup existente com acesso de escrita (IRSA / Workload Identity / Pod Identity). Veja a seção Backups de enterprise-docs/kubernetes-deployment.md.
Avaliações / sessões / queries com ClickHouse
A barra lateral da página /queries está vazia após a atualização
Três tabelas (events, evaluations, agent_sessions) são esperadas. Se a barra lateral do SchemaBrowser estiver vazia após a atualização, o servidor falhou ao aplicar o DDL do ClickHouse na inicialização. Verifique os logs do servidor por failed to apply CH DDL statement:
CrashLoopBackOff em vez de uma página de queries silenciosamente quebrada, mas um DDL parcialmente aplicado (um statement OK, os próximos com 5xx) deixa o schema incompleto. Reinicie o pod do servidor após verificar que o CH está acessível:
Novas avaliações não aparecem em /sessions ou /queries
Após a atualização, novas avaliações são escritas no ClickHouse, não no Postgres, e aparecem em /sessions (controlado por evaluations:read) e em /queries. Se não aparecerem:
- Confirme que o pipeline do avaliador está habilitado (
EVALUATOR_ENDPOINTdefinido no servidor) e produzindo resultados terminais; verifique linhas de logevaluation_finalized. - Confirme que o CH está acessível a partir do servidor:
kubectl exec -n agenteye deploy/server -- curl -fsS http://clickhouse:8123/ping. - Faça uma verificação pontual na tabela CH:
kubectl exec -n agenteye clickhouse-0 -- clickhouse-client -q 'SELECT count() FROM agenteye.evaluations'.
Queries falham sob carga com “Memory limit exceeded”, ou ClickHouse tem OOMKilled
Sintoma: sob carga pesada de painel/queries, páginas analíticas (stream de eventos, /sessions, visualização de modelos/latência, editor SQL) começam a falhar ou expirar; o servidor alterna brevemente para NotReady; e o pod do ClickHouse mostra contagem de reinicializações crescente. Isso é quase sempre memória, não CPU ou disco.
Confirme que é memória (não um problema de throughput que replicação resolveria):
-
Verifique se o pod teve kills por falta de memória:
Reason: OOMKilled/Exit Code: 137com contagem de reinicializações crescente é o indicador. -
Pergunte ao ClickHouse o que ele está rejeitando:
Uma contagem grande de
MEMORY_LIMIT_EXCEEDEDé a assinatura. A mensagem diz “maximum: N GiB” — esse N é0,9 × o limite de memória do pod(omax_server_memory_usage_to_ram_ratioemdeploy/base/clickhouse/configmap.yaml). Se suas leituras pesadas precisam de mais que N, são rejeitadas. -
Descarte as coisas que não são o problema — se CPU, contagem de partes e disco estão todos baixos, adicionar réplicas/sharding seria custo desperdiçado:
payload JSON bruta, executam JSONExtract* sobre ela e usam FINAL — cada uma pode precisar de vários GiB. Se os caches configurados (mark_cache_size + uncompressed_cache_size) são maiores que o pod, eles agravam: caches são cobrados contra o mesmo orçamento e competem com a memória de queries.
Correção — escale a memória do ClickHouse:
- Aumente o limite de memória do ClickHouse no seu overlay fazendo patch nos
resourcesdo container do StatefulSetclickhouse(o mesmo mecanismo de overlay usado pararesourcesde outros componentes). O orçamento utilizável do servidor é0,9 × limite, então um limite de6Gidá ~5,4 GiB,16Gidá ~14 GiB. Definarequests.memorycomo um piso real também, para que o scheduler o reserve. Aplicar isso recria o pod do CH (réplica única → ~30–60s de tempo de inatividade de analytics); faça-o em uma janela de baixo tráfego. - Mantenha os caches em
deploy/base/clickhouse/configmap.yamlproporcionais ao limite — caches pequenos (algumas centenas de MiB) são seguros em um pod pequeno; aumente-os apenas junto com um aumento correspondente no limite de memória. Omax_memory_usagepor query é definido explicitamente no perfilusers.xml(veja a seção de nó fixo abaixo) e é mantido abaixo do limite em nível de servidor (0,9 × limite) para que nenhuma query única possa usar mais RAM que o container tem. - Se o próprio nó é o teto, verifique a memória do host que o ClickHouse consegue ver:
Se isso for apenas um pouco acima do limite do pod, mova o ClickHouse para um nó maior (otimizado para memória) — via seletor de nó/affinity no seu overlay — antes de aumentar o limite ainda mais.
500 do painel no meio do caminho enquanto o ClickHouse continua processando — manter queries na RAM e rejeitar rapidamente a rara que excede o orçamento (MEMORY_LIMIT_EXCEEDED, sub-segundo) é o que restaura o carregamento. Observe uma peculiaridade do ClickHouse ao aplicar estas configurações:
- Estas são configurações de perfil, e o ClickHouse lê
<profiles>apenas deusers_config(users.xml/users.d/*.xml) — nunca deconfig.d. Um bloco<profiles>colocado emconfig.d/agenteye.xmlé silenciosamente ignorado (max_execution_time,max_memory_usage, etc. simplesmente não se aplicam). A configuração incluída portanto as fornece como uma chaveusers.xmlno ConfigMapclickhouse-config, montada em/etc/clickhouse-server/users.d/agenteye.xml. - Os padrões incluídos:
max_memory_usage(teto por query — uma query não pode consumir todo o orçamento do servidor),max_bytes_before_external_group_by/max_bytes_before_external_sort=0(derrame desativado) para que queries fiquem na RAM em vez de arrastar no disco lento, emax_execution_time(proteção contra runaway, alinhado com o timeout de leitura do cliente do servidor). - Verifique se estão ativos (assim você também detecta o problema do config.d):
Espere um
max_memory_usagediferente de zero emax_bytes_before_external_group_by = 0. Semax_memory_usagemostrar0/padrão, o perfil não está sendo aplicado — verifique se as configurações estão em um mountusers.d, não emconfig.d.
max_memory_usage é rejeitada (MEMORY_LIMIT_EXCEEDED) em vez de completar lentamente — em um disco lento essa rejeição rápida é preferível, porque uma query derramando excederia o timeout do cliente e falharia de qualquer forma. Se seu disco de dados é rápido (SSD), você pode em vez disso aumentar os limites max_bytes_before_external_* para permitir que queries grandes derramem para disco e completem.
Multi-tenancy (organizações)
Erros durante a atualização que habilita organizações (pods mistos antigos/novos)
Sintoma: durante um deploy em rolagem da versão que habilita organizações, algumas requisições falham: os logs do servidor mostramthere is no unique or exclusion constraint matching the ON CONFLICT specification no caminho de api_keys, e/ou canais de alerta/Slack/webhook param de disparar enquanto o rollout está em andamento.
Causa: a atualização substitui o antigo índice único de escopo de instância em api_keys(name) por índices parciais por organização, e move as configurações de canal de alerta (e default_user_permissions) da tabela global settings para org_settings por organização. Um pod antigo do servidor ainda emite ON CONFLICT (name) (agora sem constraint correspondente) e ainda lê a configuração de canal das antigas linhas de settings (agora vazias). Pods antigos e novos não podem coexistir com segurança nesses dois caminhos.
Correção: não faça um rollout lento desta atualização específica entre versões mistas. Faça a transição de forma limpa: escale o servidor antigo para zero (ou use uma breve janela de manutenção) e suba a nova versão junto com suas migrações, em vez de executar réplicas antigas e novas lado a lado. O tráfego normal e a ingestão retomam imediatamente após a transição; isso afeta apenas a janela de transição de versão.
O provisionamento de uma organização falha em CREATE USER / CREATE ROW POLICY, ou uma organização consegue ler os dados de outra
Sintoma: criar uma organização retorna um erro mencionando CREATE USER, CREATE ROW POLICY ou “access management is disabled”; ou, pior, membros de uma organização veem eventos/avaliações de outra no editor SQL ou assistente.
Causa: o isolamento por organização é aplicado por um usuário ClickHouse dedicado + política de linha por organização. Isso requer que o gerenciamento de acesso SQL esteja habilitado e que users_without_row_policies_can_read_rows=false esteja configurado no ClickHouse. Com o gerenciamento de acesso desativado, o provisionamento não consegue criar o usuário/política; com o padrão da política de linha deixado no seu valor permissivo, um usuário que tem SELECT mas nenhuma política lê todas as linhas (falha aberta).
Correção: use a configuração incluída em deploy/base/clickhouse/, que define ambos. Se você usa sua própria configuração do ClickHouse, habilite o gerenciamento de acesso SQL no usuário interno do servidor e defina users_without_row_policies_can_read_rows=false (veja deploy/base/clickhouse/configmap.yaml), depois reinicie o ClickHouse e re-crie a organização com a CLI agenteye-orgctl (veja enterprise-docs/tenant-management.md).
Usuários da organização perdem acesso ao ClickHouse após alterar ORG_CH_SECRET
Sintoma: o editor SQL e o assistente de IA de repente retornam falhas de autenticação do ClickHouse para todas as organizações, imediatamente após ORG_CH_SECRET ser alterado ou definido de forma inconsistente entre réplicas.
Causa: a senha do ClickHouse de cada organização é derivada como um HMAC de ORG_CH_SECRET. Rotacioná-lo (ou executar réplicas com valores diferentes) invalida a credencial ClickHouse armazenada de cada organização; a senha derivada não corresponde mais ao usuário provisionado.
Correção: defina ORG_CH_SECRET como um único valor forte antes de provisionar uma segunda organização e mantenha-o estável e idêntico em cada réplica do servidor. A reconciliação de inicialização do servidor re-provisiona o usuário ClickHouse de cada organização a partir do secret atual na inicialização, então uma reinicialização do servidor em todas as réplicas (com o secret consistente) corrige os usuários órfãos. Trate o valor como um secret de longa duração; não o rotacione casualmente. Como rede de segurança, se ORG_CH_SECRET for deixado no valor padrão de desenvolvimento integrado (ou seja, não definido), a reconciliação de inicialização ignora organizações não-padrão e registra um erro em vez de reescrever suas credenciais ClickHouse para o valor de desenvolvimento conhecido publicamente, então uma única réplica que reinicia sem o secret não pode quebrar as outras réplicas. Defina o secret de forma consistente e reinicie para provisionar essas organizações.
O assistente de IA retorna 400 / recusa conversar após habilitar organizações
Sintoma: o dock do assistente carrega, mas cada mensagem retorna um erro (HTTP400), e o agente registra uma requisição /chat sem organização rejeitada.
Causa: o agente é ciente de organização e falha de forma fechada; ele rejeita um /chat que não carrega contexto de organização. Isso acontece durante um rollout de transição onde o agente foi atualizado, mas o painel que envia a requisição ainda não está ciente de organização.
Correção: conclua o rollout para que o painel envie contexto de organização (o estado final normal, nenhum flag necessário). Para cobrir o período enquanto um painel não ciente de organização fala com um agente ciente de organização, defina AGENTEYE_AGENT_ALLOW_NO_ORG=1 no serviço agent para que ele recue para a organização default em vez de recusar, e limpe-o assim que a atualização do painel chegar. Veja a referência de variáveis de ambiente em enterprise-docs/assistant.md.
Auditorias
Uma auditoria nunca é executada (próxima execução continua adiando, sem histórico de execução)
Sintoma: a página de auditoria mostra last run: never, ounext run continua avançando para o futuro sem que apareça uma linha no histórico de execução.
Causa: a auditoria está desativada (auditorias desativadas não têm entrada na fila), ou os workers de auditoria do servidor estão falhando ao reivindicar trabalho.
Correção: confirme que a auditoria está habilitada (o botão executar agora requer isso). Então verifique os logs do servidor por audits pipeline started na inicialização e por erros audits: — uma linha claim_due failed aponta para conectividade do Postgres. AUDIT_WORKERS padrão é 1; deve ser ≥ 1 para qualquer auditoria executar.
Execuções de auditoria têm sucesso, mas não encontram nada
Sintoma: o histórico de execução mostrasucceeded com findings: 0 mesmo que /errors claramente mostre falhas.
Causa: a janela de varredura não cobre as falhas, ou os filtros de escopo as excluem.
Correção: verifique a janela da linha de execução (window_from → window_to) contra quando as falhas ocorreram — no modo since_last, cada execução só varre desde a última execução bem-sucedida, então falhas mais antigas são vistas apenas pela primeira execução ou por uma auditoria de janela fixed. Amplie scope (ambientes / ids de agente). As estatísticas de execução mostram policy_hits (quantas políticas determinísticas dispararam) e improvements (quantos a investigação de IA registrou) — se ambos são 0, a janela/escopo genuinamente não viu nada.
A execução diz analysis_unavailable e produz apenas descobertas de política
Sintoma: as estatísticas de execução incluem analysis_unavailable e as únicas descobertas são kind: policy; nenhuma melhoria de IA aparece.
Causa: a investigação agêntica não pôde executar: o servidor não consegue alcançar o serviço agent (AGENTEYE_AGENT_URL / AGENTEYE_AGENT_TOKEN não definidos no servidor — a auditoria reutiliza a conexão do assistente), o serviço assistente não tem LLM configurado, ou a chamada errou/expirou (a string analysis_unavailable tem o detalhe). A passagem de política determinística é o piso — sempre executa — então a auditoria ainda tem sucesso com suas descobertas de segurança.
Correção: defina AGENTEYE_AGENT_URL (por exemplo, http://agent:9100) e AGENTEYE_AGENT_TOKEN no servidor — os mesmos valores que o assistente do painel já usa (os manifestos/compose incluídos agora os conectam) — e configure um LLM no serviço assistente (veja assistant.md), depois execute novamente. Uma investigação grande pode precisar de um AUDIT_LLM_TIMEOUT_MS maior (servidor) — mantenha-o acima do AGENTEYE_AUDIT_TIMEOUT_MS do agente.
O sandbox de código da auditoria está desativado (sandbox_available: false)
Sintoma: o /health do agente mostra sandbox_available: false, e as execuções de auditoria observam que o sandbox está indisponível; a IA investiga apenas com SQL.
Causa: o sandbox bubblewrap dentro do pod precisa de namespaces de usuário não privilegiados, que o perfil seccomp do pod ou o kernel do nó está bloqueando.
Correção: defina seccompProfile: Unconfined (k8s) ou security_opt: [seccomp:unconfined] (compose) no agente, e confirme que o kernel do nó permite namespaces de usuário não privilegiados (algumas imagens gerenciadas, como GKE COS, os desativam). Onde você não pode habilitá-lo, isso é esperado e seguro — o auditor degrada para SQL apenas automaticamente. Veja deployment.md.
Relatório de e-mail de auditoria não entregue
Sintoma: uma auditoria revelou novas descobertas, mas nenhum e-mail chegou. Causa: a auditoria não tem um canal de e-mail anexado, o e-mail está desativado em toda a organização emalerts.enabled_channels, não há destinatários, ou o SMTP não está configurado.
Correção: anexe um canal de e-mail à auditoria, certifique-se de que email está em alerts.enabled_channels, defina destinatários (no canal ou via alerts.email_default_recipients) e configure o SMTP (o mesmo transporte que os e-mails de alertas + OTP usam). O e-mail é enviado apenas quando uma execução produz pelo menos uma nova descoberta.
Um padrão silenciado ou descartado mantém sua página de descoberta antiga, mas nunca é re-classificado
Sintoma: após silenciar uma descoberta, execuções posteriores nunca surfaceiam aquele padrão novamente — mesmo que ele ainda ocorra. Causa: esse é o comportamento projetado: silenciar/descartar são supressões duráveis codificadas pela impressão digital do padrão. Correção: abra a descoberta e use reopen para limpar a supressão; a próxima execução classificará o padrão novamente. Use resolve (não silenciar) para padrões “corrigidos” sobre os quais você gostaria de ser notificado se regredirem.Obtendo Ajuda
Entre em contato comsupport@exosphere.host com:
- Sua versão do AgentEye (da tag de release)
- Logs relevantes do container (
docker logs <container>) - Uma descrição do problema e o que você já tentou

