Como criar dashboards operacionais com Grafana e Loki

1. Fundamentos da stack Grafana + Loki para operações

A combinação Grafana + Loki representa uma abordagem moderna para observabilidade operacional, especialmente quando o objetivo é criar dashboards que transformem logs brutos em métricas acionáveis. Diferente de soluções tradicionais como ELK (Elasticsearch, Logstash, Kibana), o Loki foi projetado para ser econômico e eficiente: ele não indexa o conteúdo dos logs, mas sim os metadados (labels), reduzindo drasticamente o custo de armazenamento e consulta.

No Loki, os dados são organizados em três conceitos fundamentais:
- Labels: pares chave-valor que identificam a origem do log (ex: job="api-gateway", instance="10.0.1.5:9090")
- Streams: agrupamentos de logs que compartilham o mesmo conjunto de labels
- Chunks: blocos comprimidos de logs armazenados no sistema de arquivos ou no object storage

Para dashboards operacionais, essa estrutura permite consultas rápidas sem a sobrecarga de índices invertidos. Enquanto o ELK indexa cada campo do log, o Loki apenas armazena os labels e o timestamp, tornando as consultas de agregação muito mais leves para cenários de alta cardinalidade.

2. Preparação do ambiente: conectando fontes de dados

A configuração começa com a adição do Loki como datasource no Grafana. No menu Configuration > Data Sources, adicione um datasource do tipo Loki, informando a URL do serviço (ex: http://loki:3100).

Para enviar logs, o Promtail é a ferramenta recomendada por sua integração nativa. Exemplo de configuração do Promtail para capturar logs de uma aplicação Node.js:

scrape_configs:
  - job_name: api-node
    static_configs:
      - targets: [localhost]
        labels:
          job: api-node
          service: payment-api
          environment: production
          __path__: /var/log/app/*.log
    pipeline_stages:
      - regex:
          expression: '^(?P<level>\w+)\s+(?P<message>.*)$'
      - labels:
          level:

No Grafana, as labels essenciais para dashboards operacionais são:
- job: identifica o tipo de serviço (ex: api, worker, database)
- instance: endereço específico do servidor
- level: nível de severidade (ERROR, WARN, INFO)
- service: nome lógico do microsserviço
- host: nome do servidor físico ou container

3. Construção de consultas LogQL para dashboards operacionais

LogQL é a linguagem de consulta do Loki, similar ao PromQL mas orientada a logs. A sintaxe básica segue o padrão:

{label_selectors} | pipeline_expression | aggregation

Exemplos práticos para dashboards operacionais:

Contagem de erros por serviço nos últimos 15 minutos:

sum by (service) (count_over_time({job=~"api|worker"} |= "ERROR" [15m]))

Taxa de requisições com latência acima de 2 segundos:

sum(rate({job="api-gateway"} | json | duration > 2.0 [5m]))

Top 5 hosts com mais logs de warning:

topk(5, sum by (host) (count_over_time({level="WARN"} [1h])))

As funções de métricas derivadas são essenciais:
- rate(): calcula a taxa por segundo de logs que correspondem ao filtro
- sum_over_time(): soma valores ao longo de um intervalo
- topk(): retorna os K maiores valores para rankings operacionais

4. Design de métricas operacionais a partir de logs

Transformar logs em séries temporais é o coração dos dashboards operacionais. O LogQL permite fazer isso com unwrap e seletores de métrica.

Exemplo: taxa de erros 5xx por serviço:

sum by (service) (
  rate({job="api-gateway"} | json | status_code >= 500 [5m])
)

Tempo médio de resposta extraído de logs JSON:

avg by (endpoint) (
  quantile_over_time(0.95,
    {job="api"} | json | unwrap response_time [10m]
  )
)

Criação de métrica para alerta de latência alta:

max by (service) (
  avg_over_time(
    {job="api"} | json | unwrap response_time [5m]
  )
) > 3.0

Essas consultas viram painéis no Grafana, permitindo que operadores visualizem tendências sem precisar acessar sistemas de métricas separados.

5. Montagem de dashboards com painéis operacionais chave

Um dashboard operacional típico com Grafana + Loki inclui três categorias de painéis:

Visão geral (topo do dashboard):
- Taxa de logs por nível (Gráfico de barras empilhadas)
- Volume de logs por serviço (Gráfico de área)
- Top 10 mensagens de erro mais frequentes (Tabela)

Análise de incidentes (meio):
- Timeline de erros por host (Gráfico de série temporal com cores por host)
- Distribuição de erros por ambiente (Gráfico de pizza)
- Logs brutos filtrados por nível e serviço (Painel de logs com drill-down)

Performance operacional (base):
- Latência extraída de logs (Percentis P50, P95, P99)
- Vazão de requisições por endpoint (Gráfico de linha)
- Picos de log (Thresholds dinâmicos com média móvel)

Exemplo de consulta para painel de latência P95:

quantile_over_time(0.95,
  {job="api"} | json | unwrap response_time [5m]
) by (endpoint)

6. Integração com alertas baseados em logs

No Grafana, é possível criar regras de alerta diretamente a partir de consultas LogQL. Exemplo de regra para detectar aumento anômalo de erros:

# Consulta de alerta
sum by (service) (
  rate({level="ERROR"} [5m])
) > 0.1

# Threshold dinâmico com média móvel
avg by (service) (
  rate({level="ERROR"} [1h])
) * 2

Configuração de alerta:
- Condição: WHEN last() OF query (A) IS ABOVE 0.1
- Avaliação: a cada 1 minuto, com período de 5 minutos
- Mensagem: "Aumento de erros detectado no serviço {{ $labels.service }}: {{ $value }} erros/segundo"

O encaminhamento pode ser feito para Slack, PagerDuty ou webhooks, incluindo o contexto do log no payload:

{
  "text": "Alerta Operacional: {{ $labels.service }} - {{ $labels.host }}",
  "attachments": [{
    "fields": [
      {"title": "Taxa de erros", "value": "{{ $value }}", "short": true},
      {"title": "Últimos logs", "value": "{{ $labels.message }}", "short": false}
    ]
  }]
}

7. Boas práticas para manutenção e otimização

Para garantir performance em dashboards operacionais:

Retenção e indexação:
- Configure retention_period no Loki para 7-30 dias dependendo do volume
- Use compactor para consolidar chunks e reduzir overhead de consulta
- Evite labels com alta cardinalidade (ex: UUIDs, IPs de clientes)

Variáveis de template no Grafana:

# Variável: service
query: label_values({job="api"}, service)

# Variável: environment
query: label_values({job="api"}, environment)

Drill-down entre painéis:
- Configure links nos painéis para abrir o Explore do Loki com o contexto atual
- Use $__auto_interval para ajustar automaticamente a resolução dos gráficos

Versionamento de dashboards:
- Exporte dashboards como JSON e versionamento no Git
- Use o Grafana Provisioning para deploy automatizado:

apiVersion: 1
providers:
  - name: 'operational-dashboards'
    orgId: 1
    folder: 'Operações'
    type: file
    options:
      path: /etc/grafana/provisioning/dashboards

Seguindo essas práticas, você terá dashboards operacionais escaláveis, que transformam logs em insights acionáveis com baixo custo operacional.

Referências