Pular para o conteúdo principal
A plataforma AIOps do ChatCLI inclui três subsistemas avançados que trabalham juntos para otimizar operações: Capacity Planner (previsão de esgotamento de recursos), Noise Reducer (supressão inteligente de alertas) e Cost Tracker (rastreamento de custos e cálculo de ROI).

Capacity Planner

O Capacity Planner analisa tendências históricas de uso de CPU e memória para prever quando os recursos de um cluster ou namespace serão esgotados — permitindo ação proativa antes que incidentes ocorram.

Algoritmo de Regressão Linear

O Capacity Planner utiliza regressão linear por mínimos quadrados (least-squares) para projetar a data de esgotamento de recursos.
Dado um conjunto de pontos (t_i, y_i) onde:
  t_i = timestamp normalizado (horas desde o primeiro ponto)
  y_i = porcentagem de uso do recurso (0-100)

Calcula:
  slope     = (n * sum(t*y) - sum(t) * sum(y)) / (n * sum(t^2) - sum(t)^2)
  intercept = (sum(y) - slope * sum(t)) / n

Projeção de esgotamento:
  Se slope > 0:
    hours_until_full = (100 - current_usage) / slope
    exhaustion_date  = now + hours_until_full
O algoritmo requer ao menos 3 pontos de dados para gerar uma projeção confiável. Com menos de 3 pontos, o planner retorna trend: insufficient_data.

Estruturas de Dados

Representa um ponto de uso de recurso no tempo.
CampoTipoDescrição
Timestamptime.TimeMomento da coleta
CPUPercentfloat64Uso de CPU em porcentagem (0-100)
MemoryPercentfloat64Uso de memória em porcentagem (0-100)
CPUCoresfloat64Uso absoluto em cores
MemoryBytesint64Uso absoluto em bytes
NamespacestringNamespace de origem
ResourcestringNome do recurso (deployment, node)
Resultado da regressão linear para um recurso.
CampoTipoDescrição
ResourcestringNome do recurso
NamespacestringNamespace
CPUSlopefloat64Taxa de crescimento de CPU (%/hora)
MemorySlopefloat64Taxa de crescimento de memória (%/hora)
CPUInterceptfloat64Intercepto da regressão para CPU
MemoryInterceptfloat64Intercepto da regressão para memória
DataPointsintNúmero de pontos usados na regressão
R2Scorefloat64Coeficiente de determinação (qualidade do fit)
Projeção de esgotamento com recomendações.
CampoTipoDescrição
ResourcestringNome do recurso
NamespacestringNamespace
CPUExhaustionDate*time.TimeData projetada de esgotamento de CPU (nil se estável)
MemoryExhaustionDate*time.TimeData projetada de esgotamento de memória (nil se estável)
CPUCurrentPercentfloat64Uso atual de CPU
MemoryCurrentPercentfloat64Uso atual de memória
CPUGrowthRatefloat64Taxa de crescimento de CPU (%/hora)
MemoryGrowthRatefloat64Taxa de crescimento de memória (%/hora)
UrgencystringClassificação: urgent, plan, stable
Recommendations[]stringLista de recomendações
IsBottleneckboolSe o recurso é gargalo em incidentes ativos

Correlação com Incidentes

O método ResourceIsBottleneck verifica se um recurso está relacionado a incidentes ativos:
Para cada Issue ativo (state != Resolved && state != Escalated):
  Se issue.resource.name == forecast.Resource
  E  issue.resource.namespace == forecast.Namespace
  Então: forecast.IsBottleneck = true
Quando IsBottleneck = true, a recomendação de capacidade é automaticamente priorizada e inclui referência ao incidente ativo.

Geração de Recomendações

O Capacity Planner gera recomendações baseadas na urgência da projeção:
CondiçãoUrgênciaRecomendação
Esgotamento em menos de 7 diasurgent”URGENTE: {recurso} em {namespace} projetado para esgotar {tipo} em {data}. Ação imediata necessária: escalar horizontalmente ou aumentar limits.”
Esgotamento entre 7 e 30 diasplan”PLANEJAMENTO: {recurso} em {namespace} projetado para esgotar {tipo} em {data}. Planeje aumento de capacidade nas próximas semanas.”
Esgotamento em mais de 30 dias ou slope negativo/estávelstable”Estável: {recurso} em {namespace} não apresenta tendência de esgotamento no horizonte de 30 dias.”

Como Usar

planner := capacity.NewCapacityPlanner(k8sClient, logger)

// Coleta dados históricos e analisa tendências
forecasts, err := planner.AnalyzeResourceTrends(ctx, namespace)
if err != nil {
    logger.Error("falha na análise de capacidade", zap.Error(err))
    return
}

