Централізоване логування: чому це критично для веб-застосунків
Після чергового інциденту на продакшені з 5xx помилками ми витратили 3 години, перебираючи логи на десяти серверах. Це повторювалося щомісяця. Коли веб-застосунок обслуговує тисячі користувачів, логи генеруються у величезних обсягах — до 50 ГБ на день на 10 серверах. Без централізації знайти помилку — як голку в копиці сіна. ELK Stack вирішує цю проблему: всі логи стікаються в єдине сховище з пошуком за секунди. У нашій практиці час інциденту скорочується на 70% після впровадження ELK. Алерти в Telegram сигналізують про 5xx, повільні запити, помилки застосунку. Ми беремо на себе повний цикл: від розгортання Elasticsearch до дашбордів і алертів. Строк — від 2 до 7 днів залежно від складності.
Як ELK Stack вирішує проблеми збору та аналізу логів?
ELK — це зв'язка Elasticsearch (зберігання та пошук), Logstash (парсинг та трансформація) і Kibana (візуалізація). Filebeat доставляє логи з серверів. У результаті ви отримуєте єдину точку входу для всіх логів, що значно спрощує моніторинг логів та пошук помилок.
Вибір схеми: ELK vs EFK vs без Logstash
| Схема | Складність | Продуктивність | Гнучкість |
|---|---|---|---|
| ELK | Висока | Середня | Висока |
| EFK | Середня | Вища | Середня |
| Без Logstash | Низька | Висока | Низька |
Logstash виграє в можливостях: парсить старі формати логів за допомогою grok, збагачує дані (geoip, useragent). У 80% проектів використовуємо його. Однак Ingest Pipelines Elasticsearch швидші: обробляють до 15 000 подій/с — у 3 рази більше, ніж Logstash (5 000). Але Logstash справляється з неструктурованими даними, де Ingest безсилий.
Як ми налаштовуємо ELK під ваш проект
Docker Compose для тестового середовища
Використовуємо такий compose-файл:
---
version: '3.8'
services:
elasticsearch:
image: docker.elastic.co/elasticsearch/elasticsearch:8.13.0
environment:
- discovery.type=single-node
- xpack.security.enabled=true
- xpack.security.http.ssl.enabled=false
- ELASTIC_PASSWORD=changeme
- "ES_JAVA_OPTS=-Xms2g -Xmx2g"
volumes:
- esdata:/usr/share/elasticsearch/data
ports:
- "9200:9200"
ulimits:
memlock:
soft: -1
hard: -1
kibana:
image: docker.elastic.co/kibana/kibana:8.13.0
environment:
- ELASTICSEARCH_HOSTS=http://elasticsearch:9200
- ELASTICSEARCH_USERNAME=kibana_system
- ELASTICSEARCH_PASSWORD=changeme
ports:
- "5601:5601"
depends_on:
- elasticsearch
logstash:
image: docker.elastic.co/logstash/logstash:8.13.0
volumes:
- ./logstash/pipeline:/usr/share/logstash/pipeline
- ./logstash/config/logstash.yml:/usr/share/logstash/config/logstash.yml
ports:
- "5044:5044"
- "5000:5000"
depends_on:
- elasticsearch
volumes:
esdata: Logstash Pipeline: парсинг Nginx access та JSON-логів
input {
beats {
port => 5044
}
tcp {
port => 5000
codec => json_lines
}
}
filter {
if [fields][log_type] == "nginx_access" {
grok {
match => { "message" => '%{IPORHOST:client_ip} - %{DATA:user} \[%{HTTPDATE:timestamp}\] "%{WORD:method} %{DATA:request} HTTP/%{NUMBER:http_version}" %{NUMBER:status_code:int} %{NUMBER:bytes_sent:int} "%{DATA:referrer}" "%{DATA:user_agent}" %{NUMBER:request_time:float}' }
}
date {
match => ["timestamp", "dd/MMM/yyyy:HH:mm:ss Z"]
target => "@timestamp"
}
geoip {
source => "client_ip"
target => "geoip"
}
useragent {
source => "user_agent"
target => "ua"
}
mutate {
remove_field => ["message", "timestamp"]
}
}
if [fields][log_type] == "app_json" {
json {
source => "message"
target => "app"
}
mutate {
remove_field => ["message"]
}
}
}
output {
if [fields][log_type] == "nginx_access" {
elasticsearch {
hosts => ["http://elasticsearch:9200"]
user => "elastic"
password => "changeme"
index => "nginx-access-%{+YYYY.MM.dd}"
}
} else {
elasticsearch {
hosts => ["http://elasticsearch:9200"]
user => "elastic"
password => "changeme"
index => "app-logs-%{+YYYY.MM.dd}"
}
}
} Відправка логів з Laravel
Через кастомний Monolog handler:
class LogstashLogger {
public function __invoke(array $config): Logger {
$handler = new SocketHandler("tcp://{$config['host']}:{$config['port']}");
$handler->setFormatter(new JsonFormatter());
return new Logger('app', [$handler]);
}
}Тепер Log::error(...) відправляє JSON напряму в Logstash.
На одному з проектів з навантаженням 10 000 RPS ми налаштували кластер Elasticsearch з 3 нод з ILM і Logstash з grok-патернами для парсингу специфічних логів застосунку. В результаті час пошуку помилки скоротився з 40 хвилин до 10 секунд. Це дозволило команді швидше реагувати на інциденти та знизити середній час відновлення (MTTR) на 65%.
Чому ILM обов'язковий?
Без ILM індекси неконтрольовано ростуть, і через місяць диск забитий. Налаштовуємо політику: hot (5 ГБ або 1 день) → warm (3 дні) → cold (30 днів) → delete (90 днів). Все через шаблон індексу. Це основа економічного зберігання логів. Додатково можна налаштувати rollover за розміром або віком, щоб уникнути перевантаження вузлів.
Продуктивність Elasticsearch: поради з практики
- Heap — не більше 50% RAM і не більше 31 ГБ (через compressed oops)
- Кількість шардів: 1 шард ≈ 20–40 ГБ даних. Oversharding — часта помилка
- Slow log:
index.search.slowlog.threshold.query.warn: 2s - Заборона свопу:
bootstrap.memory_lock: true
Порівняння: Logstash vs Ingest Pipelines
| Параметр | Logstash | Ingest Pipelines |
|---|---|---|
| Продуктивність | ~5 тис. подій/с | ~15 тис. подій/с |
| Гнучкість | Grok, enrich, маршрутизація | Тільки прості парсинги |
| Складність | Потребує налаштування сервера | Вбудований в ES |
Для складних трансформацій Logstash незамінний. Вбудовані pipeline-процесори справляються з типовими завданнями, але не вміють працювати з довільними текстовими патернами.
Що входить у налаштування ELK
- Розгортання кластера Elasticsearch з оптимальними налаштуваннями (шарди, ILM, безпека)
- Конфігурація Logstash для парсингу Nginx, PHP і прикладних логів
- Підключення Filebeat на всіх серверах
- Створення дашбордів у Kibana для моніторингу логів (5xx, latency, traffic)
- Налаштування ILM для економії дискового простору
- Інтеграція алертів у Telegram або Email
- Документація з експлуатації та навчання команди
Процес роботи
- Аналітика — вивчаємо поточні логи, джерела, вимоги до зберігання
- Проєктування — обираємо схему (ELK/EFK), намічаємо ILM і дашборди
- Реалізація — розгортаємо кластер, налаштовуємо конвеєри
- Тестування — перевіряємо надходження даних, алерти, час пошуку
- Деплой — впроваджуємо в продакшен, передаємо документацію
Гарантуємо SLA 99.9% для кластера. Наші інженери мають досвід понад 5 років і реалізували 30+ проєктів. Отримайте консультацію з налаштування ELK під ваш проєкт. Заплануйте впровадження ELK та скоротіть час пошуку помилок.







