Instalación y Configuración de Graylog

Graylog es una plataforma de gestión centralizada de logs que permite recopilar, indexar y analizar registros de múltiples fuentes en tiempo real. Con su backend en Elasticsearch y MongoDB, Graylog ofrece búsquedas potentes, dashboards configurables, alertas automatizadas y un sistema de pipelines para enriquecer y filtrar los logs antes de almacenarlos, convirtiéndolo en una solución completa para la observabilidad de infraestructuras.

Requisitos Previos

  • Ubuntu 22.04 o CentOS/Rocky Linux 8+
  • Mínimo 4 vCPUs y 8 GB de RAM (16 GB recomendado para producción)
  • 100 GB+ de espacio en disco (SSD para Elasticsearch)
  • Java 17+ (OpenJDK)
  • MongoDB 6.0+
  • Elasticsearch 7.x u OpenSearch 2.x

Instalación de los Componentes

# Instalar Java (requerido por Graylog y Elasticsearch)
apt update && apt install -y openjdk-17-jre-headless
java -version

# Instalar MongoDB 6.0
wget -qO - https://www.mongodb.org/static/pgp/server-6.0.asc | apt-key add -
echo "deb [ arch=amd64,arm64 ] https://repo.mongodb.org/apt/ubuntu jammy/mongodb-org/6.0 multiverse" \
  | tee /etc/apt/sources.list.d/mongodb-org-6.0.list

apt update && apt install -y mongodb-org
systemctl enable mongod && systemctl start mongod

# Verificar MongoDB
mongosh --eval "db.adminCommand('ping')"
# Instalar Elasticsearch 7.x (compatible con Graylog 5.x)
wget -qO - https://artifacts.elastic.co/GPG-KEY-elasticsearch | apt-key add -
echo "deb https://artifacts.elastic.co/packages/7.x/apt stable main" \
  | tee /etc/apt/sources.list.d/elasticsearch.list

apt update && apt install -y elasticsearch

# Configurar Elasticsearch para Graylog
cat > /etc/elasticsearch/elasticsearch.yml << 'EOF'
# Configuración de Elasticsearch para Graylog
cluster.name: graylog
node.name: graylog-es-1
path.data: /var/lib/elasticsearch
path.logs: /var/log/elasticsearch

# Bind solo a localhost (Graylog está en el mismo servidor)
network.host: 127.0.0.1
http.port: 9200

# Memoria heap (ajustar según la RAM disponible)
# Configurar en /etc/elasticsearch/jvm.options
# -Xms4g
# -Xmx4g

# Para un solo nodo
discovery.type: single-node
xpack.security.enabled: false
EOF

# Configurar la memoria heap de Elasticsearch
sed -i 's/-Xms1g/-Xms4g/' /etc/elasticsearch/jvm.options
sed -i 's/-Xmx1g/-Xmx4g/' /etc/elasticsearch/jvm.options

systemctl enable elasticsearch && systemctl start elasticsearch

# Verificar Elasticsearch
curl -s http://localhost:9200/_cluster/health | python3 -m json.tool
# Instalar Graylog Server
wget https://packages.graylog2.org/repo/packages/graylog-5.2-repository_latest.deb
dpkg -i graylog-5.2-repository_latest.deb
apt update && apt install -y graylog-server

# Graylog está instalado, ahora configurarlo
graylog-ctl --version

Configuración de Graylog Server

# Generar el password_secret (clave de cifrado interna)
pwgen -N 1 -s 96
# Guardar el resultado, lo necesitaremos en server.conf

# Generar el hash SHA-256 de la contraseña de admin
echo -n "tu-contraseña-admin-aqui" | sha256sum

# Editar la configuración principal de Graylog
cat > /etc/graylog/server/server.conf << 'EOF'
# Clave secreta para cifrar contraseñas (debe ser la misma en todos los nodos)
password_secret = clave-generada-con-pwgen-de-96-caracteres

# Contraseña de admin en SHA-256
root_password_sha2 = hash-sha256-de-tu-contraseña

# Nombre de usuario del administrador
root_username = admin

# Email del administrador
root_email = [email protected]

# Timezone por defecto
root_timezone = Europe/Madrid

# Interfaz web
http_bind_address = 0.0.0.0:9000
http_publish_uri = https://graylog.midominio.com/

# Elasticsearch
elasticsearch_hosts = http://127.0.0.1:9200
elasticsearch_index_prefix = graylog
elasticsearch_max_docs_per_index = 20000000
elasticsearch_max_number_of_indices = 20

# MongoDB
mongodb_uri = mongodb://localhost:27017/graylog

