DEV Community

Thiago da Silva
Thiago da Silva

Posted on

Instalação e Configuração do Grafana Agent

Documentação de Instalação e Configuração do Grafana Agent

Introdução ao Grafana Agent

O Grafana Agent é um binário único e leve que consolida múltiplas ferramentas de observabilidade em uma única solução. Ele substitui a necessidade de executar separadamente:

  • Prometheus para coleta de métricas
  • Promtail para coleta de logs
  • Node Exporter para métricas de sistema
  • cAdvisor para métricas de containers
  • Outros exporters do ecossistema Prometheus

Principais Vantagens

  • Único binário: Reduz complexidade operacional
  • Menor footprint: Menor uso de recursos comparado a múltiplos agentes
  • Remote Write nativo: Integração direta com Prometheus, Mimir, Cortex
  • Configuração unificada: Single YAML para todas as funcionalidades
  • Flexibilidade: Habilita/desabilita componentes conforme necessário

Arquitetura e Componentes

┌─────────────────────────────────────────────────────────────┐
│                    Grafana Agent                            │
├─────────────────┬─────────────────┬─────────────────────────┤
│   Integrations  │     Metrics     │         Logs            │
│                 │                 │                         │
│ ┌─────────────┐ │ ┌─────────────┐ │ ┌─────────────────────┐ │
│ │Node Exporter│ │ │ Prometheus  │ │ │     Promtail        │ │
│ │             │ │ │   Scraper   │ │ │                     │ │
│ │ ┌─────────┐ │ │ │             │ │ │ ┌─────────────────┐ │ │
│ │ │cAdvisor │ │ │ │ ┌─────────┐ │ │ │ │ Docker Logs     │ │ │
│ │ └─────────┘ │ │ │ │ WAL     │ │ │ │ │                 │ │ │
│ │             │ │ │ └─────────┘ │ │ │ │ Syslog          │ │ │
│ │ ┌─────────┐ │ │ │             │ │ │ │                 │ │ │
│ │ │Custom   │ │ │ │Remote Write │ │ │ │ File Logs       │ │ │
│ │ │Exporters│ │ │ │             │ │ │ └─────────────────┘ │ │
│ │ └─────────┘ │ │ └─────────────┘ │ │                     │ │
│ └─────────────┘ │                 │ └─────────────────────┘ │
└─────────────────┴─────────────────┴─────────────────────────┘
                        │                        │
                        ▼                        ▼
              ┌─────────────────┐    ┌─────────────────┐
              │ Mimir/Prometheus │    │      Loki       │
              │     Backend      │    │    Backend      │
              └─────────────────┘    └─────────────────┘
Enter fullscreen mode Exit fullscreen mode

Instalação do Grafana Agent

1. Download e Instalação

# Definir versão
AGENT_VERSION="v0.40.3"
ARCH="amd64"  # ou arm64 para ARM

# Download do binário
wget https://github.com/grafana/agent/releases/download/${AGENT_VERSION}/grafana-agent-linux-${ARCH}.zip

# Extrair e instalar
unzip grafana-agent-linux-${ARCH}.zip
sudo mv grafana-agent-linux-${ARCH} /usr/local/bin/grafana-agent
sudo chmod +x /usr/local/bin/grafana-agent

# Verificar instalação
grafana-agent --version
Enter fullscreen mode Exit fullscreen mode

2. Criação do Usuário e Diretórios

# Criar usuário grafana-agent
sudo useradd --system --no-create-home --shell /bin/false grafana-agent

# Criar diretórios necessários
sudo mkdir -p /etc/grafana-agent
sudo mkdir -p /var/lib/grafana-agent
sudo mkdir -p /var/log/grafana-agent

# Definir permissões
sudo chown -R grafana-agent:grafana-agent /var/lib/grafana-agent
sudo chown -R grafana-agent:grafana-agent /var/log/grafana-agent
sudo chown grafana-agent:grafana-agent /etc/grafana-agent
Enter fullscreen mode Exit fullscreen mode

3. Configuração do Systemd

Criar o arquivo de serviço:

sudo tee /etc/systemd/system/grafana-agent.service > /dev/null <<EOF
[Unit]
Description=Grafana Agent
Documentation=https://grafana.com/docs/agent/
Wants=network-online.target
After=network-online.target
Requires=network.target

