Web Dashboard
Visão Geral
O Web Dashboard é uma Single Page Application embutida diretamente no binário do operator via Goembed.FS — não requer Node.js, npm ou qualquer build frontend separado.
operator; uma chave viewer vê tudo, mas suas ações devolvem 403.Tema e idioma
Os dois seletores ficam no cabeçalho, ao lado do controle de auto-refresh, e são acessíveis por teclado. A escolha fica guardada no navegador e é aplicada antes da primeira pintura, então um reload nunca pisca o tema errado.?theme= e ?lang= definem a preferência uma vez e a persistem, então um bookmark como http://localhost:8090/?lang=pt-BR&theme=dark abre o dashboard em português e escuro em todas as visitas seguintes. O atributo <html lang> acompanha o idioma, e os valores que vêm da API (severidade, estados de incidente e de plano, decisões de aprovação) mantêm o valor bruto no markup enquanto o rótulo visível é traduzido.
Arquitetura
/) é servida sem autenticação; toda chamada de dados que ela faz vai para /api/v1/ com a API key. No primeiro acesso o dashboard pede a chave, valida contra /api/v1/incidents e a guarda no localStorage do navegador (chatcli_api_key); Trocar a chave de API no cabeçalho a apaga.
api (8090) do Service chatcli-operator no namespace do operator, e não pelo Service da Instance do ChatCLI. Toda réplica do operator serve o dashboard e a API, então um Service com várias réplicas pode rotear para qualquer uma delas.Views do Dashboard
O dashboard tem 11 views acessíveis por abas. Um filtro de período no cabeçalho (Todo o período, ou De/Até) é repassado comofrom/to às listas que o suportam.
1. Overview
1. Overview
/analytics/summary, /analytics/compliance, /analytics/capacity, /analytics/remediation-stats, /analytics/mttd, /analytics/mttr e da lista de incidentes.Componentes:localStorage (panelOrder_overviewPanels).2. Incidents
2. Incidents
operator. Ack para a escalação do incidente no nível atual (nenhum nível a mais, nenhuma repetição) e registra quem reconheceu no status da EscalationPolicy. Adiar segura toda notificação exceto Resolved, e a escalação, até o snooze terminar; um page de escalação retido sai nesse momento e o timer do nível recomeça. Veja reconhecimento e snooze.Badges de severidade (tema escuro):3. SLOs
3. SLOs
4. Approvals
4. Approvals
status.decisions como <seu nome> (api-key: <identidade da chave>), e o controller de aprovação avalia então quorum e change window. Um quorum conta cada API key uma vez, então cada aprovador precisa da própria chave; um pedido que não está mais pendente, ou que a sua chave já decidiu, devolve erro. Veja Fluxo de Aprovação. Quando o pedido traz a annotation platform.chatcli.io/blast-risk-level, o card mostra um badge de blast radius colorido pelo nível.5. AI Insights
5. AI Insights
GET /api/v1/aiinsights6. Remediations
6. Remediations
- Modo Runbook: mostra a sequência de ações do runbook a partir do qual o plano foi montado
- Modo Agentic: mostra a contagem de passos; use a API Get Remediation Plan para o histórico completo da conversa com a IA
GET /api/v1/remediations7. Runbooks
7. Runbooks
agentic-…. Runbooks gerados levam o label platform.chatcli.io/auto-generated: "true" e são reutilizados pelo próximo incidente parecido, em vez de começar do zero.Endpoint da API: GET /api/v1/runbooks8. PostMortems
8. PostMortems
operator.9. Clusters
9. Clusters
/clusters/global-status): Total de Clusters, Saudáveis (conectados, todos os nodes Ready), Degradados (conectados, com a condition Degraded: alguns nodes não Ready), Offline.Painel de Federação:GET /api/v1/clusters/global-status, GET /api/v1/federation/status, GET /api/v1/federation/correlations10. Políticas
10. Políticas
kubectl ou GitOps, onde são revisadas; a aba mostra o que está em vigor, por namespace ou em todos.GET /api/v1/policies/{kind}, GET /api/v1/policies/{kind}/{name}11. Audit
11. Audit
Grafana Dashboards
O repositório traz 4 dashboards Grafana em JSON emdeploy/grafana/, prontos para importação. Painéis baseados em métricas chatcli_operator_* precisam que o endpoint de métricas do operator seja coletado; painéis com chatcli_grpc_*, chatcli_llm_*, chatcli_session_*, chatcli_server_* e chatcli_watcher_* precisam também da porta de métricas do servidor ChatCLI (9090).
1. AIOps Overview (aiops-overview.json)
2. SLO Burn Rate (slo-burn-rate.json)
Variáveis de template service e slo_name.
3. Incident Timeline (incident-timeline.json)
4. Remediation Stats (remediation-stats.json)
- Expired Approvals (24h) conta
chatcli_operator_approvals_total{result="expired"}. Para as aprovações pendentes agora, use o tile de Aprovações Pendentes do dashboard ou/api/v1/approvals?state=Pending. - Auto-Approved (24h) e Auto-Approve Rate leem
mode="auto", result="approved"; Notification Success Rate lêresult="success". - Notification Latency by Channel lê
chatcli_operator_notification_duration_seconds(p50/p95 porchannel_type). - Clusters by Status / Connected Clusters leem
chatcli_operator_federation_clusters_total, um gauge definido por estado (connected,degraded,disconnected) a partir das registrations que existem. - Critical Issues Detected (24h) conta as Issues críticas que entraram em
Analyzingnas últimas 24 horas.
Instalação dos Dashboards Grafana
Via Grafana Sidecar (Recomendado)
Se você usa o Helm chart do Grafana com o sidecar de dashboards habilitado, crie um ConfigMap com os quatro arquivos e o labelgrafana_dashboard: "1", a partir de um checkout do repositório:
grafana_dashboard: "1" e importa os dashboards sem restart. deploy/grafana/dashboards-configmap.yaml traz só os dois ServiceMonitors que o Prometheus precisa para coletar o operator e o servidor (o do servidor seleciona app.kubernetes.io/name: chatcli, o label que os Services das Instances e o chart do servidor têm), com esses mesmos comandos nos comentários; ele não carrega ConfigMap de dashboards, então aplicá-lo nunca sobrescreve o criado acima. Nomeie cada arquivo JSON: apontar --from-file para o diretório também colocaria esse YAML dentro do ConfigMap.Via Importação Manual
- Vá em Grafana > Dashboards > Import
- Faça upload do arquivo JSON ou cole o conteúdo
- Selecione o datasource Prometheus
- Clique em Import
ServiceMonitor para Prometheus Operator
Com o Helm chart do operator, definaserviceMonitor.enabled: true (mais serviceMonitor.interval, scrapeTimeout e labels conforme necessário); o chart gera um ServiceMonitor para a porta metrics (8080, path /metrics). Escrito à mão, para um release chamado chatcli-operator:
Referência de Métricas Prometheus
O operator expõe estas métricas (além das padrão do controller-runtime) na sua porta de métricas:GET /api/v1/analytics/cost e as previsões de capacidade em GET /api/v1/analytics/capacity. Métricas de requisições e tokens de LLM (chatcli_llm_*) vêm do servidor ChatCLI.
Queries Prometheus Úteis
Exemplos de queries PromQL para dashboards ou alertas:Tempo mediano de resolução (últimas 24h)
Tempo mediano de resolução (últimas 24h)
Taxa de sucesso de remediação
Taxa de sucesso de remediação
Burn rate do SLO (alerta multi-window)
Burn rate do SLO (alerta multi-window)
Planos segurados para um humano pelo motor de decisão
Planos segurados para um humano pelo motor de decisão
Anomalias por resultado de processamento
Anomalias por resultado de processamento
Taxa de falha de notificação por canal
Taxa de falha de notificação por canal
Acessar e publicar o dashboard
Verificar o operator
Preview local (sem cluster)
http://127.0.0.1:8085/ e entre com a API key preview, que carrega o papel admin para que aprovações, revisões e feedback de post-mortem possam ser exercitados. O seed cobre todas as abas: issues em todos os estados, um AI insight, planos de remediação, uma aprovação pendente, um post-mortem, SLOs, clusters, eventos de auditoria e runbooks com passos. Defina DASHPREVIEW_ADDR para trocar o endereço. A ferramenta vive em operator/hack/dashpreview e nunca faz parte da imagem do operator.Configurar as API Keys
chatcli-operator-secrets (chave api-keys) no próprio namespace, com fallback para o ConfigMap chatcli-operator-config (mesma chave). Crie-o você mesmo como abaixo, ou deixe o chart do operator renderizá-lo (apiKeys.create: true com apiKeys.entries; as keys ficam então guardadas na release do Helm, então não faça os dois). O valor é uma lista YAML; as roles são viewer, operator e admin (qualquer outra role é negada):/api/ devolve 401 (a página carrega, mas não consegue entrar).Para ler as keys de volta, por exemplo para entrar a partir de um navegador novo:Port-forward (desenvolvimento)
http://localhost:8090/Publicar com um Ingress (produção)
/api/v1/... e /healthz com caminhos absolutos, então sob um sub-path (/chatcli com rewrite ou strip-path) a página carrega mas todos os painéis falham; rotear /api/v1 à parte no host compartilhado só esconde o problema e publica a API em todos os hosts daquele controller.- Qualquer controller: a regra acima não precisa de anotação do controller. Não adicione reescrita de caminho (
nginx.ingress.kubernetes.io/rewrite-target,konghq.com/strip-path, um middlewareStripPrefixdo Traefik): compath: /não há nada a remover. - TLS: termine no Ingress como acima, ou sirva HTTPS (TLS 1.3) direto do operator com
security.apiTLS.certFile/keyFiledo chart (CHATCLI_AIOPS_TLS_CERT/CHATCLI_AIOPS_TLS_KEY), montando o certificado comextraVolumes/extraVolumeMounts. Um backend que serve TLS precisa da configuração de protocolo de backend do controller (no ingress-nginx,nginx.ingress.kubernetes.io/backend-protocol: "HTTPS"). - Cluster local (kind, k3d, Docker Desktop): quando o ingress controller atende em
localhost, use um nome sob.localhost, por exemplohost: aiops.localhost, e tire o blocotls. Navegadores,curl, macOS esystemd-resolvedmandam todo nome*.localhostpara o endereço de loopback, então não é preciso DNS nem entrada no/etc/hosts. - Métricas: não publique a porta de métricas (8080) pelo mesmo Ingress: ela é HTTP puro, sem autenticação.
- Rate limit: 30 requisições por minuto por host de cliente para requisições sem API key válida, 600 por minuto por key válida. Atrás de um Ingress toda requisição sem key vem do controller, então elas dividem uma cota só; o tráfego do dashboard carrega a key, então navegadores logados não dividem.
- CORS: chamadas cross-origin são negadas a menos que liberadas com
security.corsAllowedOrigins(CHATCLI_CORS_ALLOWED_ORIGINS); o dashboard em si é same-origin e não precisa de configuração de CORS.
curl -s https://aiops.example.com/healthz responde {"status":"ok",...}, e curl -s -o /dev/null -w '%{http_code}' https://aiops.example.com/api/v1/incidents responde 401 sem key.