How to Set Up OpenTelemetry Collector on RHEL 7

OpenTelemetry is the emerging industry standard for collecting telemetry data — traces, metrics, and logs — from applications and infrastructure. The OpenTelemetry Collector acts as a vendor-agnostic pipeline component that receives telemetry from instrumented applications, processes it, and exports it to one or more backends such as Jaeger, Prometheus, or any compatible observability platform. Running the Collector as a managed systemd service on RHEL 7 gives you a reliable, centralised telemetry aggregation point that can forward data to multiple destinations simultaneously without requiring changes to your application code.

Prerequisites

  • RHEL 7 server with root or sudo access
  • An instrumented application sending OTLP traces or metrics (gRPC on port 4317 or HTTP on port 4318)
  • Jaeger or another tracing backend running and accessible (optional but recommended)
  • Prometheus scraping endpoint or push receiver configured (optional)
  • At least 512 MB free RAM; 1 GB or more recommended for production workloads
  • curl and wget available on the host

Step 1: Download the OpenTelemetry Collector Binary

The OpenTelemetry project publishes pre-compiled binaries for Linux amd64 on GitHub. The Collector comes in two flavours: the core distribution and the contrib distribution. The contrib release includes receivers and exporters for a much wider range of backends and is recommended for most deployments.

OTEL_VERSION="0.99.0"
cd /tmp
wget https://github.com/open-telemetry/opentelemetry-collector-releases/releases/download/v${OTEL_VERSION}/otelcol-contrib_${OTEL_VERSION}_linux_amd64.tar.gz
tar -xzf otelcol-contrib_${OTEL_VERSION}_linux_amd64.tar.gz

Move the binary to a standard location and make it executable:

sudo mv otelcol-contrib /usr/local/bin/otelcol
sudo chmod +x /usr/local/bin/otelcol
otelcol --version

Step 2: Create the otelcol System User and Directories

Run the Collector as a dedicated low-privilege user to limit the blast radius of any security issues:

sudo useradd -r -s /sbin/nologin -d /var/lib/otelcol otelcol
sudo mkdir -p /etc/otelcol /var/log/otelcol
sudo chown otelcol:otelcol /var/log/otelcol

Step 3: Write the Collector Configuration File

The Collector is configured with a YAML file that defines four pipeline sections: receivers, processors, exporters, and service. The service section wires them together into named pipelines. Create /etc/otelcol/config.yaml:

sudo tee /etc/otelcol/config.yaml <<'EOF'
receivers:
  otlp:
    protocols:
      grpc:
        endpoint: "0.0.0.0:4317"
      http:
        endpoint: "0.0.0.0:4318"

processors:
  batch:
    timeout: 5s
    send_batch_size: 1024
  memory_limiter:
    check_interval: 1s
    limit_mib: 512
    spike_limit_mib: 128

exporters:
  logging:
    loglevel: debug
  prometheus:
    endpoint: "0.0.0.0:8888"
    namespace: otelcol
  jaeger:
    endpoint: "localhost:14250"
    tls:
      insecure: true

service:
  pipelines:
    traces:
      receivers: [otlp]
      processors: [memory_limiter, batch]
      exporters: [jaeger, logging]
    metrics:
      receivers: [otlp]
      processors: [memory_limiter, batch]
      exporters: [prometheus, logging]
  telemetry:
    logs:
      level: "info"
EOF

Set correct ownership so the service account can read the config:

sudo chown root:otelcol /etc/otelcol/config.yaml
sudo chmod 640 /etc/otelcol/config.yaml

Step 4: Create the systemd Service Unit

Create a systemd unit file to manage the Collector lifecycle:

sudo tee /etc/systemd/system/otelcol.service <<'EOF'
[Unit]
Description=OpenTelemetry Collector
Documentation=https://opentelemetry.io
After=network.target

[Service]
Type=simple
User=otelcol
Group=otelcol
ExecStart=/usr/local/bin/otelcol --config /etc/otelcol/config.yaml
Restart=on-failure
RestartSec=5s
LimitNOFILE=65536
StandardOutput=journal
StandardError=journal

