In today’s data‑driven world, logs are the silent witnesses of every transaction, error, and performance hiccup in your infrastructure. The ELK Stack—Elasticsearch, Logstash, and Kibana—offers a powerful, scalable way to ingest, store, search, and visualize those logs. This guide walks you through an end‑to‑end setup on a fresh Ubuntu 22.04 server, from installing each component to building dashboards that turn raw text into actionable insight. We’ll cover real commands, configuration snippets, and the common traps that trip up even seasoned engineers, so you can get reliable log analysis up and running without a hitch.
What You’ll Need
- Ubuntu 22.04 (or any recent Linux distro) with sudo privileges
- At least 4 GB RAM (8 GB recommended for production workloads)
- Java 11 (OpenJDK) for Logstash
- Root or sudo access to install packages and edit system files
- A basic understanding of Linux command line and networking
Step 1: Install and Secure Elasticsearch
Elasticsearch is the heart of the stack—its distributed search engine stores and indexes log data. Begin by adding the official Elastic repository and installing the package:
wget -qO - https://artifacts.elastic.co/GPG-KEY-elasticsearch | sudo apt-key add -
sudo apt-get install apt-transport-https
echo "deb https://artifacts.elastic.co/packages/8.x/apt stable main" | sudo tee /etc/apt/sources.list.d/elastic-8.x.list
sudo apt-get update
sudo apt-get install elasticsearch
After installation, edit /etc/elasticsearch/elasticsearch.yml to bind to the local interface and enable security features:
# /etc/elasticsearch/elasticsearch.yml
network.host: 127.0.0.1
http.port: 9200
xpack.security.enabled: true
xpack.security.http.ssl.enabled: true
xpack.security.http.ssl.key: "/etc/elasticsearch/certs/elastic.key"
xpack.security.http.ssl.certificate: "/etc/elasticsearch/certs/elastic.crt"
Generate a self‑signed certificate (or use your corporate PKI) with the elasticsearch-certutil tool, then restart the service:
sudo /usr/share/elasticsearch/bin/elasticsearch-certutil ca --pem
sudo /usr/share/elasticsearch/bin/elasticsearch-certutil cert --ca elastic-stack-ca.p12 --pem --out elastic-certificates.p12
sudo chown root:elasticsearch elastic-certificates.p12
sudo chmod 660 elastic-certificates.p12
sudo systemctl daemon-reload
sudo systemctl enable elasticsearch
sudo systemctl start elasticsearch
Verify the node is up and secured:
curl -k -u elastic: https://localhost:9200/_cluster/health?pretty
If you see a green status, Elasticsearch is ready.
Step 2: Install Logstash and Configure a Pipeline
Logstash pulls logs from sources, transforms them, and ships them to Elasticsearch. Install it from the same repository:
sudo apt-get install logstash
Create a pipeline configuration at /etc/logstash/conf.d/syslog.conf that reads syslog files, parses common fields, and outputs to Elasticsearch:
# /etc/logstash/conf.d/syslog.conf
input {
file {
path => "/var/log/syslog"
start_position => "beginning"
sincedb_path => "/dev/null"
}
}
filter {
grok {
match => { "message" => "%{SYSLOGTIMESTAMP:timestamp} %{HOSTNAME:host} %{DATA:program}: %{GREEDYDATA:msg}" }
}
date {
match => ["timestamp", "MMM d HH:mm:ss", "MMM dd HH:mm:ss"]
timezone => "UTC"
}
}
output {
elasticsearch {
hosts => ["https://localhost:9200"]
user => "logstash_system"
password => ""
index => "syslog-%{+YYYY.MM.dd}"
ssl => true
cacert => "/etc/elasticsearch/certs/elastic-stack-ca.pem"
}
stdout { codec => rubydebug }
}
Secure the Logstash system user inside Elasticsearch:
curl -k -u elastic: -X POST "https://localhost:9200/_security/user/logstash_system" -H 'Content-Type: application/json' -d'{"password":"","roles":["logstash_writer"]}'
Start Logstash and test the pipeline:
sudo systemctl enable logstash
sudo systemctl start logstash
sudo journalctl -u logstash -f # watch for parsing errors
If you see events flowing to Elasticsearch, the pipeline works.
Step 3: Install Kibana and Connect to Elasticsearch
Kibana provides the visual layer. Install it from the Elastic repo:
sudo apt-get install kibana
Configure /etc/kibana/kibana.yml to point at the secured Elasticsearch instance:
# /etc/kibana/kibana.yml
server.host: "0.0.0.0"
elasticsearch.hosts: ["https://localhost:9200"]
elasticsearch.username: "kibana_system"
elasticsearch.password: ""
server.ssl.enabled: true
server.ssl.certificate: "/etc/kibana/certs/kibana.crt"
server.ssl.key: "/etc/kibana/certs/kibana.key"
Generate a Kibana certificate (or reuse the Elasticsearch one) and then enable the service:
sudo systemctl enable kibana
sudo systemctl start kibana
Open https://your_server:5601 in a browser, log in with the elastic user, and you should see the Kibana landing page.
Step 4: Build Your First Dashboard
With data flowing, it’s time to visualize. In Kibana:
- Navigate to **Discover**, select the
syslog-*index pattern, and verify that recent syslog entries appear. - Click **Create index pattern**, enter
syslog-*, and set the timestamp field to@timestamp. - Switch to **Visualize**, click **Create visualization**, and choose a chart type (e.g., **Bar**).
- Configure the X‑axis with a date histogram on
@timestampand the Y‑axis with a count of records. - Save the visualization as “Syslog Volume Over Time”.
- Repeat for a **Data Table** showing top 10 programs (use a terms aggregation on
program.keyword). - Finally, go to **Dashboard**, click **Create dashboard**, and add the two visualizations. Save as “Syslog Overview”.
Now you have a live view of log volume and the most chatty services on your server.
Step 5: Set Up Alerting for Critical Events
Kibana’s built‑in alerting (formerly Watcher) can notify you when a pattern emerges—say, more than five failed SSH logins in a minute. Create an alert:
- In Kibana, go to **Stack Management → Rules and Connectors**.
- Click **Create rule**, select **Log threshold**.
- Define the rule: Index pattern
syslog-*, queryprogram: "sshd" AND msg: "Failed password", threshold > 5, time window 1m. - Choose an action connector (e.g., Email, Slack, or webhook) and configure the payload.
- Enable the rule.
When the condition fires, you’ll receive an instant notification, turning raw logs into proactive alerts.
Step 6: Optimize Performance and Retention
Production environments quickly outgrow default settings. Tweak the following:
- Shard sizing: Use
index.number_of_shards: 1for small clusters; increase only if you exceed 30 GB per shard. - ILM policies: Define a lifecycle that rolls over daily indices and deletes after 30 days.
- Heap size: Set
ES_JAVA_OPTS="-Xms2g -Xmx2g"in/etc/elasticsearch/jvm.options.d/heap.options(50 % of RAM, max 32 GB). - Pipeline workers: In
logstash.yml, setpipeline.workers: 2per CPU core for balanced throughput.
Apply ILM:
PUT _ilm/policy/syslog_policy
{
"policy": {
"phases": {
"hot": { "actions": { "rollover": { "max_size": "50gb", "max_age": "1d" } } },
"delete": { "min_age": "30d", "actions": { "delete": {} } }
}
}
}
PUT syslog-000001
{
"aliases": { "syslog": { "is_write_index": true } },
"settings": { "index.lifecycle.name": "syslog_policy" }
}
Now old logs are pruned automatically, keeping storage costs predictable.
Common Mistakes to Avoid
Even seasoned admins stumble over a few recurring issues:
- Skipping TLS: Running Elasticsearch without HTTPS leaves credentials exposed. Always enable
xpack.security.http.ssl.enabledand use certificates. - Hard‑coding passwords: Store secrets in a vault (HashiCorp Vault, AWS Secrets Manager) or use environment variables, never plain text in config files.
- Incorrect
sincedb_path: Leaving the default path causes Logstash to think it has already processed a file after a restart, leading to data loss. Use/dev/nullonly for testing; for production, point to a persistent location. - Over‑sharding: Creating many small shards hurts cluster performance. Stick to one shard per 30 GB of data.
- Neglecting JVM heap: Setting heap too high (>50 % RAM) triggers garbage‑collection pauses. Monitor
/_cat/nodes?v&h=heap.percent,heap.max.
Tips and Tricks
Here are a few shortcuts that make daily operations smoother:
- Use Filebeat: Instead of raw Logstash file inputs, deploy Filebeat agents on each host; they forward logs over TLS and reduce Logstash CPU load.
- Leverage ingest pipelines: Define pipelines inside Elasticsearch to parse logs before indexing, cutting down on Logstash complexity.
- Dashboard templating: Save visualizations as reusable objects; you can clone a “Web Server” dashboard for every new host by just changing the index pattern.
- Hot‑reload pipelines: After editing a
.conffile, send aSIGHUPto Logstash (sudo kill -HUP $(pidof java)) to reload without downtime. - Monitor health: Set up Metricbeat’s Elasticsearch module; feed its metrics back into Kibana for a “Cluster health” dashboard.
Frequently Asked Questions
Can I run the ELK Stack on Windows?
Yes, Elastic provides native Windows packages for all three components. However, production deployments are usually Linux‑based because of superior memory handling and easier automation.
Do I need a separate server for each component?
Not necessarily. For small environments a single‑node installation works, but scaling out—dedicating nodes for master, data, ingest, and Kibana—improves resilience and performance as log volume grows.
How do I secure Kibana access?
Enable TLS in kibana.yml, enforce basic authentication with the built‑in Elastic users, and consider an additional reverse‑proxy (NGINX or Apache) with HTTP‑Basic or SSO integration.
Conclusion
By following this guide you’ve built a full‑featured ELK pipeline: Elasticsearch safely stores indexed logs, Logstash (or Filebeat) ships and enriches them, and Kibana turns the raw data into real‑time visual insights and alerts. With the performance tweaks, security hardening, and alerting rules covered, you’re now equipped to scale the stack, keep your logs under control, and turn every event into a proactive signal. Keep experimenting with ingest pipelines, custom dashboards, and machine‑learning jobs—ELK is a living ecosystem that rewards continuous refinement.
Photo by Portraits of Modern Dairy on Unsplash





