OpenTelemetry Collector es un servicio que recibe telemetría (trazas, métricas y logs), la procesa y la reenvía a uno o varios backends sin que tus aplicaciones tengan que saber a dónde va. En este tutorial instalarás la distribución otelcol-contrib en Ubuntu 24.04, la configurarás para recibir datos OTLP de tus aplicaciones, recoger métricas del propio servidor y leer logs del sistema, y expondrás las métricas para que Prometheus las recoja. Al final añadirás un exportador OTLP para enviar trazas y logs a un backend externo.
Requisitos previos
Para seguir esta guía necesitas:
- Un servidor con Ubuntu 24.04 LTS de 64 bits (x86_64), por ejemplo un VPS de CubePath, con al menos 1 GB de RAM.
- Un usuario no root con privilegios
sudo. curlinstalado (viene por defecto en Ubuntu 24.04).- Opcional: un servidor Prometheus que pueda alcanzar este servidor por el puerto 8889, y un backend compatible con OTLP (Jaeger, Grafana Tempo, Grafana Cloud, etc.) para el último paso.
Cómo funciona la configuración del Collector
El Collector se configura con un único archivo YAML formado por cuatro bloques:
| Bloque | Función | Ejemplos |
|---|---|---|
receivers | Entrada de datos, por push o por pull | otlp, hostmetrics, filelog, prometheus |
processors | Transformación en tránsito | memory_limiter, batch, resourcedetection, attributes |
exporters | Salida hacia backends | debug, prometheus, otlp, otlphttp |
extensions | Funciones auxiliares que no tocan los datos | health_check, pprof, zpages |
Definir un componente no lo activa. Solo se ejecutan los que aparecen en service.pipelines (uno por tipo de señal: traces, metrics, logs) y en service.extensions. Además, puedes repetir un tipo de componente con un nombre distinto usando la sintaxis tipo/nombre, por ejemplo otlp/backend.
Existen dos distribuciones oficiales: otelcol, con pocos componentes, y otelcol-contrib, que incluye los receptores hostmetrics y filelog y el exportador prometheus. En esta guía usarás otelcol-contrib.
Paso 1: Instalar otelcol-contrib
El proyecto publica paquetes .deb en GitHub que crean el usuario de sistema otelcol-contrib, el servicio de systemd y una configuración de ejemplo. Consulta la última versión en la página de releases y guárdala en una variable (en el momento de escribir esta guía es la 0.161.0):
OTELCOL_VERSION=0.161.0
Descarga el paquete y su suma de comprobación:
cd /tmp
curl -fsSLO "https://github.com/open-telemetry/opentelemetry-collector-releases/releases/download/v${OTELCOL_VERSION}/otelcol-contrib_${OTELCOL_VERSION}_linux_amd64.deb"
curl -fsSLO "https://github.com/open-telemetry/opentelemetry-collector-releases/releases/download/v${OTELCOL_VERSION}/otelcol-contrib_${OTELCOL_VERSION}_linux_amd64.deb.sha256"
El archivo .sha256 solo contiene el hash, así que se compara añadiendo el nombre del paquete:
echo "$(cat otelcol-contrib_${OTELCOL_VERSION}_linux_amd64.deb.sha256) otelcol-contrib_${OTELCOL_VERSION}_linux_amd64.deb" | sha256sum -c
otelcol-contrib_0.161.0_linux_amd64.deb: OK
Instala el paquete con apt para que resuelva cualquier dependencia:
sudo apt install ./otelcol-contrib_${OTELCOL_VERSION}_linux_amd64.deb
Comprueba la versión y el estado del servicio, que el paquete habilita y arranca automáticamente:
otelcol-contrib --version
systemctl status otelcol-contrib --no-pager
otelcol-contrib version 0.161.0
● otelcol-contrib.service - OpenTelemetry Collector Contrib
Loaded: loaded (/usr/lib/systemd/system/otelcol-contrib.service; enabled; preset: enabled)
Active: active (running) since ...
El paquete instala estos archivos, que usarás en el resto de la guía:
/etc/otelcol-contrib/config.yaml: configuración del Collector./etc/otelcol-contrib/otelcol-contrib.conf: variables de entorno del servicio, entre ellasOTELCOL_OPTIONScon la ruta de la configuración./usr/bin/otelcol-contrib: el binario.
Paso 2: Escribir la configuración
La configuración de ejemplo activa receptores de Jaeger y Zipkin que probablemente no necesitas. Guarda una copia y sustitúyela por una propia:
sudo cp /etc/otelcol-contrib/config.yaml /etc/otelcol-contrib/config.yaml.orig
sudo nano /etc/otelcol-contrib/config.yaml
Borra el contenido y pega lo siguiente:
extensions:
health_check:
endpoint: 127.0.0.1:13133
receivers:
otlp:
protocols:
grpc:
endpoint: 0.0.0.0:4317
http:
endpoint: 0.0.0.0:4318
hostmetrics:
collection_interval: 30s
scrapers:
cpu:
memory:
load:
disk:
filesystem:
network:
filelog:
include:
- /var/log/syslog
start_at: end
processors:
memory_limiter:
check_interval: 1s
limit_percentage: 75
spike_limit_percentage: 15
resourcedetection:
detectors: [env, system]
batch:
exporters:
debug:
verbosity: basic
prometheus:
endpoint: 0.0.0.0:8889
resource_to_telemetry_conversion:
enabled: true
service:
extensions: [health_check]
pipelines:
traces:
receivers: [otlp]
processors: [memory_limiter, resourcedetection, batch]
exporters: [debug]
metrics:
receivers: [otlp, hostmetrics]
processors: [memory_limiter, resourcedetection, batch]
exporters: [prometheus]
logs:
receivers: [otlp, filelog]
processors: [memory_limiter, resourcedetection, batch]
exporters: [debug]
Qué hace cada parte:
otlpescucha el protocolo nativo de OpenTelemetry por gRPC (4317) y HTTP (4318). Es lo que usan los SDK de OpenTelemetry por defecto.hostmetricsrecoge CPU, memoria, carga, disco, sistemas de ficheros y red del servidor cada 30 segundos, sin necesidad de instalar node_exporter.filelogsigue/var/log/syslog. Constart_at: endsolo lee las líneas nuevas y no reenvía todo el histórico al arrancar.memory_limiterdebe ir el primero en cada pipeline: cuando el proceso supera el 75 % de la memoria disponible, rechaza datos en lugar de dejar que el kernel lo mate por falta de memoria.resourcedetectionañade atributos comohost.nameyos.typea toda la telemetría.batchagrupa los datos antes de exportarlos, lo que reduce mucho el número de peticiones. Debe ir el último.debugescribe un resumen de lo recibido en el journal. Sirve para comprobar que los datos llegan y lo sustituirás por un backend real en el paso 6.prometheuspublica las métricas enhttp://servidor:8889/metricspara que Prometheus las recoja.
Valida la sintaxis antes de reiniciar el servicio. El comando validate detecta claves mal escritas, componentes inexistentes y pipelines que referencian componentes no definidos:
sudo otelcol-contrib validate --config=/etc/otelcol-contrib/config.yaml
Si la configuración es correcta, el comando termina sin mostrar nada.
Paso 3: Dar acceso a los logs y reiniciar el servicio
En Ubuntu, /var/log/syslog pertenece al grupo adm con permisos 640, y el servicio se ejecuta como el usuario sin privilegios otelcol-contrib. Añádelo al grupo adm para que pueda leer los logs del sistema:
sudo usermod -aG adm otelcol-contrib
Reinicia el servicio para aplicar la configuración y el nuevo grupo:
sudo systemctl restart otelcol-contrib
Comprueba que responde la extensión health_check:
curl -s http://127.0.0.1:13133/
{"status":"Server available","upSince":"2026-09-25T10:15:02.114Z","uptime":"5.4s"}
Revisa también el journal. Deberías ver una línea Everything is ready y ningún error:
sudo journalctl -u otelcol-contrib -n 30 --no-pager
Con el exportador debug activo, cada vez que se escriba algo en syslog aparecerá una línea como esta:
info Logs {"otelcol.component.id": "debug", "otelcol.component.kind": "exporter", "otelcol.signal": "logs", "resource logs": 1, "log records": 3}
Paso 4: Enviar una traza de prueba
Para comprobar el pipeline de trazas sin instrumentar todavía una aplicación, envía un span en formato OTLP/JSON al endpoint HTTP con curl. El comando genera la marca de tiempo actual en nanosegundos:
NOW="$(date +%s)000000000"
curl -s -X POST http://localhost:4318/v1/traces \
-H 'Content-Type: application/json' \
-d '{"resourceSpans":[{"resource":{"attributes":[{"key":"service.name","value":{"stringValue":"prueba-curl"}}]},"scopeSpans":[{"spans":[{"traceId":"5b8efff798038103d269b633813fc60c","spanId":"eee19b7ec3c1b174","name":"span-de-prueba","kind":1,"startTimeUnixNano":"'"$NOW"'","endTimeUnixNano":"'"$NOW"'"}]}]}]}'
El Collector responde con un objeto vacío de éxito parcial, que significa que ha aceptado todos los datos:
{"partialSuccess":{}}
En el journal aparecerá el span:
sudo journalctl -u otelcol-contrib -n 5 --no-pager | grep Traces
info Traces {"otelcol.component.id": "debug", "otelcol.component.kind": "exporter", "otelcol.signal": "traces", "resource spans": 1, "spans": 1}
Tus aplicaciones instrumentadas con un SDK de OpenTelemetry enviarán datos al mismo sitio si defines en ellas la variable OTEL_EXPORTER_OTLP_ENDPOINT=http://your_server_ip:4318, donde your_server_ip es la IP de este servidor.
Paso 5: Recoger las métricas con Prometheus
Comprueba primero que el exportador prometheus publica las métricas del servidor. Los nombres OpenTelemetry con puntos se convierten a guiones bajos y los atributos de recurso aparecen como etiquetas gracias a resource_to_telemetry_conversion:
curl -s http://localhost:8889/metrics | grep '^system_cpu_load_average_1m'
system_cpu_load_average_1m{host_name="servidor-01",os_type="linux",otel_scope_name="github.com/open-telemetry/opentelemetry-collector-contrib/receiver/hostmetricsreceiver/internal/scraper/loadscraper",otel_scope_schema_url="",otel_scope_version="0.161.0"} 0.08
Las métricas pueden tardar hasta 30 segundos en aparecer tras el reinicio, que es el collection_interval de hostmetrics.
En el servidor de Prometheus, añade un trabajo de scrape en /etc/prometheus/prometheus.yml, dentro de scrape_configs:
- job_name: "otel-collector"
static_configs:
- targets: ["your_server_ip:8889"]
Comprueba la configuración y reinicia Prometheus:
promtool check config /etc/prometheus/prometheus.yml
sudo systemctl restart prometheus
En la interfaz de Prometheus, en Status > Targets, el trabajo otel-collector debe aparecer con estado UP.
Notael Collector también expone sus propias métricas internas (datos aceptados, rechazados y enviados por cada componente) en
http://127.0.0.1:8888/metrics. Las que empiezan porotelcol_exporter_send_failed_son las primeras que debes vigilar.
Paso 6: Reenviar trazas y logs a un backend OTLP
El exportador debug solo sirve para depurar. Para enviar las trazas y los logs a un backend real (Jaeger, Grafana Tempo, Grafana Cloud u otro servicio compatible con OTLP) añade un exportador otlp (gRPC) u otlphttp (HTTP). Este ejemplo usa otlphttp con autenticación por token.
Guarda el token en el archivo de entorno del servicio, no en el YAML:
sudo nano /etc/otelcol-contrib/otelcol-contrib.conf
Añade una línea al final, sustituyendo your_otlp_token por el token de tu proveedor:
OTLP_TOKEN=your_otlp_token
Restringe los permisos del archivo, ya que contiene una credencial. systemd lo lee como root, así que el servicio sigue funcionando:
sudo chmod 600 /etc/otelcol-contrib/otelcol-contrib.conf
Edita /etc/otelcol-contrib/config.yaml y añade el exportador dentro del bloque exporters, sustituyendo https://otlp.example.com por la URL base del endpoint OTLP/HTTP de tu backend (el exportador añade /v1/traces y /v1/logs por su cuenta):
otlphttp/backend:
endpoint: https://otlp.example.com
headers:
Authorization: "Bearer ${env:OTLP_TOKEN}"
sending_queue:
enabled: true
queue_size: 5000
retry_on_failure:
enabled: true
max_elapsed_time: 300s
Con sending_queue y retry_on_failure, si el backend deja de responder, el Collector guarda los lotes en memoria y los reintenta durante un máximo de cinco minutos en lugar de descartarlos al primer fallo.
Después, sustituye debug por el nuevo exportador en los pipelines de trazas y logs:
traces:
receivers: [otlp]
processors: [memory_limiter, resourcedetection, batch]
exporters: [otlphttp/backend]
metrics:
receivers: [otlp, hostmetrics]
processors: [memory_limiter, resourcedetection, batch]
exporters: [prometheus]
logs:
receivers: [otlp, filelog]
processors: [memory_limiter, resourcedetection, batch]
exporters: [otlphttp/backend]
Si tu backend usa gRPC (por ejemplo, Jaeger o Tempo en tu propia red, en el puerto 4317), usa en su lugar un exportador otlp/backend con endpoint: your_backend_host:4317. Si la conexión no lleva TLS, añade tls: con insecure: true.
Valida y reinicia:
sudo otelcol-contrib validate --config=/etc/otelcol-contrib/config.yaml
sudo systemctl restart otelcol-contrib
Repite el curl del paso 4 y comprueba que la traza span-de-prueba del servicio prueba-curl aparece en tu backend. Si hay un problema de conexión, el journal mostrará mensajes Exporting failed. Will retry the request after interval. con el error concreto.
Paso 7: Restringir el acceso con UFW
Los puertos 4317 y 4318 aceptan datos sin autenticación, así que solo deben estar abiertos a los servidores que envían telemetría. Del mismo modo, el 8889 solo debe ser accesible desde Prometheus. Sustituye app_server_ip y prometheus_server_ip por las IP correspondientes:
sudo ufw allow from app_server_ip to any port 4317:4318 proto tcp
sudo ufw allow from prometheus_server_ip to any port 8889 proto tcp
Si las aplicaciones y Prometheus corren en este mismo servidor, no abras nada y cambia 0.0.0.0 por 127.0.0.1 en los endpoints del receptor otlp y del exportador prometheus.
Comprueba las reglas activas:
sudo ufw status
Los puertos 13133 (health check) y 8888 (métricas internas) ya escuchan solo en 127.0.0.1, así que no necesitan reglas.
Solución de problemas
El servicio no arranca tras editar la configuración. Ejecuta sudo otelcol-contrib validate --config=/etc/otelcol-contrib/config.yaml. Los errores más habituales son una sangría incorrecta, un componente definido pero con un nombre distinto en pipelines, o un componente que no existe en la distribución instalada.
permission denied al leer /var/log/syslog. El usuario otelcol-contrib no está en el grupo adm o el servicio no se ha reiniciado después de añadirlo. Comprueba con id otelcol-contrib y reinicia el servicio.
bind: address already in use. Otro proceso ocupa el puerto, por ejemplo un Jaeger local en el 4317. Localízalo con sudo ss -ltnp | grep 4317 y cambia uno de los dos puertos.
data refused due to high memory usage en el journal. El memory_limiter está rechazando datos porque el proceso se acerca al límite. Reduce el volumen de entrada, añade memoria al servidor o reparte la carga entre varios Collectors.
Conclusión
Tienes OpenTelemetry Collector funcionando como servicio en Ubuntu 24.04, recibiendo telemetría OTLP de tus aplicaciones, recogiendo métricas y logs del propio servidor, publicando las métricas para Prometheus y reenviando trazas y logs a un backend con reintentos. Como siguientes pasos, puedes instrumentar tus aplicaciones con el SDK de OpenTelemetry de su lenguaje, añadir el procesador attributes para eliminar datos sensibles antes de exportarlos o desplegar un Collector por servidor que envíe a un Collector central actuando como gateway.