[Install]
WantedBy=multi-user.target
EOF

Reload systemd, enable the service, and start it:

sudo systemctl daemon-reload
sudo systemctl enable otelcol
sudo systemctl start otelcol
sudo systemctl status otelcol

Inspect the service journal to confirm it started without errors:

sudo journalctl -u otelcol -f --no-pager

You should see lines reporting that the OTLP receiver started on ports 4317 and 4318, the Prometheus exporter started on port 8888, and the Jaeger exporter connected to port 14250.

Step 5: Open Firewall Ports

Expose the OTLP receiver ports so instrumented applications can send telemetry from other hosts:

sudo firewall-cmd --permanent --add-port=4317/tcp
sudo firewall-cmd --permanent --add-port=4318/tcp
sudo firewall-cmd --permanent --add-port=8888/tcp
sudo firewall-cmd --reload

Step 6: Configure Your Application to Send OTLP Telemetry

With the Collector running, configure your application’s OpenTelemetry SDK to export to the Collector’s OTLP endpoint. For a Python application using opentelemetry-sdk:

# Install required packages
pip install opentelemetry-sdk opentelemetry-exporter-otlp-proto-grpc

# Set OTLP endpoint via environment variable
export OTEL_EXPORTER_OTLP_ENDPOINT="http://192.168.1.100:4317"
export OTEL_SERVICE_NAME="my-python-app"
export OTEL_TRACES_EXPORTER="otlp"
export OTEL_METRICS_EXPORTER="otlp"

For a Java Spring Boot application using the OpenTelemetry Java agent:

java -javaagent:/opt/opentelemetry-javaagent.jar 
     -Dotel.exporter.otlp.endpoint=http://192.168.1.100:4317 
     -Dotel.service.name=spring-app 
     -jar /opt/myapp.jar

Step 7: View Traces in Jaeger

If Jaeger is running (see the Jaeger installation tutorial), open its UI at http://<jaeger-host>:16686. After your application generates a few requests, select your service name from the Service dropdown and click Find Traces. Each trace represents one request’s journey through your system. Click a trace to see the individual spans, their durations, and any attached attributes or events.

Step 8: View Metrics in Prometheus and Grafana

The Collector’s Prometheus exporter exposes metrics at http://<collector-host>:8888/metrics. Add this as a scrape target in your Prometheus configuration:

# In /etc/prometheus/prometheus.yml
scrape_configs:
  - job_name: 'otelcol'
    static_configs:
      - targets: ['192.168.1.100:8888']
  - job_name: 'app-metrics'
    static_configs:
      - targets: ['192.168.1.100:8888']

Reload Prometheus after editing:

sudo systemctl reload prometheus

In Grafana, import the OpenTelemetry Collector dashboard (ID 15983 from grafana.com/dashboards) to visualise pipeline throughput, dropped spans, and memory utilisation of the Collector itself.

Step 9: Advanced Configuration — Tail Sampling and Filtering

In high-traffic environments you may not want to store every trace. The tail_sampling processor (available in the contrib distribution) makes sampling decisions after seeing the complete trace, allowing you to keep all error traces while sampling successful ones at a lower rate:

# Add to the processors section in /etc/otelcol/config.yaml
processors:
  tail_sampling:
    decision_wait: 10s
    num_traces: 100000
    expected_new_traces_per_sec: 10
    policies:
      - name: keep-errors
        type: status_code
        status_code: {status_codes: [ERROR]}
      - name: probabilistic-sample
        type: probabilistic
        probabilistic: {sampling_percentage: 10}

Apply the change by restarting the service:

sudo systemctl restart otelcol

The OpenTelemetry Collector is the cornerstone of a modern observability pipeline on RHEL 7. Its receiver-processor-exporter architecture allows you to change backends without modifying application code, fan out telemetry to multiple destinations simultaneously, and apply enrichment and filtering in a centralised location. As your microservices estate grows, deploying the Collector as a daemonset or sidecar pattern keeps telemetry handling consistent and your application code free of backend-specific SDK configuration.