# Email (para alertas)
transport_email_enabled = true
transport_email_hostname = smtp.miempresa.com
transport_email_port = 587
transport_email_use_tls = true
transport_email_use_ssl = false
transport_email_auth_username = [email protected]
transport_email_auth_password = contraseña-smtp
transport_email_from_email = [email protected]
transport_email_subject_prefix = [Graylog]

# Número de workers de procesamiento de mensajes
processbuffer_processors = 5
outputbuffer_processors = 3

# Tamaño del ring buffer interno
ring_size = 65536

# Retención de índices
enabled_stale_master_election = false
EOF

# Ajustar la memoria JVM de Graylog
cat > /etc/default/graylog-server << 'EOF'
GRAYLOG_SERVER_JAVA_OPTS="-Xms2g -Xmx2g -XX:NewRatio=1 -server -XX:+ResizeTLAB -XX:-OmitStackTraceInFastThrow"
EOF

# Iniciar Graylog
systemctl enable graylog-server && systemctl start graylog-server
systemctl status graylog-server

# Acceder a la interfaz web: http://tu-servidor:9000
# Usuario: admin, contraseña: la que definiste en root_password_sha2

Configuración de Inputs

Los Inputs son los receptores de logs en Graylog. Se configuran desde la UI o la API REST.

# Crear un Input GELF UDP (para aplicaciones que envían logs en formato GELF)
curl -s -X POST \
  -H "Content-Type: application/json" \
  -u admin:contraseña \
  "http://localhost:9000/api/system/inputs" \
  -d '{
    "title": "GELF UDP",
    "type": "org.graylog2.inputs.gelf.udp.GELFUDPInput",
    "global": true,
    "configuration": {
      "bind_address": "0.0.0.0",
      "port": 12201,
      "recv_buffer_size": 1048576
    }
  }'

# Crear un Input Syslog UDP (para recibir logs de sistemas Linux)
curl -s -X POST \
  -H "Content-Type: application/json" \
  -u admin:contraseña \
  "http://localhost:9000/api/system/inputs" \
  -d '{
    "title": "Syslog UDP",
    "type": "org.graylog2.inputs.syslog.udp.SyslogUDPInput",
    "global": true,
    "configuration": {
      "bind_address": "0.0.0.0",
      "port": 514,
      "recv_buffer_size": 1048576,
      "allow_override_date": true,
      "store_full_message": false,
      "force_rdns": false
    }
  }'

# Configurar rsyslog en los servidores cliente para enviar a Graylog
cat > /etc/rsyslog.d/graylog.conf << 'EOF'
# Enviar todos los logs al servidor Graylog mediante UDP syslog
*.* @graylog.midominio.com:514
EOF

systemctl restart rsyslog

Streams y Pipelines

# Los Streams filtran mensajes en tiempo real y los dirigen a diferentes destinos
# Se configuran principalmente desde la UI web de Graylog

# Ejemplo de Stream mediante la API:
curl -s -X POST \
  -H "Content-Type: application/json" \
  -u admin:contraseña \
  "http://localhost:9000/api/streams" \
  -d '{
    "title": "Errores de Produccion",
    "description": "Logs de error de los servidores de produccion",
    "rules": [
      {
        "field": "level",
        "value": "3",
        "type": 1,
        "inverted": false
      },
      {
        "field": "source",
        "value": "prod-.*",
        "type": 2,
        "inverted": false
      }
    ],
    "matching_type": "AND",
    "remove_matches_from_default_stream": false
  }'

# Configurar una Pipeline Rule para enriquecer logs
# (vía UI: System → Pipelines → Manage Rules)
# Ejemplo de regla de pipeline:
cat << 'PIPELINE_RULE'
rule "Clasificar nivel de error"
when
  has_field("level")
then
  let level = to_long($message.level);
  let nivel_texto = if(level == 0, "emergency",
                    if(level == 1, "alert",
                    if(level == 2, "critical",
                    if(level == 3, "error",
                    if(level == 4, "warning",
                    if(level == 5, "notice",
                    if(level == 6, "info", "debug")))))));
  set_field("nivel_texto", nivel_texto);
end
PIPELINE_RULE

Dashboards

# Los dashboards se crean desde la UI de Graylog
# Widgets de dashboard disponibles:
# - Contador de mensajes
# - Histograma de mensajes
# - Términos más frecuentes (Top N)
# - Gráfico de campos
# - Mapa de estadísticas
# - Tabla de mensajes

# Exportar un dashboard como backup
curl -s \
  -u admin:contraseña \
  "http://localhost:9000/api/dashboards" \
  | python3 -m json.tool > dashboards-backup.json

# Ver estadísticas de los índices de Elasticsearch
curl -s \
  -u admin:contraseña \
  "http://localhost:9000/api/system/indexer/indices" \
  | python3 -m json.tool | grep -A3 "index_name"

