Skip to main content

Linux

Install and configure the Scout Collector on Linux systems.

Whether you're using Debian, Red Hat, or other Linux distributions, you'll learn how to set up telemetry collection for your observability needs.

Overview

The Scout Collector is a vendor-agnostic agent that collects, processes, and exports telemetry data. This guide covers:

  • Installing Scout Collector via DEB packages (Ubuntu, Debian)
  • Installing Scout Collector via RPM packages (RHEL, CentOS, Fedora)
  • Manual installation for other Linux distributions
  • Configuring receivers for host metrics, container logs, journald logs, and Prometheus endpoints
  • Exporting telemetry to Scout and storing credentials securely
  • Running as a systemd service and verifying the pipeline
  • Troubleshooting and logging

System Requirements

  • Linux operating system (amd64/arm64/i386)
  • systemd for service management
  • Root or sudo access
  • Minimum 512MB RAM
  • 1GB free disk space

Package Availability

Official Scout Collector packages are available in the following formats:

  • DEB packages for Debian-based systems
  • RPM packages for Red Hat-based systems
  • Precompiled binaries for manual installation

Default configuration path: /etc/otelcol-contrib/config.yaml

DEB Installation

To install the Scout Collector on Debian-based systems, run the following commands:

sudo apt-get update
sudo apt-get -y install wget
wget https://github.com/open-telemetry/opentelemetry-collector-releases/releases/download/v0.127.0/otelcol-contrib_0.127.0_linux_amd64.deb
sudo dpkg -i otelcol-contrib_0.127.0_linux_amd64.deb

RPM Installation

To install the Scout Collector on Red Hat-based systems, run the following commands:

sudo yum update
sudo yum -y install wget systemctl
wget https://github.com/open-telemetry/opentelemetry-collector-releases/releases/download/v0.127.0/otelcol-contrib_0.127.0_linux_amd64.rpm
sudo rpm -ivh otelcol-contrib_0.127.0_linux_amd64.rpm

Manual Linux Installation

The OpenTelemetry Collector releases are available for various architectures. You can download the binary and install it manually:

curl --proto '=https' --tlsv1.2 -fOL https://github.com/open-telemetry/opentelemetry-collector-releases/releases/download/v0.127.0/otelcol-contrib_0.127.0_linux_amd64.tar.gz
tar -xvf otelcol-contrib_0.127.0_linux_amd64.tar.gz

Configure Telemetry Collection

After installation, edit /etc/otelcol-contrib/config.yaml to define what telemetry the Scout Collector gathers from the machine and where it sends it. A configuration is built from receivers (what to collect), processors (how to enrich and batch), an exporter (where to send), and pipelines that wire them together.

Receivers

Host metrics

The hostmetrics receiver collects CPU, memory, disk, filesystem, network, and load metrics from the host:

receivers:
hostmetrics:
collection_interval: 60s
scrapers:
cpu:
memory:
load:
disk:
filesystem:
network:
paging:
processes:

Listing a scraper by name, as above, enables it with its default set of metrics — you don't need to enumerate individual metrics to get the usual CPU, memory, disk, and network signals. Some metrics are opt-in and stay off until you ask for them, such as the percentage-based system.cpu.utilization and system.memory.utilization. Enable an opt-in metric (or disable a default one) under a metrics: block:

receivers:
hostmetrics:
scrapers:
cpu:
metrics:
system.cpu.utilization:
enabled: true

The processes scraper above reports lightweight, system-wide process counts and needs no special privileges. A separate process scraper (not shown) reports per-process metrics and needs elevated privileges to read other users' entries under /proc — see Running with elevated privileges.

Container logs (Docker)

When applications run as Docker containers, their stdout and stderr are written to JSON log files under /var/lib/docker/containers. The filelog receiver tails these files, and the container operator unwraps Docker's JSON envelope into the log body:

