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.
  • curl instalado (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:

BloqueFunciónEjemplos
receiversEntrada de datos, por push o por pullotlp, hostmetrics, filelog, prometheus
processorsTransformación en tránsitomemory_limiter, batch, resourcedetection, attributes
exportersSalida hacia backendsdebug, prometheus, otlp, otlphttp
extensionsFunciones auxiliares que no tocan los datoshealth_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 ellas OTELCOL_OPTIONS con 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:

  • otlp escucha el protocolo nativo de OpenTelemetry por gRPC (4317) y HTTP (4318). Es lo que usan los SDK de OpenTelemetry por defecto.
  • hostmetrics recoge CPU, memoria, carga, disco, sistemas de ficheros y red del servidor cada 30 segundos, sin necesidad de instalar node_exporter.
  • filelog sigue /var/log/syslog. Con start_at: end solo lee las líneas nuevas y no reenvía todo el histórico al arrancar.
  • memory_limiter debe 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.
  • resourcedetection añade atributos como host.name y os.type a toda la telemetría.
  • batch agrupa los datos antes de exportarlos, lo que reduce mucho el número de peticiones. Debe ir el último.
  • debug escribe 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.
  • prometheus publica las métricas en http://servidor:8889/metrics para 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.

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.