for _, forecast := range forecasts {
    if forecast.Urgency == "urgent" {
        // Criar alerta ou incidente proativo
        logger.Warn("recurso em risco de esgotamento",
            zap.String("resource", forecast.Resource),
            zap.Time("cpu_exhaustion", *forecast.CPUExhaustionDate),
        )
    }
}
O Capacity Planner coleta dados a cada ciclo de reconciliação (30 segundos) e armazena histórico em um ConfigMap (chatcli-capacity-history). A regressão é recalculada a cada 5 minutos.

Noise Reducer

O Noise Reducer implementa quatro estratégias de supressão de alertas para reduzir a fadiga de alerta (alert fatigue) e melhorar a relação sinal/ruído.

Estratégia 1: Supressão de Repetitivos

Suprime alertas idênticos quando há acúmulo sem mudança de estado.
Condição de supressão:
  - 5 ou mais alertas idênticos na última 1 hora
  - Sem mudança de estado (severity, resource, signal_type iguais)
  - Hash de identidade: SHA256(signal_type + resource_name + namespace)

Resultado:
  - Alerta suprimido (não gera nova Anomaly CR)
  - Contador de supressão incrementado
  - Log: "alerta repetitivo suprimido (N ocorrências em 1h)"
Se a severidade do alerta mudar (ex: high para critical), a supressão é desativada imediatamente e o alerta é processado normalmente.

Estratégia 2: Padrões Sazonais

Identifica e suprime alertas que ocorrem em horários previsíveis (ex: jobs de limpeza, deploys agendados). SeasonalPattern struct:
CampoTipoDescrição
SignalTypestringTipo do sinal (ex: pod_restart)
ResourcestringNome do recurso
NamespacestringNamespace
DayOfWeektime.WeekdayDia da semana (0=domingo)
HourOfDayintHora do dia (0-23)
MinuteWindowintJanela de tolerância em minutos
OccurrencesintNúmero de ocorrências confirmadas
Confidencefloat64Confiança do padrão (0-1)
LastSeentime.TimeÚltima ocorrência
Algoritmo de Detecção:
Para cada alerta recebido:
  1. Busca padrões sazonais existentes para (signal_type, resource, namespace)
  2. Para cada padrão encontrado:
     - Verifica se day_of_week == padrão.DayOfWeek
     - Verifica se |hora_atual - padrão.HourOfDay| <= 30 minutos (janela de tolerância)
     - Se match: incrementa Occurrences, atualiza LastSeen
     - Se Occurrences >= 3 E Confidence >= 0.7: SUPRIME o alerta
  3. Se nenhum padrão existente faz match:
     - Cria novo SeasonalPattern candidato (Occurrences=1, Confidence=0.3)
Como padrões são aprendidos: A confiança do padrão cresce com cada confirmação:
Confidence = min(1.0, 0.3 + (Occurrences - 1) * 0.15)

Occurrences | Confidence | Suprime?
     1      |    0.30    |   Não
     2      |    0.45    |   Não
     3      |    0.60    |   Não
     4      |    0.75    |   Sim (>= 0.7 e >= 3)
     5      |    0.90    |   Sim
     6+     |    1.00    |   Sim
Exemplo prático:
  • ConfigMap update job roda toda segunda às 03:00
  • Gera alerta pod_restart no namespace jobs
  • Após 4 semanas: padrão identificado (segunda, 03:00, confidence 0.75)
  • A partir da 5a semana: alerta suprimido automaticamente
Padrões são armazenados no ConfigMap chatcli-seasonal-patterns.

Estratégia 3: Detecção de Flap

Detecta recursos que oscilam entre estados (resolved -> detected -> resolved) repetidamente.
Condição de flap:
  - 3 ou mais ciclos resolved → detected na mesma janela de 24 horas
  - Mesmo recurso (resource_name + namespace)

Ações:
  1. Marca recurso como "flapping"
  2. Suprime novos alertas do recurso por 2 horas
  3. Gera alerta consolidado: "Recurso {name} em flap — {N} ciclos em 24h"
  4. Recomenda investigação de causa raiz

Saída do flap:
  - Se nenhum novo ciclo em 2 horas: remove flag de flap
  - Novos alertas voltam a ser processados normalmente

Estratégia 4: Alert Fatigue Scoring

Calcula uma pontuação de fadiga de alerta (0-100) para determinar se o volume de alertas está excessivo.
fatigue_score = volume_score + resolve_rate_score + recency_score