Reglas de Alertas

# Crear una condición de alerta por número de mensajes
# (desde la UI: Alerts → Conditions → Add new condition)

# Vía API - Alerta cuando hay más de 10 errores en 5 minutos
curl -s -X POST \
  -H "Content-Type: application/json" \
  -u admin:contraseña \
  "http://localhost:9000/api/streams/<stream-id>/alerts/conditions" \
  -d '{
    "type": "message-count",
    "title": "Demasiados errores en produccion",
    "parameters": {
      "time": 5,
      "threshold": 10,
      "threshold_type": "more",
      "grace": 5,
      "backlog": 10
    }
  }'

# Crear una notificación de alerta por email
curl -s -X POST \
  -H "Content-Type: application/json" \
  -u admin:contraseña \
  "http://localhost:9000/api/alerts/notifications" \
  -d '{
    "title": "Notificacion Email SRE",
    "type": "org.graylog2.alarmcallbacks.EmailAlarmCallback",
    "configuration": {
      "sender": "[email protected]",
      "subject": "[ALERTA] ${stream.title}: ${alertCondition.title}",
      "receivers": "[email protected],[email protected]",
      "body": "Alerta en el stream ${stream.title}.\nCondicion: ${alertCondition.title}\nURL: ${stream.url}"
    }
  }'

Integración con Sistemas Externos

# Enviar logs desde una aplicación Python usando python-graypy
pip install graypy

# Ejemplo de código Python con GELF:
cat << 'PYTHON'
import logging
import graypy

# Configurar el logger para enviar a Graylog
logger = logging.getLogger('mi_aplicacion')
logger.setLevel(logging.DEBUG)

handler = graypy.GELFUDPHandler('graylog.midominio.com', 12201)
logger.addHandler(handler)

# Enviar logs con campos personalizados
logger.info('Usuario autenticado', 
            extra={'usuario_id': 123, 'ip': '192.168.1.1', 'servicio': 'api'})
logger.error('Error en el pago', 
             extra={'pedido_id': 456, 'error_code': 'PAYMENT_FAILED'})
PYTHON

# Configurar Filebeat para enviar logs de fichero a Graylog
cat > /etc/filebeat/filebeat.yml << 'EOF'
filebeat.inputs:
  - type: log
    enabled: true
    paths:
      - /var/log/nginx/access.log
      - /var/log/nginx/error.log
    tags: ["nginx", "produccion"]

output.logstash:
  # Usar Logstash si Graylog no tiene Beats input habilitado
  hosts: ["graylog.midominio.com:5044"]
  
# O directamente a Graylog con GELF output
# output.logstash no funciona con GELF directamente
# Usar el Beats input de Graylog:
# output.logstash:
#   hosts: ["graylog.midominio.com:5044"]
EOF

Solución de Problemas

Graylog no inicia:

# Ver los logs de inicio
journalctl -u graylog-server -f

# Verificar que MongoDB y Elasticsearch están accesibles
mongosh --eval "db.runCommand({ connectionStatus: 1 })"
curl -s http://localhost:9200/_cluster/health

# Verificar el archivo de configuración
grep -v "^#\|^$" /etc/graylog/server/server.conf

Los mensajes no aparecen en Graylog:

# Verificar que el input está recibiendo mensajes
curl -s -u admin:contraseña \
  "http://localhost:9000/api/system/inputs" | python3 -m json.tool

# Probar el envío de un mensaje de prueba
echo '{"version":"1.1","host":"servidor-prueba","short_message":"Test desde curl","level":6}' \
  | nc -u -w1 graylog.midominio.com 12201

# Verificar el throughput de mensajes
curl -s -u admin:contraseña \
  "http://localhost:9000/api/system/throughput" | python3 -m json.tool

Elasticsearch sin espacio en disco:

# Ver el uso de disco de los índices
curl -s "http://localhost:9200/_cat/indices?v&s=store.size:desc&h=index,store.size,docs.count"

# Eliminar índices antiguos manualmente
curl -X DELETE "http://localhost:9200/graylog_0"

# Configurar la rotación automática de índices en Graylog
# System → Indices → Default index set → Edit
# Establecer "Max number of indices" y "Index retention strategy"

Conclusión

Graylog proporciona una plataforma completa de gestión de logs que va más allá del simple almacenamiento: con sus streams, pipelines y dashboards configurables, permite extraer valor real de los logs de infraestructura y aplicaciones. Para equipos que gestionan múltiples servidores o aplicaciones, centralizar los logs en Graylog reduce significativamente el tiempo de diagnóstico de incidentes y permite detectar anomalías de forma proactiva mediante las reglas de alerta automatizadas.