receivers:
filelog:
include: [/var/lib/docker/containers/*/*-json.log]
start_at: end
include_file_path: true
operators:
- type: container
format: docker
add_metadata_from_filepath: false

Leave add_metadata_from_filepath set to false. That option exists to extract pod, namespace, and container names from Kubernetes pod log paths (/var/log/pods/...); a Docker log path has no such structure, so setting it true makes every record fail with failed to detect a valid log path.

/var/lib/docker/containers is readable only by root, so the collector must run as root to tail these files — see Running with elevated privileges.

If your application logs in JSON, add a json_parser to lift its fields into attributes and a severity_parser to set the log severity:

- type: json_parser
parse_from: body
on_error: send
- type: severity_parser
parse_from: attributes.level
on_error: send

on_error: send keeps any non-JSON lines flowing instead of dropping them, so startup banners and stack traces are preserved.

System and journald logs

For services managed by systemd, the journald receiver reads the journal directly. For plain text log files, use a filelog receiver:

receivers:
journald:
units: [my-service]
filelog/syslog:
include: [/var/log/syslog, /var/log/messages]
start_at: end

Scrape a Prometheus endpoint

Many applications expose metrics on a Prometheus /metrics endpoint. The prometheus receiver scrapes them on an interval:

receivers:
prometheus/app:
config:
scrape_configs:
- job_name: my-app
scrape_interval: 30s
metrics_path: /metrics
static_configs:
- targets: [localhost:8080]

The target must be reachable from the host where the collector runs. If the application runs in a Docker container, its container-network name (for example my-app:8080) does not resolve from the host. Publish the metrics port and scrape localhost:<port>, or use the container's bridge IP:

docker port <container>

Export to Scout

Send the collected telemetry to Scout with the oauth2client extension and an otlphttp exporter. Replace the tenant placeholder with your Scout tenant, and supply credentials via environment variables (see Store credentials securely):

extensions:
oauth2client:
client_id: ${env:SCOUT_CLIENT_ID}
client_secret: ${env:SCOUT_CLIENT_SECRET}
endpoint_params:
audience: b14collector
token_url: https://id.b14.dev/realms/__YOUR_TENANT__/protocol/openid-connect/token
tls:
insecure_skip_verify: true

exporters:
otlphttp/b14:
endpoint: https://otel.play.b14.dev/__YOUR_TENANT__/otlp
auth:
authenticator: oauth2client
tls:
insecure_skip_verify: true

For the full list of tenant, endpoint, and authentication options, see Scout Exporter Configuration.

Store credentials securely

Keep secrets out of config.yaml by referencing environment variables with ${env:VAR} and defining them in the systemd environment file at /etc/otelcol-contrib/otelcol-contrib.conf:

SCOUT_CLIENT_ID=__YOUR_CLIENT_ID__
SCOUT_CLIENT_SECRET=__YOUR_CLIENT_SECRET__

Keep the existing OTELCOL_OPTIONS line in that file. Then restrict the file's permissions so the secret is not world-readable:

sudo chmod 600 /etc/otelcol-contrib/otelcol-contrib.conf

systemd loads this file when the service starts, so restart the collector after changing it.

Complete configuration

The following config combines host metrics and Docker container logs with a Scout exporter, wired into metrics and logs pipelines. Save it to /etc/otelcol-contrib/config.yaml:

extensions:
health_check:
endpoint: 0.0.0.0:13133
oauth2client:
client_id: ${env:SCOUT_CLIENT_ID}
client_secret: ${env:SCOUT_CLIENT_SECRET}
endpoint_params:
audience: b14collector
token_url: https://id.b14.dev/realms/__YOUR_TENANT__/protocol/openid-connect/token
tls:
insecure_skip_verify: true

receivers:
hostmetrics:
collection_interval: 60s
scrapers:
cpu:
memory:
load:
disk:
filesystem:
network:
filelog:
include: [/var/lib/docker/containers/*/*-json.log]
start_at: end
include_file_path: true
operators:
- type: container
format: docker
add_metadata_from_filepath: false
- type: json_parser
parse_from: body
on_error: send
- type: severity_parser
parse_from: attributes.level
on_error: send

processors:
memory_limiter:
check_interval: 5s
limit_percentage: 80
spike_limit_percentage: 30
resourcedetection:
detectors: [system]
timeout: 5s
resource:
attributes:
- key: environment
value: production
action: upsert
batch:
timeout: 2s
send_batch_size: 8192
send_batch_max_size: 10000

