Vector: Recolección y Transformación de Logs
Vector es una herramienta de observabilidad de alto rendimiento escrita en Rust que permite recolectar, transformar y enrutar logs, métricas y trazas con una latencia mínima. A diferencia de Logstash o Fluentd, Vector ofrece un consumo de recursos notablemente menor y un lenguaje de transformación propio (VRL) que facilita el procesamiento complejo de datos. Esta guía cubre la instalación en Linux, configuración de pipelines y la integración con stacks de monitoreo como Loki, Elasticsearch y Datadog.
Requisitos Previos
- Ubuntu 20.04/22.04, Debian 11+ o CentOS 8+/Rocky Linux 8+
- 512 MB de RAM mínimo (Vector es muy eficiente)
- Acceso a las fuentes de logs (archivos, Docker, syslog, etc.)
- Destino donde enviar los logs (Loki, Elasticsearch, S3, etc.)
Instalación de Vector
Instalación con el script oficial
# Método más sencillo: script de instalación oficial
curl --proto '=https' --tlsv1.2 -sSf https://sh.vector.dev | bash
# Verificar instalación
vector --version
Instalación con apt (Ubuntu/Debian)
# Añadir repositorio oficial de Vector
curl -1sLf 'https://repositories.timber.io/public/vector/cfg/setup/bash.deb.sh' | sudo bash
# Instalar Vector
sudo apt install -y vector
# Habilitar e iniciar el servicio
sudo systemctl enable vector --now
# Verificar estado
sudo systemctl status vector
Instalación con rpm (CentOS/Rocky)
# Añadir repositorio
curl -1sLf 'https://repositories.timber.io/public/vector/cfg/setup/bash.rpm.sh' | sudo bash
# Instalar
sudo dnf install -y vector
# Habilitar e iniciar
sudo systemctl enable vector --now
Instalación con Docker
# Ejecutar Vector como contenedor
docker run \
-d \
--name vector \
-v /etc/vector/vector.yaml:/etc/vector/vector.yaml:ro \
-v /var/log:/var/log:ro \
timberio/vector:latest-alpine
Conceptos Fundamentales
Vector organiza el procesamiento de datos en una topología con tres componentes:
- Sources: fuentes de datos (archivos de log, Docker, syslog, HTTP, Kafka...)
- Transforms: transformaciones aplicadas a los datos (parsing, filtrado, enriquecimiento...)
- Sinks: destinos donde se envían los datos procesados (Loki, Elasticsearch, S3, stdout...)
El archivo de configuración principal se encuentra en /etc/vector/vector.yaml.
Configuración de Fuentes (Sources)
# /etc/vector/vector.yaml
# Leer archivos de log del sistema
sources:
archivos_nginx:
type: file
include:
- /var/log/nginx/access.log
- /var/log/nginx/error.log
read_from: beginning # O "end" para solo logs nuevos
# Leer logs de contenedores Docker
docker_logs:
type: docker_logs
include_containers:
- mi-app
- mi-api
# Leer desde syslog
syslog_udp:
type: syslog
mode: udp
address: "0.0.0.0:514"
# Recibir datos via HTTP (webhook)
http_webhook:
type: http_server
address: "0.0.0.0:8080"
encoding:
codec: json
# Leer desde Kafka
kafka_input:
type: kafka
bootstrap_servers: "kafka:9092"
group_id: vector-consumer
topics:
- logs-aplicacion
decoding:
codec: json
Transformaciones con VRL
VRL (Vector Remap Language) es el lenguaje de transformación propio de Vector, diseñado para ser seguro y performante:
transforms:
# Parsear logs de Nginx con expresión regular
parsear_nginx:
type: remap
inputs:
- archivos_nginx
source: |
# Extraer campos del log de acceso de Nginx
parsed, err = parse_regex(.message, r'(?P<ip>\S+) \S+ \S+ \[(?P<timestamp>[^\]]+)\] "(?P<metodo>\S+) (?P<ruta>\S+) \S+" (?P<status>\d+) (?P<bytes>\d+)')
if err != null {
log("Error parseando log: " + string!(err), level: "warn")
abort
}
. = merge(., parsed)
.status = to_int!(.status)
.bytes = to_int!(.bytes)
# Añadir campo de nivel según el código HTTP
if .status >= 500 {
.nivel = "error"
} else if .status >= 400 {
.nivel = "warning"
} else {
.nivel = "info"
}
# Filtrar logs: solo errores HTTP 5xx
solo_errores:
type: filter
inputs:
- parsear_nginx
condition: '.status >= 500'
# Enriquecer con geolocalización IP
enriquecer_geo:
type: remap
inputs:
- parsear_nginx
source: |
# Resolver geolocalización de la IP del cliente
.geo = get_enrichment_table_record!("geoip", {"ip": .ip})
# Deduplicar eventos repetidos
deduplicar:
type: dedupe
inputs:
- parsear_nginx
fields:
match:
- ip
- ruta
- status
cache:
max_events: 5000
# Agregar métricas desde logs
metricas_nginx:
type: log_to_metric
inputs:
- parsear_nginx
metrics:
- type: counter
field: status
name: nginx_peticiones_total
tags:
status: "{{status}}"
metodo: "{{metodo}}"
Destinos (Sinks)
sinks:
# Enviar a Loki (Grafana)
loki:
type: loki
inputs:
- parsear_nginx
endpoint: http://loki:3100
encoding:
codec: json
labels:
job: nginx
host: "{{ host }}"
nivel: "{{ nivel }}"
# Enviar a Elasticsearch / OpenSearch
elasticsearch:
type: elasticsearch
inputs:
- parsear_nginx
endpoints:
- http://elasticsearch:9200
index: "logs-nginx-%Y-%m-%d"
auth:
strategy: basic
user: elastic
password: contraseña_elastic
# Enviar a S3 para archivado a largo plazo
s3_archivo:
type: aws_s3
inputs:
- parsear_nginx
bucket: mi-bucket-logs
region: eu-west-1
key_prefix: "logs/nginx/%Y/%m/%d/"
encoding:
codec: json
compression: gzip
batch:
max_bytes: 10000000 # Archivos de ~10 MB
timeout_secs: 300 # O cada 5 minutos
# Enviar métricas a Prometheus (via remote_write)
prometheus:
type: prometheus_remote_write
inputs:
- metricas_nginx
endpoint: http://prometheus:9090/api/v1/write
# Enviar a Datadog
datadog:
type: datadog_logs
inputs:
- solo_errores
default_api_key: "${DATADOG_API_KEY}"
site: datadoghq.eu
# Salida por consola (útil para depuración)
consola:
type: console
inputs:
- parsear_nginx
encoding:
codec: json
Ejemplo de Pipeline Completo
Aquí un pipeline funcional completo para recolectar logs de aplicaciones Docker y enviarlos a Loki:
# /etc/vector/vector.yaml - Pipeline completo para Docker + Loki
sources:
docker:
type: docker_logs
include_labels:
vector.enable: "true"
transforms:
parsear_json:
type: remap
inputs:
- docker
source: |
# Intentar parsear el mensaje como JSON estructurado
structured, err = parse_json(.message)
if err == null {
. = merge(., structured)
}
# Normalizar el campo de nivel de log
.nivel = downcase(string!(.level ?? .severity ?? .lvl ?? "info"))
# Eliminar campos internos de Docker que no necesitamos
del(.stream)
del(.source_type)
filtrar_health:
type: filter
inputs:
- parsear_json
condition: '!includes(["GET /health", "GET /ping"], .message)'
sinks:
loki:
type: loki
inputs:
- filtrar_health
endpoint: http://loki:3100
encoding:
codec: json
labels:
job: "{{ container_name }}"
nivel: "{{ nivel }}"
host: "{{ host }}"
batch:
max_bytes: 1048576
timeout_secs: 5
# Validar la configuración antes de aplicarla
vector validate /etc/vector/vector.yaml
# Probar la configuración en modo dry-run
vector tap --config /etc/vector/vector.yaml
# Recargar configuración sin reiniciar
sudo systemctl reload vector
# Ver métricas internas de Vector
vector top
Solución de Problemas
Vector no lee archivos de log:
# Verificar permisos del usuario vector sobre los archivos
ls -la /var/log/nginx/
sudo usermod -aG adm vector # Añadir vector al grupo que lee logs
# Reiniciar el servicio
sudo systemctl restart vector
Los logs no llegan al destino:
# Revisar logs de Vector
sudo journalctl -u vector -f
# Activar modo debug temporalmente
VECTOR_LOG=debug vector --config /etc/vector/vector.yaml
# Usar sink de consola para depurar el pipeline
# Añadir temporalmente:
# sinks:
# debug:
# type: console
# inputs: [nombre_transform]
# encoding:
# codec: json
Error de conexión a Loki/Elasticsearch:
# Verificar conectividad de red
curl -v http://loki:3100/ready
curl -v http://elasticsearch:9200/_cluster/health
# Revisar que las URLs en la configuración sean correctas
vector validate --config /etc/vector/vector.yaml
Consumo de memoria elevado:
# Limitar el buffer de Vector en la configuración del sink
sinks:
loki:
# ... configuración ...
buffer:
type: memory
max_events: 500
when_full: drop_newest
Conclusión
Vector es una herramienta excepcional para construir pipelines de observabilidad eficientes gracias a su bajo consumo de recursos, su velocidad y la potencia de VRL para transformaciones complejas. Su arquitectura declarativa permite definir topologías completas en un solo archivo YAML, facilitando el mantenimiento y la gestión como código. Integrado con herramientas como Loki, Elasticsearch o Datadog, Vector se convierte en la pieza central de cualquier stack de observabilidad moderno.