[Service]
Type=simple
User=grafana-agent
Group=grafana-agent
ExecStart=/usr/local/bin/grafana-agent --config.file=/etc/grafana-agent/config.yaml --storage.path=/var/lib/grafana-agent
Restart=always
RestartSec=5
StandardOutput=journal
StandardError=journal

# Limites de recursos
LimitNOFILE=65536
LimitNPROC=32768

# Segurança
NoNewPrivileges=true
CapabilityBoundingSet=CAP_NET_BIND_SERVICE
AmbientCapabilities=CAP_NET_BIND_SERVICE
PrivateTmp=true
PrivateDevices=true
ProtectHome=true
ProtectSystem=strict
ReadWritePaths=/var/lib/grafana-agent /var/log/grafana-agent /tmp

[Install]
WantedBy=multi-user.target
EOF
Enter fullscreen mode Exit fullscreen mode

4. Habilitar e Iniciar o Serviço

# Recarregar systemd
sudo systemctl daemon-reload

# Habilitar para iniciar no boot
sudo systemctl enable grafana-agent

# Não iniciar ainda (vamos configurar primeiro)
# sudo systemctl start grafana-agent
Enter fullscreen mode Exit fullscreen mode

Configuração Completa

Arquivo de Configuração Principal

Criar o arquivo /etc/grafana-agent/config.yaml:

# /etc/grafana-agent/config.yaml

# Configurações do servidor
server:
  log_level: info
  log_format: logfmt
  http_listen_port: 9090
  grpc_listen_port: 9091

# Integrações (Exporters embutidos)
integrations:
  # Node Exporter integrado
  node_exporter:
    enabled: true
    # Caminhos para sistemas de arquivos
    rootfs_path: /
    sysfs_path: /sys
    procfs_path: /proc

    # Coletores habilitados
    set_collectors:
      - uname
      - cpu
      - loadavg
      - meminfo
      - filesystem
      - netdev
      - diskstats
      - cpufreq
      - os
      - time
      - xfs
      - cpu_guest_seconds_metric
      - boottime
      - systemd
      - processes
      - nvme
      - nfs
      - netstat
      - logind
      - stat
      - vmstat

    # Configurações de relabeling
    relabel_configs:
      - action: replace
        replacement: '${INSTANCE_NAME}'
        target_label: instance
      - action: replace
        replacement: '${TENANT_ID}'
        target_label: tenant

  # cAdvisor integrado (opcional)
  cadvisor:
    enabled: true
    docker_only: true
    instance: '${INSTANCE_NAME}'

    relabel_configs:
      - action: replace
        replacement: 'cadvisor'
        target_label: job
      - action: replace
        replacement: '${TENANT_ID}'
        target_label: tenant

    # Remover labels desnecessários
    metric_relabel_configs:
      - action: labeldrop
        regex: 'container_label_com_docker_compose_.*'
      - action: labeldrop
        regex: 'container_label_org_.*'

  # Process Exporter integrado (opcional)
  process_exporter:
    enabled: false
    config:
      process_names:
        - name: "{{.Comm}}"
          cmdline:
          - '.+'

# Configuração de Métricas
metrics:
  # Diretório para Write-Ahead Log
  wal_directory: /var/lib/grafana-agent/wal

  # Configurações globais
  global:
    scrape_interval: 30s
    scrape_timeout: 10s
    external_labels:
      cluster: '${CLUSTER_NAME}'
      region: '${AWS_REGION}'

    # Remote Write para Mimir/Prometheus
    remote_write:
      - url: https://mimir.${DOMAIN}/api/v1/push
        headers:
          X-Scope-OrgID: '${TENANT_ID}'

        # Configurações de queue
        queue_config:
          capacity: 10000
          max_samples_per_send: 2000
          batch_send_deadline: 5s
          min_shards: 1
          max_shards: 200

        # Configurações de retry
        write_relabel_configs:
          - source_labels: [__name__]
            regex: 'go_.*'
            action: drop

  # Configurações de scrape
  configs:
    - name: default
      scrape_configs:
        # Scrape do próprio agent
        - job_name: 'grafana-agent'
          static_configs:
            - targets: ['127.0.0.1:9090']
          scrape_interval: 30s
          relabel_configs:
            - action: replace
              replacement: '${INSTANCE_NAME}'
              target_label: instance

        # Scrape de aplicações locais
        - job_name: 'local-apps'
          static_configs:
            - targets: ['127.0.0.1:8080', '127.0.0.1:3000']
          scrape_interval: 15s
          relabel_configs:
            - action: replace
              replacement: '${INSTANCE_NAME}'
              target_label: instance
            - action: replace
              replacement: '${TENANT_ID}'
              target_label: tenant

        # Service Discovery via file
        - job_name: 'file-sd'
          file_sd_configs:
            - files:
              - '/etc/grafana-agent/targets/*.json'
              refresh_interval: 30s
          relabel_configs:
            - action: replace
              replacement: '${INSTANCE_NAME}'
              target_label: instance