exporters:
otlphttp/b14:
endpoint: https://otel.play.b14.dev/__YOUR_TENANT__/otlp
auth:
authenticator: oauth2client
tls:
insecure_skip_verify: true

service:
extensions: [health_check, oauth2client]
pipelines:
metrics:
receivers: [hostmetrics]
processors: [memory_limiter, resourcedetection, resource, batch]
exporters: [otlphttp/b14]
logs:
receivers: [filelog]
processors: [memory_limiter, resourcedetection, resource, batch]
exporters: [otlphttp/b14]

Add the journald, filelog/syslog, or prometheus/app receivers from above to the relevant pipeline as needed.

Configuring the Scout Collector Service

By default, the otelcol-contrib systemd service starts with the --config=/etc/otelcol-contrib/config.yaml option after installation. This configuration follows the Scout Collector Configuration standards.

To customize the collector settings, modify the OTELCOL_OPTIONS variable in the /etc/otelcol-contrib/otelcol-contrib.conf systemd environment file with appropriate command-line options. Run /usr/bin/otelcol-contrib --help to see all available options. Additional environment variables can be passed to the otelcol-contrib service by adding them to this file.

After modifying the Collector configuration file or /etc/otelcol-contrib/otelcol-contrib.conf, restart the otelcol-contrib service to apply the changes:

sudo systemctl restart otelcol-contrib

To check the logs from the otelcol-contrib service, run:

sudo journalctl -u otelcol-contrib

For more information on configuring and using the Scout Collector, refer to the official OpenTelemetry documentation.

Running with elevated privileges

Reading Docker container logs under /var/lib/docker/containers requires root. Override the service user with a systemd drop-in rather than editing the packaged unit file, which an upgrade would overwrite.

Create the drop-in directory and file:

sudo mkdir -p /etc/systemd/system/otelcol-contrib.service.d
sudo tee /etc/systemd/system/otelcol-contrib.service.d/10-root.conf >/dev/null <<'EOF'
[Service]
User=root
EOF

The drop-in must live under /etc/systemd/system/...; a file placed elsewhere under /etc/systemd/ is silently ignored. Reload systemd and restart so the change takes effect:

sudo systemctl daemon-reload
sudo systemctl restart otelcol-contrib

Confirm the effective user:

systemctl show otelcol-contrib -p User

If you prefer not to run the collector as root, configure the container with the journald log driver and read it with the journald receiver instead of filelog.

Validate and verify

Validate the configuration before restarting. Because credentials come from the environment file, load it first — otherwise ${env:...} resolves to empty and validation reports a missing endpoint and client ID even though the config is correct:

sudo bash -c 'set -a; . /etc/otelcol-contrib/otelcol-contrib.conf; set +a; \
otelcol-contrib validate --config=/etc/otelcol-contrib/config.yaml'

Restart the service and watch the logs for export or authentication errors:

sudo systemctl restart otelcol-contrib
sudo journalctl -u otelcol-contrib -f

Check the health endpoint to confirm the collector is up:

curl -s localhost:13133

Then confirm the telemetry arrives in Scout under the service or host you configured.

Troubleshooting

SymptomCauseFix
validate reports no ClientID provided or at least one endpoint must be specified${env:...} variables are not set in your shell; systemd injects them only at service startLoad the environment file before validating (see Validate and verify), or rely on systemctl restart and read the journal.
finding files ... permission denied on /var/lib/docker/containersThe collector is not running as rootApply the User=root drop-in; confirm with systemctl show otelcol-contrib -p User.
User still shows the default after adding a drop-inThe drop-in is in the wrong directory, lacks the .conf suffix, or systemd was not reloadedPlace it under /etc/systemd/system/otelcol-contrib.service.d/ with a .conf name, then run daemon-reload and restart.
failed to detect a valid log path from the container operatoradd_metadata_from_filepath: true expects Kubernetes pod log pathsSet add_metadata_from_filepath: false.
Config edits have no effectThe collector reads its config only at startupRun sudo systemctl restart otelcol-contrib.
No data arrives, but there are no errorsfilelog uses start_at: end, so only new lines are sentGenerate new activity; historical lines are not backfilled. Use start_at: beginning only for testing.
Was this page helpful?