Централізоване логування: чому це критично для веб-застосунків
Після чергового інциденту на продакшені з 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 та скоротіть час пошуку помилок.