# Configuração de Logs
logs:
  configs:
    - name: default
      # Cliente para Loki
      clients:
        - url: https://loki.${DOMAIN}/loki/api/v1/push
          headers:
            X-Scope-OrgID: '${TENANT_ID}'

          # Configurações de batching
          batchwait: 1s
          batchsize: 1048576

          # Configurações de retry
          backoff_config:
            min_period: 500ms
            max_period: 5m
            max_retries: 10

      # Arquivo de posições
      positions:
        filename: /var/lib/grafana-agent/positions.yaml

      # Configurações de scrape de logs
      scrape_configs:
        # Logs do Docker
        - job_name: docker
          docker_sd_configs:
            - host: "unix:///var/run/docker.sock"
              refresh_interval: 30s

          relabel_configs:
            - source_labels: [__meta_docker_container_name]
              target_label: container
            - source_labels: [__meta_docker_container_name]
              target_label: service_name
            - source_labels: [__meta_docker_container_log_stream]
              target_label: stream
            - action: replace
              replacement: '${INSTANCE_NAME}'
              target_label: instance
            - action: replace
              replacement: '${TENANT_ID}'
              target_label: tenant

        # Logs do sistema via journald
        - job_name: systemd
          journal:
            json: false
            max_age: 12h
            path: /var/log/journal

          relabel_configs:
            - source_labels: [__journal__systemd_unit]
              target_label: unit
            - source_labels: [__journal__hostname]
              target_label: hostname
            - action: replace
              replacement: '${INSTANCE_NAME}'
              target_label: instance
            - action: replace
              replacement: '${TENANT_ID}'
              target_label: tenant

        # Logs de arquivos específicos
        - job_name: syslog
          static_configs:
            - targets: [localhost]
              labels:
                job: syslog
                tenant: '${TENANT_ID}'
                __path__: /var/log/syslog

          relabel_configs:
            - action: replace
              target_label: instance
              replacement: '${INSTANCE_NAME}'

        # Logs de aplicações personalizadas
        - job_name: app-logs
          static_configs:
            - targets: [localhost]
              labels:
                job: app-logs
                tenant: '${TENANT_ID}'
                __path__: /var/log/myapp/*.log

          # Pipeline de processamento
          pipeline_stages:
            - json:
                expressions:
                  timestamp: timestamp
                  level: level
                  message: message
                  module: module

            - timestamp:
                source: timestamp
                format: RFC3339Nano

            - labels:
                level:
                module:

# Configuração de Traces (opcional)
traces:
  configs:
    - name: default
      receivers:
        jaeger:
          protocols:
            thrift_http:
              endpoint: 0.0.0.0:14268
            grpc:
              endpoint: 0.0.0.0:14250

        otlp:
          protocols:
            grpc:
              endpoint: 0.0.0.0:4317
            http:
              endpoint: 0.0.0.0:4318

      remote_write:
        - endpoint: https://tempo.${DOMAIN}:443
          headers:
            X-Scope-OrgID: '${TENANT_ID}'
Enter fullscreen mode Exit fullscreen mode

Arquivo de Variáveis de Ambiente

Criar /etc/grafana-agent/environment:

# /etc/grafana-agent/environment

# Identificação da instância
INSTANCE_NAME="server-001"
TENANT_ID="company"

# Cluster e região
CLUSTER_NAME="production"
AWS_REGION="us-east-1"

# Domínio base
DOMAIN="monitoring.company.com"

# Credenciais (se necessário)
# AWS_ACCESS_KEY_ID="your-access-key"
# AWS_SECRET_ACCESS_KEY="your-secret-key"
Enter fullscreen mode Exit fullscreen mode

Script de Configuração com Substituição de Variáveis

Criar /usr/local/bin/setup-grafana-agent.sh:

#!/bin/bash

# Script para configurar Grafana Agent com substituição de variáveis

set -e

# Carregar variáveis de ambiente
source /etc/grafana-agent/environment

# Função para substituir variáveis no arquivo de configuração
substitute_variables() {
    local config_file="/etc/grafana-agent/config.yaml"
    local temp_file="/tmp/config.yaml.tmp"

    # Substituir variáveis
    envsubst < "${config_file}.template" > "${temp_file}"

    # Validar configuração
    if grafana-agent --config.file="${temp_file}" --config.validate; then
        mv "${temp_file}" "${config_file}"
        chown grafana-agent:grafana-agent "${config_file}"
        echo "Configuração atualizada com sucesso"
    else
        echo "Erro na validação da configuração"
        rm -f "${temp_file}"
        exit 1
    fi
}

# Verificar se template existe
if [[ ! -f "/etc/grafana-agent/config.yaml.template" ]]; then
    echo "Template de configuração não encontrado"
    exit 1
fi

# Substituir variáveis
substitute_variables

# Recarregar serviço se estiver rodando
if systemctl is-active --quiet grafana-agent; then
    systemctl reload grafana-agent
    echo "Serviço recarregado"
fi
Enter fullscreen mode Exit fullscreen mode

Service Discovery Dinâmico

Configuração via File SD

Criar diretório para targets:

sudo mkdir -p /etc/grafana-agent/targets
sudo chown grafana-agent:grafana-agent /etc/grafana-agent/targets
Enter fullscreen mode Exit fullscreen mode

Exemplo de arquivo de targets (/etc/grafana-agent/targets/web-servers.json):

[
  {
    "targets": ["192.168.1.10:9100", "192.168.1.11:9100"],
    "labels": {
      "job": "node-exporter",
      "env": "production",
      "team": "infrastructure"
    }
  },
  {
    "targets": ["192.168.1.20:8080", "192.168.1.21:8080"],
    "labels": {
      "job": "web-app",
      "env": "production",
      "team": "backend"
    }
  }
]
Enter fullscreen mode Exit fullscreen mode

Scripts de Gerenciamento

Script de Status

#!/bin/bash
# /usr/local/bin/grafana-agent-status.sh

echo "=== Grafana Agent Status ==="
systemctl status grafana-agent --no-pager

echo ""
echo "=== Últimos logs ==="
journalctl -u grafana-agent --no-pager -n 20

echo ""
echo "=== Uso de recursos ==="
ps aux | grep grafana-agent | grep -v grep

echo ""
echo "=== Verificação de conectividade ==="
curl -s http://localhost:9090/-/ready && echo "Agent ready" || echo "Agent not ready"

echo ""
echo "=== Métricas de status ==="
curl -s http://localhost:9090/metrics | grep -E 'prometheus_agent_|agent_build_info'
Enter fullscreen mode Exit fullscreen mode

Script de Backup de Configuração

#!/bin/bash
# /usr/local/bin/backup-agent-config.sh

BACKUP_DIR="/var/backups/grafana-agent"
DATE=$(date +%Y%m%d_%H%M%S)

mkdir -p "$BACKUP_DIR"

# Backup da configuração
tar -czf "$BACKUP_DIR/grafana-agent-config-$DATE.tar.gz" \
    /etc/grafana-agent/ \
    /etc/systemd/system/grafana-agent.service

# Manter apenas últimos 10 backups
ls -t "$BACKUP_DIR"/grafana-agent-config-*.tar.gz | tail -n +11 | xargs -r rm

echo "Backup criado: $BACKUP_DIR/grafana-agent-config-$DATE.tar.gz"
Enter fullscreen mode Exit fullscreen mode

Inicialização e Verificação

Primeira Inicialização

# 1. Criar configuração a partir do template
sudo cp /etc/grafana-agent/config.yaml /etc/grafana-agent/config.yaml.template

# 2. Executar script de configuração
sudo /usr/local/bin/setup-grafana-agent.sh

# 3. Validar configuração
sudo grafana-agent --config.file=/etc/grafana-agent/config.yaml --config.validate

# 4. Iniciar serviço
sudo systemctl start grafana-agent

# 5. Verificar status
sudo systemctl status grafana-agent

# 6. Verificar logs
sudo journalctl -u grafana-agent -f
Enter fullscreen mode Exit fullscreen mode

Comandos de Verificação

# Status do serviço
systemctl status grafana-agent

# Logs em tempo real
journalctl -u grafana-agent -f

# Verificar se está escutando nas portas
ss -tulpn | grep grafana-agent

# Verificar métricas do agent
curl http://localhost:9090/metrics

# Verificar readiness
curl http://localhost:9090/-/ready

# Verificar configuração atual
curl http://localhost:9090/-/config

# Verificar targets descobertos
curl http://localhost:9090/api/v1/targets
Enter fullscreen mode Exit fullscreen mode

Monitoramento e Troubleshooting

Principais Métricas do Agent

# CPU usage do agent
rate(process_cpu_seconds_total{job="grafana-agent"}[5m])

# Memória utilizada
process_resident_memory_bytes{job="grafana-agent"}

# Samples enviados via remote write
rate(prometheus_remote_storage_samples_total[5m])

# Falhas no remote write
rate(prometheus_remote_storage_samples_failed_total[5m])

# WAL size
prometheus_tsdb_wal_size_bytes

# Logs enviados
rate(promtail_sent_entries_total[5m])
Enter fullscreen mode Exit fullscreen mode

Problemas Comuns e Soluções

1. Falhas no Remote Write

# Verificar conectividade
curl -I https://mimir.domain.com/api/v1/push

# Verificar certificados
openssl s_client -connect mimir.domain.com:443

# Verificar logs específicos
journalctl -u grafana-agent | grep "remote_write"
Enter fullscreen mode Exit fullscreen mode

2. Alto Uso de Memória

# Ajustar configurações no config.yaml
metrics:
  global:
    remote_write:
      - queue_config:
          capacity: 5000        # Reduzir de 10000
          max_samples_per_send: 1000  # Reduzir de 2000
Enter fullscreen mode Exit fullscreen mode

3. Logs Não Sendo Coletados

# Verificar permissões
ls -la /var/log/
ls -la /var/run/docker.sock

# Adicionar usuário ao grupo docker (para logs Docker)
sudo usermod -a -G docker grafana-agent
sudo systemctl restart grafana-agent
Enter fullscreen mode Exit fullscreen mode

Configurações Avançadas

Rate Limiting

metrics:
  configs:
    - name: default
      scrape_configs:
        - job_name: 'rate-limited-app'
          static_configs:
            - targets: ['app:8080']
          scrape_interval: 1m  # Menos frequente para apps sensíveis
          metrics_path: /metrics
          honor_labels: true
Enter fullscreen mode Exit fullscreen mode

Filtering de Métricas

metrics:
  global:
    remote_write:
      - url: https://mimir.domain.com/api/v1/push
        write_relabel_configs:
          # Drop métricas específicas
          - source_labels: [__name__]
            regex: 'go_gc_.*|go_memstats_.*'
            action: drop

          # Manter apenas métricas importantes
          - source_labels: [__name__]
            regex: 'up|cpu_usage_.*|memory_usage_.*'
            action: keep
Enter fullscreen mode Exit fullscreen mode

Multi-tenancy

metrics:
  global:
    remote_write:
      # Tenant A
      - url: https://mimir.domain.com/api/v1/push
        headers:
          X-Scope-OrgID: 'tenant-a'
        write_relabel_configs:
          - source_labels: [tenant]
            regex: 'tenant-a'
            action: keep

      # Tenant B  
      - url: https://mimir.domain.com/api/v1/push
        headers:
          X-Scope-OrgID: 'tenant-b'
        write_relabel_configs:
          - source_labels: [tenant]
            regex: 'tenant-b'
            action: keep
Enter fullscreen mode Exit fullscreen mode

Conclusão

O Grafana Agent oferece uma solução unificada e eficiente para observabilidade, consolidando múltiplas ferramentas em um único binário. Com remote write nativo e integrações embarcadas, simplifica significativamente a arquitetura de monitoramento, reduzindo a complexidade operacional e o overhead de recursos.

Benefícios da Implementação:

  1. Simplicidade: Um único agente para métricas, logs e traces
  2. Eficiência: Menor uso de recursos que múltiplos agentes
  3. Flexibilidade: Configuração modular por necessidade
  4. Escalabilidade: Remote write nativo para backends distribuídos
  5. Manutenção: Gerenciamento centralizado via systemd

Top comments (0)