ELK Stack — ELK Architecture

6 minute read

ELK Architecture Overview

Understanding how data flows through the ELK Stack is essential before you start building anything. The architecture follows a simple pipeline: Collect → Transform → Store → Visualize.

┌──────────────────────────────────────────────────────────────────┐
│                     ELK Stack Data Flow                          │
│                                                                   │
│  ┌─────────┐    ┌─────────┐    ┌──────────────┐    ┌─────────┐  │
│  │  Beats  │───▶│Logstash │───▶│Elasticsearch │───▶│ Kibana  │  │
│  │(Collect)│    │(Process)│    │   (Store)    │    │(Display)│  │
│  └─────────┘    └─────────┘    └──────────────┘    └─────────┘  │
│                                                                   │
│  Filebeat         Grok Parse      Index Data       Dashboards    │
│  Metricbeat       Filter          Full-Text Search  Discover     │
│  Heartbeat        Enrich          Aggregate         Alerting     │
│  Packetbeat       Route           Retain            Lens         │
└──────────────────────────────────────────────────────────────────┘

Let’s break down each stage.

Stage 1 — Data Collection (Beats)

Beats are lightweight agents installed on your servers. Their only job is to read log files (or collect metrics) and ship them to the next stage. Think of Beats as postal workers — they pick up the mail and deliver it.

┌──────────────────────────────────────────┐
│            Your Servers                   │
│                                           │
│  Server 1: [Filebeat] → reads access.log │
│  Server 2: [Filebeat] → reads app.log    │
│  Server 3: [Metricbeat] → reads CPU/RAM  │
│  Server 4: [Heartbeat] → pings services  │
│                                           │
│  All Beats ship data to ──▶ Logstash     │
│                        or ──▶ Elasticsearch│
└──────────────────────────────────────────┘

Key characteristics of Beats:

  • Lightweight — minimal CPU and memory footprint
  • Purpose-built — each Beat handles one type of data
  • Reliable — built-in backpressure handling and delivery guarantees
  • Simple — YAML configuration, no coding required

The most common Beat is Filebeat, which tails log files and sends each line as an event.

Stage 2 — Data Processing (Logstash)

Logstash receives raw log data and transforms it into structured, searchable documents. Think of Logstash as a factory — raw materials go in, finished products come out.

A Logstash pipeline has three sections:

┌───────────────────────────────────────────────┐
│              Logstash Pipeline                 │
│                                                │
│  ┌─────────┐   ┌──────────┐   ┌────────────┐ │
│  │  INPUT   │──▶│  FILTER  │──▶│   OUTPUT   │ │
│  │         │   │          │   │            │ │
│  │ beats   │   │ grok     │   │ elasticsearch│
│  │ file    │   │ date     │   │ stdout     │ │
│  │ syslog  │   │ mutate   │   │ file       │ │
│  │ kafka   │   │ geoip    │   │ kafka      │ │
│  └─────────┘   └──────────┘   └────────────┘ │
└───────────────────────────────────────────────┘

Example transformation:

Raw NGINX log line:

192.168.1.50 - - [15/Mar/2025:10:15:30 +0000] "GET /api/users HTTP/1.1" 200 1234

After Logstash grok parsing:

{
  "client_ip": "192.168.1.50",
  "timestamp": "2025-03-15T10:15:30.000Z",
  "method": "GET",
  "path": "/api/users",
  "http_version": "1.1",
  "status_code": 200,
  "bytes_sent": 1234
}

Now you can search for all status_code: 500 errors or aggregate traffic by client_ip. That’s the power of structured data.

Stage 3 — Data Storage (Elasticsearch)

Elasticsearch is the heart of the stack. It stores every log event as a JSON document and makes it searchable in near real-time (typically within 1 second of ingestion).

┌──────────────────────────────────────────────┐
│           Elasticsearch Cluster              │
│                                               │
│  ┌─────────────┐  ┌─────────────┐            │
│  │   Node 1    │  │   Node 2    │            │
│  │  (Master)   │  │  (Data)     │            │
│  │             │  │             │            │
│  │ Shard 0 (P) │  │ Shard 0 (R) │            │
│  │ Shard 1 (R) │  │ Shard 1 (P) │            │
│  └─────────────┘  └─────────────┘            │
│                                               │
│  Index: nginx-logs-2025.03.15                │
│  Documents: 2,500,000                         │
│  Size: 1.2 GB                                 │
│  Searchable in: < 1 second                   │
└──────────────────────────────────────────────┘

Key capabilities:

  • Full-text search — find log entries by any keyword
  • Structured queries — filter by status code, IP, timestamp, or any field
  • Aggregations — count errors per hour, average response time, top URLs
  • Near real-time — data is searchable within ~1 second of indexing
  • Distributed — scales horizontally by adding more nodes
  • Resilient — data is replicated across nodes for fault tolerance

