Elasticsearch, Logstash and Kibana are the three pieces most teams reach for when they decide to centralize their logs. This page covers what each one does, how they fit together in production, and what it takes to keep the result running.
ELK is an acronym for three open source projects that are usually deployed together: Elasticsearch, Logstash and Kibana. Elastic, the company behind them, now calls the combination the Elastic Stack, partly because a fourth family of components called Beats became part of the standard deployment and the acronym stopped fitting.
Worth knowing up front: none of the three was built for logs. Elasticsearch is a search engine, Kibana is a visualization tool, and Logstash is a data pipeline. Log management is the use case they became famous for, and a lot of what follows comes down to that history.
| Component | What it does |
|---|---|
| Elasticsearch | A distributed search and analytics engine built on Apache Lucene. It stores logs as JSON documents, indexes the fields, and answers queries across them. This is the part that does the work and consumes the resources. It runs on the JVM, it wants memory, and it expects to be clustered across at least three master-eligible nodes so a quorum survives losing one. |
| Logstash | A processing pipeline. It takes input from many sources, transforms it, and forwards it to Elasticsearch. The transform step is where you write the rules that turn a raw log line into structured fields, usually with grok patterns. Logstash is another JVM process and is often the first component to fall over under load. |
| Kibana | The web interface. Search, dashboards, visualizations, and in recent versions a set of security and observability applications on top. Everything you see is something somebody configured. Kibana ships with no dashboards for your data because it has no idea what your data is. |
| Beats | Lightweight shippers that run on the machines producing the logs. Filebeat for log files, Winlogbeat for Windows events, Metricbeat for system metrics. They exist because putting a JVM on every server you want to collect from was never reasonable. Plenty of deployments now send from Beats straight into Elasticsearch and skip Logstash. |
Filebeat runs on each server and tails the log files. It ships to Logstash, which parses the lines into fields. Logstash writes into Elasticsearch, which is a cluster of three or more nodes. Kibana runs somewhere with access to the cluster, usually behind a reverse proxy that handles authentication. Index lifecycle policies roll older indices onto cheaper storage and eventually delete them.
Somewhere between Logstash and Elasticsearch you need a buffer. During a burst, Logstash will produce faster than Elasticsearch accepts writes, and without something in the middle you drop data. Most production deployments put Kafka or Redis there, which is a fourth and fifth system to run and monitor.
That is a sound architecture. It scales past volumes almost nobody reaches, and if you have the team for it there is a lot to like. But it is an architecture, and it becomes yours the moment you deploy it.
The download is free. That gets discussed. What gets discussed less is everything below, which is where the cost lives.
Writing the parsers
Elasticsearch does not know what an sshd line means. Take this one:
Failed password for invalid user admin from 203.0.113.5 port 44122 ssh2
To Elasticsearch that is a string. Turning it into a username, a source address and a port means writing a grok pattern, which is a named regular expression. Then you write one for your firewall, your web server, your mail server, your Windows events, your load balancer, and every application your team has ever deployed. Grok patterns are slow when written carelessly, and a pattern that fails silently produces a document with a _grokparsefailure tag and no fields, which nobody notices until they search for something that should be there.
They also rot. Vendors change log formats in point releases. We have hit this ourselves: a FortiGate traffic rule that had worked for years quietly stopped capturing addresses on ICMP events, because ICMP lines carry an identifier field where TCP and UDP lines carry a source port. Roughly fifteen hundred events a day were being stored with no source address attached, and nothing anywhere reported an error. Somebody has to notice that, and on a self-hosted stack that somebody is you.
Tuning the cluster
Heap size is the first thing everyone gets wrong. The JVM stops using compressed object pointers somewhere around 32GB, so a node given 40GB of heap can address less usable memory than one given 30GB. Elastic's guidance is to stay under the threshold and add nodes instead, which is not obvious to anyone who has not been bitten by it.
After that: shard count and shard size, replica count, refresh interval, field mappings, and mapping explosion when an application starts logging JSON with unpredictable keys. The usual shard guidance is tens of gigabytes each, so an index strategy that was reasonable at fifty gigabytes a day becomes a problem at five hundred. Most ELK incidents are a cluster going yellow or red, and most of those trace back to a shard strategy that was correct when it was chosen.
Building the dashboards
Kibana starts empty, and every saved search and visualization is something a person builds and then maintains against field names that change. The stack has no opinion about which of your logs matter, since it does not know what they are.
Doing the security part twice
ELK is log infrastructure. It will store an authentication failure and a successful login and let you search for both, but nothing in the base stack notices that fifty failures from one address were followed by a success from that same address. That single pattern is the difference between an attempt and a breach, and expressing it requires correlation rather than search.
Elastic sells a security product built on the stack and the free tier covers some of it, though detection rules and case management have sat behind paid tiers. The common alternative is to add Wazuh, a fork of OSSEC that uses Elasticsearch for storage. That works, and it also means running two systems with two rule sets, two agents and two upgrade cycles.
Owning it
A self-hosted ELK deployment is a production system that other production systems depend on. Patching, capacity planning, upgrade testing across major versions that have broken compatibility more than once, and somebody who understands it well enough to fix it at an unhelpful hour. A pattern we see often enough to mention: the engineer who built the deployment becomes the only person who can maintain it, and then changes jobs.
These three get compared and they answer different questions.
OSSEC is a host based intrusion detection system. It reads logs and decides whether something security relevant happened, using thousands of rules that know what a brute force attempt looks like, what privilege escalation looks like, what a web application attack looks like. It also does file integrity monitoring and rootkit detection. Storing and searching large volumes of logs was never its strength.
Wazuh forked OSSEC and fixed the storage problem by putting Elasticsearch underneath. The combination is common and it works. It also means running the Elastic cluster described above plus the Wazuh manager, agents and rule set on top of it.
We mention this because Trunc was built by the people who wrote OSSEC. The detection logic shares that ancestry, and the storage and search layer was designed for logs from the beginning instead of being adapted to them.
Trunc does what most teams are after when they set out to build an ELK deployment: logs from everything in one place, searchable immediately, with the security relevant ones already identified. There is nothing to run. No cluster, no heap tuning, no grok patterns, no dashboards to build, no queue in the middle, and nobody paged when the logging platform itself has a bad night.
Parsers that already exist
Trunc ships with parsers for the things people run: Linux and Windows, sshd, sudo, Apache, nginx, IIS, Postfix, Dovecot, pfSense, FortiGate, Sophos, Cisco, Ubiquiti, Office 365, AWS, WordPress and a long list beyond that. A log arrives already broken into source address, user, action and result. When a vendor changes a format, updating the parser is our problem. That FortiGate ICMP case above is one of ours, and fixing it fixed it for everybody sending FortiGate logs.
Categories, not just fields
Every event is tagged with what it means as well as what it says. Authentication failure, brute force, web attack, firewall block, configuration change, PCI DSS 10.2. That taxonomy is what makes the interface useful, because you can ask for everything security relevant across the whole estate without knowing which device produced it or what its format looks like.
Detection inherited from OSSEC
Rules that correlate across events instead of matching one at a time. Repeated authentication failures from an address, and separately the case that matters more, repeated failures followed by a success from that same address. A source that stops sending when it should still be sending. Scanning across your web servers. These fire without configuration, and can publish a blocklist your firewall pulls directly.
An interface that only does logs
Kibana is a visualization tool that can be pointed at logs. Trunc only ever does one thing, so it can assume what Kibana cannot: that you want volume over time split by severity, that you care which hosts went quiet, that a source address should link through to everything else it has done. Search is full text with field filters and returns while you are still looking at the screen.
| Self-hosted ELK | Trunc | |
|---|---|---|
| Time to first useful search | Days to weeks | Minutes |
| Log parsing | You write grok patterns | Included and maintained |
| Security categorization | Add Wazuh, or a paid tier | Built in, from OSSEC |
| Correlation rules | You write them | Included |
| Dashboards | You build them | Purpose built for logging |
| Infrastructure to run | Cluster, shippers, queue, proxy | None |
| Who gets paged for it | You | Us |
| Retention | Your disks, your lifecycle policies | Included, configurable |
| Compliance reporting | Build it yourself | PCI DSS and ISO 27001 built in |
Four cases where a self-hosted stack wins, and we would rather say so than have you find out later.
If none of those fit, the question worth asking is whether the stack solves a problem you have or adds a system you now maintain. Teams rarely set out wanting a search cluster.
Is the ELK Stack free?
The software can be downloaded and run at no cost, and for many deployments that is enough. Elastic moved away from Apache 2.0 in 2021 and added AGPL as an option in 2024, so it is worth checking the current terms against your own policy rather than relying on what you remember. Either way the licence is rarely the expensive part next to hardware and engineering time.
What about Elastic Cloud or OpenSearch?
Elastic Cloud is Elastic's managed offering, and it removes the cluster operations problem, which is a real portion of what is described above. It does not remove the parsing, the dashboard building or the detection rules. You get a managed general purpose search engine that you then configure for logs. OpenSearch is the fork AWS created after the licence change and the same reasoning applies.
Can Trunc replace Wazuh?
For log analysis and security event detection, yes, and the rule logic shares an ancestor. Wazuh also does file integrity monitoring and vulnerability detection on the endpoint, which are agent side features. If those are central to what you need, compare properly rather than taking our word for it.
Can I migrate from an existing ELK deployment?
Run both for a while. Point your shippers at Trunc alongside Elasticsearch, confirm you are seeing what you expect, then decommission. Trunc accepts standard syslog, so anything already forwarding to Logstash can forward to Trunc without touching the source.
14 days free trial. No credit card required.