Onde:
  volume_score (0-40):
    - alerts_per_hour = total_alerts_last_6h / 6
    - volume_score = min(40, alerts_per_hour * 4)

  resolve_rate_score (0-30):
    - auto_resolve_rate = auto_resolved / total * 100
    - Se auto_resolve_rate > 90%: resolve_rate_score = 30
    - Se auto_resolve_rate > 70%: resolve_rate_score = 20
    - Se auto_resolve_rate > 50%: resolve_rate_score = 10
    - Senão: resolve_rate_score = 0

  recency_score (0-30):
    - Se > 5 alertas nos últimos 10 minutos: recency_score = 30
    - Se > 3 alertas nos últimos 10 minutos: recency_score = 20
    - Se > 1 alerta nos últimos 10 minutos: recency_score = 10
    - Senão: recency_score = 0
Classificação:
ScoreClassificaçãoAção
0-25lowNenhuma ação. Volume saudável.
26-50moderateLog de aviso. Monitorar tendência.
51-75highAtiva supressão agressiva. Consolida alertas similares.
76-100criticalSuprime tudo exceto critical severity. Gera meta-alerta para SRE.

Cost Tracker

O Cost Tracker rastreia custos operacionais (LLM + downtime) e calcula o ROI da automação AIOps.

Custos de LLM por Provedor

O custo de cada chamada LLM é calculado com base nos tokens consumidos e nos preços configurados por provedor:
ProvedorCusto Input (por 1M tokens)Custo Output (por 1M tokens)Modelo de Referência
claude$3.00$15.00Claude Sonnet
gpt-4$10.00$30.00GPT-4 Turbo
default$1.00$3.00Qualquer outro

Configuração de Custos

Os preços são configuráveis via ConfigMap chatcli-cost-config:
apiVersion: v1
kind: ConfigMap
metadata:
  name: chatcli-cost-config
  namespace: chatcli-system
data:
  costs.json: |
    {
      "providers": {
        "claude": {"input_per_million": 3.00, "output_per_million": 15.00},
        "gpt-4": {"input_per_million": 10.00, "output_per_million": 30.00},
        "gpt-4o": {"input_per_million": 2.50, "output_per_million": 10.00},
        "gemini": {"input_per_million": 0.50, "output_per_million": 1.50},
        "default": {"input_per_million": 1.00, "output_per_million": 3.00}
      },
      "downtime_cost_per_minute": 10.00,
      "engineer_hourly_rate": 75.00
    }
Se o ConfigMap não existir, os valores padrão são usados. A atualização do ConfigMap é refletida em tempo real (watch no ConfigMap).

IncidentCost

Custo total de um incidente, decomposto em componentes:
CampoTipoDescrição
IncidentNamestringNome do incidente
NamespacestringNamespace
LLMCostCostBreakdownCusto das chamadas LLM
DowntimeCostfloat64Custo do downtime (minutos * custo/minuto)
TotalCostfloat64LLMCost.Total + DowntimeCost
ProviderstringProvedor LLM usado
ModelstringModelo LLM usado
Durationtime.DurationDuração total do incidente
AutoRemediatedboolSe foi resolvido automaticamente
CostBreakdown:
CampoTipoDescrição
InputTokensint64Total de tokens de input
OutputTokensint64Total de tokens de output
InputCostfloat64Custo dos tokens de input
OutputCostfloat64Custo dos tokens de output
Totalfloat64InputCost + OutputCost
CallsintNúmero de chamadas LLM
Exemplo de cálculo:
Incidente: CrashLoopBackOff no api-server
  - Provider: claude
  - Chamadas LLM: 2 (AnalyzeIssue + 1 AgenticStep)
  - Input tokens: 8,500 | Output tokens: 2,200
  - InputCost:  8,500 / 1,000,000 * $3.00  = $0.0255
  - OutputCost: 2,200 / 1,000,000 * $15.00 = $0.0330
  - LLMCost total: $0.0585

  - Downtime: 3 minutos
  - DowntimeCost: 3 * $10.00 = $30.00

  - TotalCost: $0.0585 + $30.00 = $30.06

CostSummary

Agregação de custos para um período:
CampoTipoDescrição
PeriodstringPeríodo de agregação (ex: 30d)
TotalLLMCostfloat64Soma de todos os custos LLM
TotalDowntimeCostfloat64Soma de todos os custos de downtime
TotalCostfloat64TotalLLMCost + TotalDowntimeCost
IncidentCountintTotal de incidentes no período
AutoRemediatedCountintIncidentes resolvidos automaticamente
AvgCostPerIncidentfloat64TotalCost / IncidentCount
TopCostlyIncidents[]IncidentCostTop 5 incidentes mais caros
CostByProvidermap[string]float64Custo agregado por provedor LLM
CostByNamespacemap[string]float64Custo agregado por namespace
ROIROICalculationCálculo de retorno sobre investimento

Cálculo de ROI

