Capacity Planner
O Capacity Planner gera um relatório de CPU e memória para cada Deployment que aparece como recurso de uma Issue. Ele não é um job em segundo plano: roda só quandoGET /api/v1/analytics/capacity é chamado e não guarda histórico próprio.
O que Ele Calcula
Para cada recurso distinto (kind/namespace/name) entre as Issues listadas (todas, ou as do ?namespace=), o planner:
- Lê o Deployment com esse nome e namespace. Se não existir (o recurso é um StatefulSet, um DaemonSet, um Pod ou foi apagado), o recurso é pulado sem erro.
- Pega
resources.limitseresources.requestsde CPU e memória do primeiro container e calculauso% = requests / limits × 100(0 quando não há limit). - Correlaciona o recurso com os incidentes do namespace dele dentro da janela (abaixo).
- Define uma urgência e uma recomendação a partir do que sabe: a porcentagem de requests/limits e a correlação com incidentes.
from e to são passados juntos (RFC 3339), a janela passa a ser a diferença entre eles, e continua terminando agora.
Tendência e Urgência
Urgency só tem esses dois valores: sem histórico, nada é urgent. O banner de capacidade do dashboard lista os recursos com Urgency: "plan".
Campos da Resposta
O endpoint retornakind: CapacityForecastList com um CapacityForecast por recurso. Os nomes de campo são os nomes Go (sem renomeação JSON), exceto a referência de recurso aninhada:
CapacityForecast
CapacityForecast
ResourceTrend
ResourceTrend
ForecastResult
ForecastResult
IncidentResourceCorrelation
IncidentResourceCorrelation
Correlação com Incidentes
Urgency para plan e, quando os requests estão dentro dos limits, define a recomendação.
Geração de Recomendações
A primeira regra que casar vence (o texto é sempre em inglês):Como Usar
viewer (só GET). Cada chamada lista todas as Issues do escopo e, por recurso, lê um Deployment mais as Issues do namespace, então mantenha as chamadas esporádicas em clusters grandes.
Noise Reducer
O Noise Reducer roda dentro do controller de Anomaly. Ele só é consultado para uma anomalia que abriria uma Issue nova: uma anomalia cujo recurso já tem Issue ativa é antes correlacionada a ela, e uma que chega dentro do cooldown de resolução (spec.aiops.resolutionCooldownMinutes da Instance de onde a anomalia veio, padrão 10, 0 desliga) após uma resolução é suprimida antes de chegar ao Noise Reducer.
As quatro checagens rodam em ordem e a primeira que disparar vence. Uma anomalia suprimida é marcada com status.correlated: true, com o motivo registrado como suppressed:<motivo>; nenhuma Issue é criada e chatcli_operator_anomalies_processed_total{result="suppressed_noise"} é incrementado. Se uma checagem falhar (por exemplo, erro num List), a anomalia não é suprimida. Os recursos são comparados pelo nome dentro do namespace da anomalia.
Estratégia 1: Supressão Repetitiva
Estratégia 2: Padrões Sazonais
Toda anomalia não suprimida é registrada como ocorrência sazonal. Os padrões ficam por namespace no ConfigMapchatcli-seasonal-patterns, chave patterns, como um array JSON.
SeasonalPattern (JSON):
Algoritmo:
TZ no operator; a imagem inclui tzdata). A distância de horas não dá a volta na meia-noite (23:00 e 00:00 ficam a 23 horas de distância).
Estratégia 3: Detecção de Flapping
Estratégia 4: Score de Fadiga de Alertas
A referência de recência é o último item da lista de Anomalies do namespace sem filtro, não a anomalia mais nova do recurso, então o
recency_score pode refletir outro recurso. O limite > 80 é fixo e não configurável.Cost Tracker
O Cost Tracker registra o gasto de LLM de cada incidente a partir do usage que o servidor reporta e serve o agregado pela API REST.Custos de LLM por Provider
Toda análise (AnalyzeIssue, controller de AIInsight) e todo passo de remediação agêntica (AgenticStep, controller de Remediation) é contabilizado a partir do usage de tokens que o servidor informa na resposta, atribuído ao provider e modelo que de fato responderam (a fallback chain do servidor pode ter roteado para outro). Quando a resposta não traz usage (um servidor anterior aos campos de usage), as análises caem para caracteres divididos por quatro na entrada e na saída, e os passos agênticos registram zero tokens de entrada e o tamanho do raciocínio dividido por quatro como saída.
O preço por token é resolvido nesta ordem:
- uma entrada para o provider no ConfigMap
chatcli-cost-configdo namespace da Issue (a palavra do operador do cluster); - o motor de preço compartilhado (
llm/pricing), as mesmas tabelas por modelo, overrides e regras de assinatura que o/costda CLI usa (incluindo um overrideCHATCLI_MODEL_PRICINGdefinido no processo do operator, por exemplo peloextraEnvdo chart), então o ledger aqui e a sessão lá concordam no preço da mesma chamada; - um padrão por provider para um modelo que o motor não conhece (por exemplo
CLAUDEAI15,OPENAI30,OPENROUTER8,DEVIN1/$3 por milhão de tokens de entrada/saída).
cost_usd / cost_known na própria resposta (veja modo servidor); o ledger não usa esses campos.
Configuração de Custos
Os preços podem ser sobrescritos por provider no ConfigMapchatcli-cost-config, chave pricing, uma entrada por nome de provider exatamente como o servidor o informa (CLAUDEAI, OPENAI, …). O tracker o procura no namespace da Issue sendo contabilizada, o mesmo namespace do ledger dela, então crie um em cada namespace cujos incidentes você queira precificar de outro jeito:
Uma entrada vale para todos os modelos daquele provider; não existe chave por modelo. Sem o ConfigMap, para um provider que ele não lista, ou quando o valor de
pricing não é um JSON válido, valem as tarifas por modelo do motor de preço. O ConfigMap é lido a cada contabilização, então uma atualização vale a partir da próxima chamada; chamadas já registradas mantêm o preço com que foram registradas.IncidentCost
Uma entrada no ledger por incidente, escrita pelos controllers de AIInsight e Remediation a cada chamada ao LLM:Cada chamada é precificada uma vez, pelas tarifas do provider e modelo que a responderam, e somada ao total da entrada. Uma chamada posterior em outro modelo (por exemplo depois de um fallback) nunca reprecifica as anteriores;
provider e model só nomeiam a chamada mais recente.CLAUDEAI acima):
usage em AnalyzeIssue e AgenticStep) é o que entra no ledger, então ele reflete contagens reais de tokens, não estimativas.
Duas chamadas registradas ao mesmo tempo no mesmo namespace não se sobrescrevem: a atualização do ledger leva a versão que leu, e um conflito de escrita é tentado de novo. Um registro que ainda falha (o limite de tamanho do ConfigMap, falta de RBAC, um ledger que não pode ser lido ou uma entrada que não pode ser decodificada) é registrado no log do controller (
Failed to book the analysis cost on the ledger ou Failed to book the agentic step cost on the ledger); a análise ou o passo em si não é afetado, e uma entrada ilegível nunca é sobrescrita por uma nova.CostSummary
Agregação num período, servida pela API REST (papelviewer, só GET), como kind: CostSummary com o resumo em spec:
from e to (RFC 3339) definem um período absoluto: com os dois, é exatamente [from, to]; só com from, vai até agora; só com to, são os 30 dias que terminam em to; sem nenhum, são os últimos 30 dias. Uma entrada conta inteira quando o recordedAt dela (último registro) cai no período; entradas sem recordedAt sempre contam. Sem namespace, o resumo agrega todos os chatcli-cost-ledger do cluster. Um namespace sem ledger retorna zeros; qualquer outra falha ao ler um ledger retorna 500 (failed to read the cost ledger: ...) em vez de zeros.
totalLLMCost com a economia dos seus próprios incidentes se precisar deles.
Arquitetura de Armazenamento (ConfigMaps)
Esses subsistemas persistem os dados em ConfigMaps no namespace da Issue ou da Anomaly a que se referem (não no namespace do operator). O Capacity Planner não armazena nada.Formato de Armazenamento
Um ConfigMap por namespace,chatcli-cost-ledger, uma chave por incidente com o JSON do IncidentCost. O tracker o cria com o label app.kubernetes.io/managed-by: chatcli-operator, que é como o resumo de todos os namespaces encontra cada ledger:
Integrações
API REST
/api/v1/analytics/cost serve o resumo do ledger; /api/v1/analytics/capacity serve as previsões de capacidade; /api/v1/analytics/summary expõe dados de incidentes.Web Dashboard
A view Overview tem um banner de avisos de capacidade alimentado por
/analytics/capacity: ele lista os recursos com Urgency: "plan" e a recomendação de cada um. O dashboard não mostra o ledger de custos.Grafana
O dashboard
remediation-stats.json cobre o sucesso da remediação por tipo de ação. Nenhum dashboard incluído cobre capacidade ou custo de LLM.AIOps Platform
Arquitetura completa do pipeline AIOps e como estes subsistemas se integram.