QA Interview Hub · База знань · Тести
Логи й observability
Інструменти й запити
ELK / OpenSearch і Kibana: KQL
ELK (Elastic Stack) — Elasticsearch (сховок і пошук), Logstash або легші Beats/Elastic Agent (збір і обробка), Kibana (інтерфейс). OpenSearch — форк з аналогом Dashboards. Логи індексуються за часом (індекси чи data streams), тому в Kibana завжди обирають часовий діапазон і data view.
Основна мова пошуку в Kibana Discover — KQL (Kibana Query Language):
log.level: "error" and service.name: "checkout"
log.level: "error" and not message: "healthcheck"
http.response.status_code >= 500
trace.id: "4bf92f3577b34da6a3ce929d0e0e4736"
user.email: *@example.com and event.action: "login"
Правила: поле: значення, оператори and, or, not, дужки для групування, порівняння >, >= для чисел і дат, шаблон *, значення з пробілами беруть у лапки. Назви полів залежать від схеми (часто Elastic Common Schema: log.level, service.name, trace.id).
Типовий робочий процес QA в Kibana:
- обрати часове вікно навколо відтворення бага;
- звузити за сервісом/оточенням, потім за рівнем ERROR;
- або одразу шукати за
trace.id/request id з відповіді;
- додати колонки (поля) в таблицю, відсортувати за часом, відкрити документ і прочитати стек;
- зберегти пошук чи зробити візуалізацію (кількість помилок за часом) для звіту.
Окрім KQL, є Lucene-синтаксис і ES|QL (конвеєрна мова запитів Elastic); у співбесіді достатньо розуміти фільтр за полями, часом і trace id.
Grafana Loki, LogQL, Datadog і Sentry
Grafana Loki — система логів, яка індексує лише мітки (labels) потоку (сервіс, оточення, pod), а не повний текст; решту фільтрують під час запиту. Запити пишуть мовою LogQL у Grafana (Explore). Запит починається з селектора потоку у фігурних дужках, далі йдуть фільтри:
{app="checkout", env="staging"} |= "timeout"
{app="checkout"} |= "error" != "healthcheck"
{app="checkout"} |~ "order (8841|8842)"
{app="checkout"} | json | level="error" | durationMs > 1000
sum by (app) (count_over_time({env="staging"} |= "error" [5m]))
|= містить рядок, != не містить, |~ збігається з regex, !~ не збігається;
| json (або | logfmt) розбирає рядок і створює мітки з полів, які далі фільтрують (level="error");
- метричні запити (
count_over_time, rate) перетворюють логи на ряд для графіка чи алерта; діапазон задають у квадратних дужках.
Datadog — SaaS для логів, метрик і APM-трейсів в одному місці; за відповідного налаштування логи пов’язуються з трейсами (поля dd.trace_id, dd.span_id), тому з трейса одним кліком переходять до його логів.
Sentry — трекер помилок: збирає винятки (фронтенд і бекенд), групує їх у issues за стеком, показує breadcrumbs (що відбувалось перед помилкою), оточення та версію release. Для QA корисно: побачити, чи нова помилка з’явилась саме в цьому релізі, скільки користувачів зачеплено, і чи вона регресує після «виправлення». Для читабельних стеків фронтенду завантажують source maps.
Вибір інструмента залежить від компанії; важливо вміти сформулювати загальну послідовність: час → сервіс/оточення → рівень → ідентифікатор запиту → першопричина.
Командний рядок: docker logs, kubectl logs, grep, jq
Навіть коли є Kibana чи Grafana, логи локального оточення й CI читають у терміналі.
Docker:
docker logs -f --tail 100 api # стежити, останні 100 рядків
docker logs --since 10m api # за останні 10 хвилин
docker compose logs -f --tail=50 api db # кілька сервісів compose
docker compose logs --no-color --timestamps > compose.log
Kubernetes:
kubectl logs deploy/checkout --since=15m
kubectl logs -f pod/checkout-7d9f -c app # конкретний контейнер
kubectl logs pod/checkout-7d9f --previous # контейнер, що впав і перезапустився
kubectl logs -l app=checkout --tail=100 --prefix # за міткою, з іменами pod
--previous — те, що люблять питати: якщо pod у CrashLoopBackOff, поточний контейнер ще порожній, причину падіння дивляться в логах попереднього.
Файли й текст:
tail -f app.log | grep --line-buffered ERROR # живий потік помилок
grep -n -C 3 "orderId=8841" app.log # 3 рядки контексту навколо
grep -c "ERROR" app.log # кількість
zgrep "timeout" app.log.2026-10-11.gz # у стисненому архіві
JSON-логи через jq:
jq -c 'select(.level=="error")' app.log
jq -r 'select(.traceId=="4bf92f35...") | [.ts,.service,.msg] | @tsv' app.log
jq -s 'group_by(.error) | map({error: .[0].error, n: length})' app.log
У PowerShell аналог grep — Select-String, а tail -f — Get-Content -Wait -Tail 50.