O ROI é calculado comparando o custo da automação com o custo estimado de resolução manual:
Variáveis:
  autoRemediated    = número de incidentes resolvidos automaticamente
  avgManualHours    = 2h (tempo estimado de resolução manual por incidente)
  engineerRate      = $75/hora (configurável via ConfigMap)
  downtimePrevented = autoRemediated * avgDowntimeMinutes
  downtimeCostRate  = $10/minuto (configurável via ConfigMap)

Cálculo:
  engineerHoursSaved = autoRemediated * avgManualHours
  laborSavings       = engineerHoursSaved * engineerRate
  downtimeSavings    = downtimePrevented * downtimeCostRate
  totalSavings       = laborSavings + downtimeSavings
  totalLLMCost       = soma de todos os custos LLM no período

  ROI% = ((totalSavings - totalLLMCost) / totalLLMCost) * 100
ROICalculation struct:
CampoTipoDescrição
EngineerHoursSavedfloat64Horas de engenheiro economizadas
LaborSavingsfloat64Economia com mão de obra ($)
DowntimePreventedfloat64Minutos de downtime prevenidos
DowntimeSavingsfloat64Economia com downtime ($)
TotalSavingsfloat64Economia total ($)
TotalLLMCostfloat64Custo total com LLM ($)
ROIPercentfloat64Retorno sobre investimento (%)
Exemplo de ROI mensal:
Dados do mês:
  - 312 incidentes resolvidos automaticamente
  - Custo total LLM: $18.72

Cálculo:
  engineerHoursSaved = 312 * 2h = 624 horas
  laborSavings       = 624 * $75 = $46,800
  downtimePrevented  = 312 * 4.5min = 1,404 minutos
  downtimeSavings    = 1,404 * $10 = $14,040
  totalSavings       = $46,800 + $14,040 = $60,840
  totalLLMCost       = $18.72

  ROI% = ($60,840 - $18.72) / $18.72 * 100 = 324,935%
O ROI tipicamente excede 100,000% porque o custo de chamadas LLM ($0.03-0.10 por incidente) é ordens de magnitude menor que o custo de resolução manual (2h de engenheiro + downtime).

Arquitetura de Armazenamento (ConfigMaps)

Todos os dados do Capacity Planner, Noise Reducer e Cost Tracker são persistidos em ConfigMaps no namespace do operator:
ConfigMapDadosRetenção
chatcli-capacity-historyHistórico de uso de CPU/memória por recurso. Série temporal compactada em JSON.7 dias (rolling window)
chatcli-pattern-storeHashes de dedup do Noise Reducer, contadores de supressão, flags de flap.24 horas (pruning automático)
chatcli-seasonal-patternsPadrões sazonais aprendidos (SeasonalPattern structs em JSON).Indefinido (padrões com Confidence < 0.3 e LastSeen > 30 dias são removidos)
chatcli-cost-ledgerRegistro de custos por incidente (IncidentCost em JSON). Usado para agregação.90 dias (rolling window)
chatcli-cost-configConfiguração de preços por provedor, custo de downtime, taxa de engenheiro.Indefinido (gerenciado pelo usuário)
ConfigMaps têm limite de 1MB no Kubernetes. Para clusters com alto volume de incidentes (>1000/mês), o Cost Tracker compacta registros antigos automaticamente, mantendo apenas agregações diárias para dados com mais de 30 dias.

Formato de Armazenamento

apiVersion: v1
kind: ConfigMap
metadata:
  name: chatcli-cost-ledger
  namespace: chatcli-system
  labels:
    app.kubernetes.io/component: cost-tracker
    platform.chatcli.io/managed-by: operator
data:
  ledger.json: |
    {
      "version": 2,
      "lastCompaction": "2026-03-19T00:00:00Z",
      "entries": [
        {
          "incident": "issue-crashloop-api-server-production",
          "namespace": "production",
          "timestamp": "2026-03-19T14:13:00Z",
          "llmCost": 0.0585,
          "downtimeCost": 30.00,
          "totalCost": 30.06,
          "provider": "claude",
          "autoRemediated": true,
          "durationSeconds": 180
        }
      ],
      "dailyAggregates": [
        {
          "date": "2026-03-18",
          "totalLLMCost": 0.62,
          "totalDowntimeCost": 350.00,
          "incidentCount": 12,
          "autoRemediatedCount": 11
        }
      ]
    }

Integrações

API REST

Endpoints /api/v1/analytics/remediation-stats e /api/v1/analytics/summary expõem dados de custo e capacidade.

Web Dashboard

A view Overview do dashboard exibe métricas de ROI e projeções de capacidade em tempo real.

Grafana

O dashboard remediation-stats.json inclui painéis de custo e ROI.

AIOps Platform

Arquitetura completa do pipeline AIOps e como estes subsistemas se integram.