Stage 4 — Visualization (Kibana)

Kibana is the window into your data. It connects to Elasticsearch and provides a web interface to search, analyze, and visualize your logs.

┌──────────────────────────────────────────────┐
│              Kibana Features                  │
│                                               │
│  ┌──────────┐  ┌──────────┐  ┌──────────┐   │
│  │ Discover │  │   Lens   │  │Dashboards│   │
│  │          │  │          │  │          │   │
│  │ Search & │  │ Drag-drop│  │ Combined │   │
│  │ explore  │  │ charts   │  │ views    │   │
│  │ raw logs │  │          │  │          │   │
│  └──────────┘  └──────────┘  └──────────┘   │
│                                               │
│  ┌──────────┐  ┌──────────┐  ┌──────────┐   │
│  │ Alerting │  │ Canvas   │  │ Maps     │   │
│  │          │  │          │  │          │   │
│  │ Notify   │  │ Custom   │  │ GeoIP    │   │
│  │ on       │  │ pixel-   │  │ based    │   │
│  │ anomalies│  │ perfect  │  │ visuals  │   │
│  └──────────┘  └──────────┘  └──────────┘   │
└──────────────────────────────────────────────┘

Common Architecture Patterns

Pattern 1 — Simple (Small Teams)

For small setups (< 10 servers), you can skip Logstash entirely:

Filebeat ──────────▶ Elasticsearch ──▶ Kibana

Filebeat can parse common log formats using modules (NGINX, Apache, MySQL, etc.) and send structured data directly to Elasticsearch.

Pattern 2 — Standard (Most Teams)

For medium setups that need custom parsing:

Filebeat ──▶ Logstash ──▶ Elasticsearch ──▶ Kibana

Logstash handles complex parsing, enrichment, and routing.

Pattern 3 — Buffered (High Volume)

For high-volume environments (millions of events per second), add a message queue:

Filebeat ──▶ Kafka ──▶ Logstash ──▶ Elasticsearch ──▶ Kibana

Kafka acts as a buffer — if Elasticsearch is slow or down, events queue in Kafka instead of being lost.

Pattern 4 — Multi-Cluster (Enterprise)

For large organizations:

┌─────────────────────────────────────────────┐
│  Region: US-East                             │
│  Filebeat ──▶ Logstash ──▶ ES Cluster 1    │
└──────────────────────────┬──────────────────┘
                           │
                    Cross-Cluster Search
                           │
┌──────────────────────────┴──────────────────┐
│  Region: EU-West                             │
│  Filebeat ──▶ Logstash ──▶ ES Cluster 2    │
└─────────────────────────────────────────────┘
                           │
                     ┌─────┴─────┐
                     │  Kibana   │
                     │ (Central) │
                     └───────────┘

Data Flow — Step by Step

Let’s trace a single log event through the entire stack:

1. An NGINX server handles a request and writes to access.log:

192.168.1.50 - - [15/Mar/2025:10:15:30 +0000] "GET /api/users HTTP/1.1" 200 1234

2. Filebeat (running on the NGINX server) reads the new line and sends it to Logstash:

{
  "message": "192.168.1.50 - - [15/Mar/2025:10:15:30 +0000] \"GET /api/users HTTP/1.1\" 200 1234",
  "host": "web-server-01",
  "log": { "file": { "path": "/var/log/nginx/access.log" } }
}

3. Logstash applies a grok filter to parse the raw message:

{
  "client_ip": "192.168.1.50",
  "timestamp": "2025-03-15T10:15:30.000Z",
  "method": "GET",
  "path": "/api/users",
  "status_code": 200,
  "bytes_sent": 1234,
  "host": "web-server-01"
}

4. Logstash sends the structured document to Elasticsearch:

  • Indexed into nginx-logs-2025.03.15
  • Searchable within ~1 second

5. You open Kibana and search for status_code: 500 to find errors:

  • Kibana sends the query to Elasticsearch
  • Elasticsearch returns matching documents
  • Kibana displays results in the Discover view or a dashboard

Port Reference

Component Default Port Purpose
Elasticsearch 9200 REST API (HTTP)
Elasticsearch 9300 Node-to-node communication
Kibana 5601 Web UI
Logstash (Beats input) 5044 Receives data from Beats
Logstash (HTTP input) 9600 Monitoring API
Filebeat — No listening port (pushes data)

Quick Reference

Stage Component Role
Collect Beats (Filebeat, Metricbeat) Ship logs/metrics from servers
Transform Logstash Parse, filter, enrich log data
Store Elasticsearch Index and search documents
Visualize Kibana Dashboards, search, alerts
Default ports ES: 9200, Kibana: 5601, Logstash: 5044  
Patterns Simple, Standard, Buffered, Multi-Cluster Choose based on scale

Next Step

Now that you understand how the ELK architecture works, let’s explore real-world use cases where the ELK Stack is commonly deployed.