QA Interview Hub · База знань · Тести

Логи й observability

Логи для QA

Що в записі логу й що означають рівні

Лог — це журнал подій, які застосунок сам про себе записує. Для QA це найкоротший шлях від «щось зламалось» до «ось де й чому». Типовий запис містить:

  • timestamp — час події (краще в UTC, з мілісекундами і зоною, наприклад ISO 8601);
  • рівень (severity);
  • джерело — сервіс, інстанс, клас чи модуль, інколи потік;
  • повідомлення — що сталося;
  • контекст — request id / trace id, user id (псевдонімізований), параметри, код помилки, стек виклику.

Рівні від найдетальнішого до найкритичнішого:

  • TRACE — дуже докладний хід виконання, зазвичай вимкнений;
  • DEBUG — деталі для розробника: значення змінних, гілки логіки; на проді зазвичай вимкнений;
  • INFO — звичайні значущі події: старт сервісу, замовлення створено;
  • WARN — щось дивне, але система впоралась: повторна спроба, застаріле API, повільна відповідь;
  • ERROR — операція не вдалася (запит завершився помилкою), потрібна увага;
  • FATAL — застосунок не може продовжувати роботу (є не в усіх бібліотеках).

Поріг рівня задається конфігурацією: на рівні INFO ви не побачите DEBUG. Тому «в логах нічого немає» інколи означає лише, що потрібний рівень вимкнений на цьому оточенні.

Що перевіряє QA: що помилка справді потрапляє в ERROR (а не губиться), що валідаційні відмови користувача (400) не засмічують ERROR, що в записі є контекст для розслідування, і що в ньому немає паролів, токенів і персональних даних.

Структуровані й текстові логи

Текстовий лог — вільний рядок для людини:

2026-10-12 09:14:03,512 ERROR [checkout] Payment failed for order 8841: gateway timeout

Його легко читати очима, але важко аналізувати: щоб дістати order id чи тривалість, потрібні regex, які ламаються при зміні формулювання.

Структурований лог — зазвичай один JSON-об’єкт на рядок (NDJSON / JSON Lines):

{"ts":"2026-10-12T09:14:03.512Z","level":"error","service":"checkout","msg":"payment failed","orderId":8841,"traceId":"4bf92f3577b34da6a3ce929d0e0e4736","error":"gateway timeout","durationMs":30012}

Поля можна фільтрувати й агрегувати без парсингу тексту: «усі помилки сервісу checkout за останню годину, згруповані за error». Тому в сучасних системах логи пишуть структурованими, а повідомлення роблять стабільним (без змінних усередині), а змінне виносять у поля.

Практичні правила:

  • одна подія — один рядок; стек-трейс — у полі, а не розмазаний на десятки рядків (інакше агрегатор розірве запис);
  • іменування полів єдине в усіх сервісах (наприклад, traceId, userId);
  • не логувати великі тіла запитів/відповідей цілком;
  • для людини локально можна використовувати «гарний» формат, на проді — JSON.

Для QA: структуровані логи дають змогу автотесту точно знайти запис за полем, а не за підрядком у повідомленні.

Де шукати логи й як локалізувати баг за ними

Де лежать логи:

  • браузер: DevTools → Console (JS-помилки, console.error, помилки ресурсів), Network (статуси й тіла відповідей);
  • бекенд: stdout/stderr контейнера (docker logs, kubectl logs), файли на сервері, а в зрілих системах — централізований сховок (ELK/OpenSearch, Loki, Datadog);
  • CI: консоль джоби та артефакти (логи сервісів, звіти);
  • мобільні: Android — adb logcat / Logcat в Android Studio; iOS — консоль Xcode, Console.app, log stream; краш-звіти — Crashlytics/Sentry.

Як локалізувати баг:

  1. Відтворіть і зафіксуйте точний час та оточення (з урахуванням часової зони!).
  2. У DevTools подивіться Console і Network: чи є червоні запити? Який статус? Якщо запит пішов і повернув 5xx — проблема на бекенді, якщо запит не пішов або є JS-виняток — на фронтенді; 4xx — часто невірні дані чи авторизація.
  3. Візьміть request id / trace id з заголовка відповіді чи тіла помилки й знайдіть за ним записи у логах бекенду.
  4. Знайдіть першу помилку в ланцюжку, а не останню: каскадні збої породжують десятки наступних ERROR.
  5. Подивіться, що було до неї: WARN, повторні спроби, зміни конфігурації, деплой.

Що додати в баг-репорт: кроки, очікуваний/фактичний результат, оточення і версію збірки, час із зоною, request/trace id, відповідний уривок логу (без секретів), скріншот чи HAR/trace. Така заявка економить розробнику час на відтворення.