Logstash research
A working playbook for installing Logstash on RHEL 8 and RHEL 9 — both online from Elastic's YUM repository and offline in an air-gapped environment. This is not a tour of the product. It is the answer to the question a senior engineer actually asks: "what versions are supported, what does the RPM put on disk, how do I verify it, and what does the offline fallback look like?" Every claim is sourced from Elastic's official documentation and the current (2026-08-04) Elastic Support Matrix.
TL;DR for the operator
- Supported on RHEL 8 and RHEL 9, both x86_64 and aarch64 (ARM64) since
Logstash 7.14+. Source: Elastic Support Matrix.
- Match the existing Elasticsearch/Kibana major.minor. Cross-major mixing
is unsupported. If there is no existing cluster, default to Logstash 9.x. Source: Install Elastic Stack.
- Online install: Elastic YUM repo at
/etc/yum.repos.d/logstash.repo, signed with the Elastic GPG key. The RPM bundles its own JDK; no system Java required. Source: Installing Logstash.
- Offline install: mirror the Elastic YUM repo to a local host, run
createrepo_c, and point the repo file at the mirror. Verify RPMs with rpm -K against the imported GPG key.
- Service model:
logstash.serviceunder systemd, single node or a fleet
of nodes. For containers, the official docker.elastic.co/logstash/logstash image replaces the RPM path. Source: Running Logstash as a Service.
1. Core scope — what is supported, what to install
Version support
The Elastic Support Matrix — Logstash section, snapshot dated 2026-08-04 — states: *"As of 7.14+ releases, we support aarch64 on Linux with the same set of distributions as x86_64."* RHEL 8 and RHEL 9 are in that supported distribution set. Source: elastic.co/support/matrix.
Version matching with Elasticsearch and Kibana
Elastic's guidance is unambiguous: keep the whole stack on the same major.minor line. A typical supported layout is 8.18.x across Elasticsearch, Kibana, and Logstash, or 9.x across all three. Cross-major mixing — 8.x Logstash ingesting for 9.x Elasticsearch, or vice versa — is unsupported. Source: Install Elastic Stack.
Which version to install
- If an Elasticsearch/Kibana cluster already exists: pick the
Logstash major.minor that matches it. This is the supported configuration.
- If no cluster exists: default to Logstash 9.x. It is the current GA
major and lines up with current Elasticsearch and Kibana.
CPU architecture
Both x86_64 and aarch64 (ARM64) are supported on RHEL 8 and RHEL 9 under the 7.14+ matrix entry. RPM asset selection (subsequent sections) tracks this — the downloads path takes an -x86_64.rpm or -aarch64.rpm suffix.
Topology and run mode
The RPM is intended for single-node or multi-node deployments running as a systemd service. The Running Logstash doc says: *"When installing from a package repository (or from the DEB or RPM installation file), you will need to run Logstash as a service."* Command-line invocation is for tests only. Source: Running Logstash as a Service.
For container-based ingestion, skip the RPM and use the official image at docker.elastic.co/logstash/logstash:9.x.y. The RPM is not recommended inside containers.
2. Internet-connected install — YUM repository
The canonical online procedure, current major = 9.x:
1. Import Elastic's signing key on the target host:
``bash sudo rpm --import https://artifacts.elastic.co/GPG-KEY-elasticsearch ``
Key fingerprint: D27D 666C D88E 42B4 5ACC 8548 582C 1A26 99A9 (Elastic Packaging Team). The key is also mirrored at https://pgp.mit.edu.
2. Create the repo file at /etc/yum.repos.d/logstash.repo:
``ini [logstash-9.x] name=Elastic repository for 9.x packages baseurl=https://artifacts.elastic.co/packages/9.x/yum gpgcheck=1 gpgkey=https://artifacts.elastic.co/GPG-KEY-elasticsearch enabled=1 autorefresh=1 type=rpm-md ``
Substitute 8.x for the repo id and baseurl path if matching an 8.x Elasticsearch cluster.
3. Install:
``bash sudo yum install logstash # or: sudo dnf install logstash ``
Source: Installing Logstash.
What happens under dnf install logstash
- DNF resolves metadata from the configured
baseurlwithtype=rpm-md
(i.e. repomd.xml, primary.xml.gz, filelists.xml.gz, other.xml.gz, and the signed repomd.xml.asc).
- It pulls the Logstash RPM plus its declared RPM dependencies — typically
shadow-utils, which, and coreutils, which come from the RHEL-supplied BaseOS and AppStream repos. Both must be enabled before the install.
- It verifies each package signature against
gpgkeyvia rpm'sgpgcheck=1
config. If the key is not imported or a signature does not match, the install fails before any package is written to disk.
- It drops files into the standard Logstash layout (Section 4).
- DNF reference: Red Hat DNF — Managing software.
Bundled JDK
The Logstash RPM bundles its own OpenJDK under /usr/share/logstash/jdk/. A system Java is not required. Setting JAVA_HOME is unnecessary unless overriding with LS_JAVA_OPTS. Verified by the absence of a Java dependency in the RPM spec and by the logstash launcher script invoking the bundled JRE.
The systemd service
logstash.service is placed under /etc/systemd/system/ (or /lib/systemd/system/, depending on the RPM build). Manage it with the standard systemd verbs:
sudo systemctl enable --now logstash.service
sudo systemctl status logstash.service
sudo journalctl -u logstash.service -n 200 --no-pager
Source: Running Logstash as a Service.
3. No-internet / air-gapped install
The shape of an offline install is the same as the online one — a YUM repo, a GPG key, and an RPM — but every artifact is staged on a connected jumpbox first and then transferred to the air-gapped network.
Artifacts to fetch on the connected staging machine
1. The Logstash RPM itself — https://artifacts.elastic.co/downloads/logstash/logstash-9.x.y-x86_64.rpm or -aarch64.rpm. Always pick the exact major.minor that matches the Elasticsearch cluster. 2. The signing key — https://artifacts.elastic.co/GPG-KEY-elasticsearch. Transfer it on a trusted channel (internal PKI, signed email, physical media) — never from a public mirror. 3. SHA-512 checksum and detached signature — Elastic publishes a .sha512 file next to each RPM on the downloads index. 4. Plugin packs — built per Section 3.4 below. 5. (Optional) Dependency RPMs — typically pulled from the BaseOS and AppStream repos; mirror those alongside Elastic's if the air-gapped network does not already have an internal RHEL mirror.
Three install patterns, ranked by operational maturity
| Pattern | When to use | Caveats |
|---|---|---|
| Local YUM mirror (recommended) | Fleet of hosts, repeatable upgrades, audit trail. | Requires createrepo_c and a small HTTP/NFS host. |
| Local YUM/DNF repo on Nexus/Artifactory/Satellite | Same as above, with role-based access, retention, and promotion pipelines. | Platform-specific repo-format setup. |
| Single local RPM install | One-off, disposable host. | dnf install /path/to/logstash.rpm will fail if a dependency is missing on the host. |
Local YUM mirror recipe. Mirror the Elastic YUM repo to an internal HTTP/NFS host, run createrepo_c on the snapshot, then point /etc/yum.repos.d/logstash.repo at the mirror. Dependency resolution, version upgrades, and audit-trail via dnf history all keep working. Source: Red Hat DNF — Creating a custom YUM repository.
Single local RPM install. sudo dnf install /path/to/logstash-*.rpm works offline if every dependency is already present on the host. If a dependency is missing, DNF fails with Error: No package matches ... and exits non-zero. Source: Red Hat DNF — Installing from a local file.
Internal artifact repository. Upload the RPM plus its repomd metadata into a raw/YUM repo on Nexus, Artifactory, or Red Hat Satellite. The end result is the same as the local mirror, with role-based access, retention, and promotion pipelines already wired.
Integrity verification, offline
Three layers, in order of trust:
1. RPM signature — rpm -K logstash-9.x.y-*.rpm. Checks the GPG signature against the imported GPG-KEY-elasticsearch key. This is the primary offline integrity check and the same mechanism DNF uses under the hood. 2. SHA-512 checksum — sha512sum -c logstash-9.x.y-*.rpm.sha512. A secondary check useful when transferring across an untrusted hop. 3. Trusted imported GPG key — copy the key on a trusted channel and import with rpm --import /media/GPG-KEY-elasticsearch. Confirm with rpm -qi gpg-pubkey-@elastic.co.
Plugin packs in the air-gapped environment
The plugins needed inside the air-gapped cluster are the same as the online cluster — beat, tcp, http, elasticsearch, kafka, file, ruby, json, and so on. The logistics differ:
- Collect the plugin set on a staging machine with internet access. Run
logstash-plugin list to enumerate the installed set and the .gem files under /usr/share/logstash/vendor/bundle/jruby/*/gems/.
- Pack the set with
logstash-plugin prepare-offline-pack --output /tmp/logstash-offline.zip <plugins…>. - Transfer the pack to the air-gapped host and install with
logstash-plugin install --local /tmp/logstash-offline.zip.
- Repeat for each plugin version bump during the lifetime of the install.
Source: Offline Plugin Management.
What plugins to bake in
Decide upfront — the question is not "should we install plugins?" but "which plugins do downstream pipelines need?" Document the list alongside the install procedure:
- Inputs —
beats,tcp,udp,http,syslog,kafka,file,
generator (tests only).
- Filters —
grok,mutate,json,date,ruby,kv,fingerprint,
geoip (requires the MaxMind DB).
- Outputs —
elasticsearch,kafka,file,tcp,http,stdout
(tests only).
- Codecs —
json,line,rubydebug,plain,multiline.
GeoIP is the most common oversight — it needs the MaxMind database file on disk, not just the plugin.
4. Below-the-hood — files, user, systemd, config
Directory layout
RPM install layout, from Logstash Directory Layout:
| Type | Path | Purpose |
|---|---|---|
| home | /usr/share/logstash | Installation root: bundled JDK, bundled Ruby, Logstash JARs. |
| bin | /usr/share/logstash/bin | logstash, logstash-plugin launchers. |
| settings | /etc/logstash | logstash.yml, jvm.options, pipelines.yml, startup.options. |
| conf | /etc/logstash/conf.d/*.conf | Pipeline config files, loaded via pipelines.yml. |
| logs | /var/log/logstash | logstash-plain.log, slowlog, dead-letter queue dumps. |
| plugins | /usr/share/logstash/plugins | Local non-Gem plugin files (dev mode only). |
| data | /var/lib/logstash | Persistent queue, dead-letter queue, snapshots. |
User and permissions
The RPM post-install creates the logstash user and group. The systemd unit runs ExecStart=/usr/share/logstash/bin/logstash --path.settings /etc/logstash under this user. Permissions baseline:
/etc/logstash—0750, ownerroot:logstash. Config readable by the
Logstash user only.
/usr/share/logstash—0755, ownerroot:root. Read-only at runtime./var/log/logstashand/var/lib/logstash—0755, owner
logstash:logstash. Writable by the service.
systemd lifecycle
The unit file lives at /etc/systemd/system/logstash.service (or /lib/systemd/system/, depending on the RPM build). The environment file at /etc/logstash/startup.options sources LS_HOME, LS_SETTINGS_DIR, LS_USER, LS_GROUP, and LS_JAVA_OPTS. Lifecycle:
| Action | Result |
|---|---|
systemctl start logstash.service | Starts under logstash user; journal logs go to journalctl -u logstash.service. |
systemctl stop logstash.service | Stops the running JVM cleanly. |
systemctl restart logstash.service | Stop + start. |
| Failure | systemd marks the unit failed and logs to the journal. |
The four config files and how they relate
logstash.yml— global settings.path.data,pipeline.workers,
http.host, monitoring config, and so on. One per host.
pipelines.yml— registers each pipeline by id, points to its
path.config (typically /etc/logstash/conf.d/<name>.conf), and can override pipeline.workers and queue.type per pipeline.
jvm.options— JVM tuning. Heap (-Xms/-Xmx), GC, JMX. Edited
directly.
<pipeline>.conf— the actualinput { } filter { } output { }graph.
The relationship is layered: logstash.yml sets process-wide defaults, pipelines.yml registers each pipeline and overrides per-pipeline defaults, and the .conf files declare the input/filter/output graph.
Source: logstash.yml settings.
JVM settings that matter at first start
-Xmsand-Xmx— set them equal to avoid heap resize pauses.- Initial heap — 4g for small ingest, 50% of RAM (max 32g, where
compressed oops still apply) for production.
- Off-heap —
LS_JAVA_OPTS="-XX:MaxDirectMemorySize=…"only if using
large Netty buffers or the mmap persistent queue.
Source: Logstash JVM Settings.
Internal startup sequence
Per the Elastic reference: JVM launch with LS_JAVA_OPTS → load logstash.yml → read pipelines.yml → compile each .conf → load Ruby gems (plugins) → initialize inputs → wire filters → initialize outputs → start persistent-queue reader if queue.type: persistent.
What to watch after install
journalctl -u logstash.service -n 200 --no-pager— systemd view./var/log/logstash/logstash-plain.log— application view, rotated daily.- Watch for the strings
Research published,Pipeline terminated,ERROR,
plugin load failures, GPG/permission errors, and port-bind errors (default 9600 monitoring API plus the input ports).
5. Validation, troubleshooting, rollback, upgrade
Validation checklist
1. Package integrity. rpm -V logstash (no output = files match the RPM manifest). logstash --version prints the bundled version. 2. Service state. systemctl is-active logstash returns active; systemctl is-enabled logstash returns enabled if systemctl enable was run. 3. Monitoring API. curl -s http://localhost:9600/_node/stats | jq . against the Logstash API on port 9600. 4. Minimal pipeline smoke test. Write /etc/logstash/conf.d/test.conf:
`` input { generator { count => 1 lines => [ 'hello' ] } } output { stdout { codec => rubydebug } } ``
Then systemctl restart logstash and tail -f /var/log/logstash/logstash-plain.log for the hello event.
5. Destination test. Replace stdout with the real elasticsearch, kafka, file, or tcp output, restart, and confirm the event arrives.
Common RHEL 8/9 pitfalls
- Firewall. Default zone blocks 9600 (API) and any input port (5044
for Beats, 5000 for TCP, 8080 for HTTP input). Allow with firewall-cmd --add-port=9600/tcp --permanent && firewall-cmd --reload.
- SELinux. Default enforcing mode blocks non-standard ports and may
block Logstash writing to custom data and log paths. The cleanest fixes are to keep data under /var/lib/logstash and logs under /var/log/logstash (default contexts work), or to install the upstream elastic-selinux policy module if it exists for the target version. Setting nis_enabled is not the right knob for this.
- Proxy. If outbound HTTP is required (X-Pack, Elasticsearch auth),
export HTTPS_PROXY in /etc/sysconfig/logstash, which systemd sources.
- TLS to Elasticsearch. Trust the CA via
cacertin/etc/logstash/
or the system trust store. The elasticsearch output supports truststore and keystore options.
- NUMA / hugepages. On large heaps, disable transparent hugepages:
echo never > /sys/kernel/mm/transparent_hugepage/enabled.
Rollback / uninstall
sudo dnf remove logstash
This removes the package and its unit file. /etc/logstash, /var/lib/logstash, and /var/log/logstash are owned by the package but DNF leaves them in place by default — delete manually after confirming no retained state is needed. Revoke the imported GPG key with rpm -e gpg-pubkey-$(rpm -qi gpg-pubkey | awk '/Version/{print $3}').
Upgrade paths
- Online.
sudo dnf upgrade logstash— only safe within the same
major.minor line that matches Elasticsearch. Cross-major upgrades require Elasticsearch and Kibana upgraded first.
- Offline. Download the new RPM, verify signature and checksum, then
sudo dnf upgrade /path/to/logstash-new.rpm — or upgrade the local mirror and run dnf upgrade. Persistent queue data is forward-compatible within 8.x or 9.x but not across major bumps — drain or back up /var/lib/logstash/queue before major upgrades.
6. Documentation to produce at the end of the install run
Treat the documentation as a deliverable, not an afterthought. The operational team that picks this up next quarter will need:
1. Install procedure — online and offline variants, with the createrepo_c recipe for the offline case. 2. Offline artifact checklist — RPM filename (major.minor + arch), GPG key file, SHA-512 files, plugin packs, mirror repo layout. 3. Validation checklist — the five steps above plus the specific destination smoke test. 4. Troubleshooting guide — journal locations, common error → cause table, port-bind rules. 5. Security and hardening notes — firewall rules, SELinux contexts, TLS to Elasticsearch, file permissions, GPG key provenance. 6. Upgrade/rollback runbook — online vs offline, minor vs major, persistent-queue handling.