Ось твій урок у стилі CS50! 🚀
🎓 Урок: Логування та Моніторинг
(або "Як не літати наосліп")
1. 🔥 Вступ: Проблема та мотивація
Уявіть, що ви — пілот літака. Ви летите вночі, у суцільній темряві, над океаном. Раптом двигун починає дивно гудіти.
А тепер уявіть, що у вашій кабіні немає жодного приладу. Жодної лампочки, жодної стрілки, жодного екрана. Тільки штурвал і темрява за вікном. Страшно?
У програмуванні це називається запустити код без логів та моніторингу.
Коли ви пишете код на своєму ноутбуці, ви бачите термінал. Ви бачите помилки. Але коли ваш код працює на сервері десь у хмарі (AWS, Google Cloud), він стає тим самим літаком у нічному небі. * Якщо він "впаде" — як ви дізнаєтесь, чому? * Якщо він почне "гальмувати" — як ви зрозумієте, де саме? * Чи вистачить йому "палива" (пам’яті) до ранку?
Без логування та моніторингу ви — сліпий детектив, який прийшов на місце злочину, де все вже прибрали. Логування залишає відбитки пальців. Моніторинг повідомляє вам про злочин, поки він ще відбувається.
Сьогодні ми навчимося перетворювати "чорну скриньку" на прозорий механізм. Поїхали!
2. 🧠 Теоретична база (без нудної академічності)
Давайте розберемо два ключові поняття. Вони як брати, але виконують різні ролі.
📜 1. Логування (Logging) — це "Щоденник капітана"
Це історія подій. Це текстові записи про те, що робила програма в конкретний момент часу. * Аналогія: Бортовий самописець ("чорна скринька"). * Питання: "Чому це зламалося вчора о 14:00?"
📊 2. Моніторинг (Monitoring) — це "Приладова панель"
Це агреговані дані в реальному часі. Це графіки, цифри, зелені або червоні лампочки. * Аналогія: Спідометр, рівень палива, температура двигуна. * Питання: "Чи здорова система прямо зараз?"
Як це працює під капотом?
Логування:
Коли ви пишете print("Hello"), ви просто кидаєте текст у стандартний вивід (екран). У "дорослому" логуванні ми пишемо не просто текст, а структуроване повідомлення:
1. Timestamp (Коли?) — 2023-10-27 10:00:05
2. Level (Наскільки важливо?) — INFO, WARNING, ERROR
3. Message (Що сталося?) — User 42 failed to login
Рівні важливості (запам'ятайте їх, це база!): * 🟢 DEBUG: Для вас, розробників. Дрібні деталі, змінні. (Вмикаємо тільки коли лагодимо). * 🔵 INFO: Звичайний хід подій. "Сервер запустився", "Користувач увійшов". * 🟡 WARNING: Щось пішло не так, але ми працюємо далі. "Мало місця на диску", "Пароль застарілий". * 🔴 ERROR: Помилка виконання операції. "Не вдалося зберегти файл", "База даних не відповідає". * 🔥 CRITICAL: Все пропало. Система падає. Потрібно будити адміна о 3-й ночі.
3. 🧪 Приклади (від print до PRO)
Приклад 1: Як роблять новачки (і чому це погано)
Уявіть, що ви очікуєте побачити в консолі, якщо станеться помилка ділення на нуль?
def divide(a, b):
if b == 0:
print("Ой, помилка!") # ❌ Погано!
return None
return a / b
divide(10, 0)
Чому це погано? * Ми не знаємо коли це сталося. * Ми не знаємо де це сталося (в якій функції). * В потоці тисяч повідомлень ви просто пропустите це "Ой".
Приклад 2: Як роблять профі (модуль logging)
Тепер подивимось на той самий код, але з використанням стандартної бібліотеки Python.
import logging
# Налаштовуємо логер: показувати час, рівень і повідомлення
logging.basicConfig(
level=logging.INFO,
format='%(asctime)s - %(levelname)s - %(message)s'
)
def divide(a, b):
logging.info(f"Спроба поділити {a} на {b}") # 🔵 Записуємо дію
if b == 0:
logging.error("Спроба ділення на нуль! Операцію скасовано.") # 🔴 Фіксуємо проблему
return None
result = a / b
logging.info(f"Успіх: результат {result}")
return result
divide(10, 0)
divide(10, 2)
Результат у консолі:
2023-10-27 12:00:01 - INFO - Спроба поділити 10 на 0
2023-10-27 12:00:01 - ERROR - Спроба ділення на нуль! Операцію скасовано.
2023-10-27 12:00:02 - INFO - Спроба поділити 10 на 2
2023-10-27 12:00:02 - INFO - Успіх: результат 5.0
Бачите різницю? Тепер ми маємо контекст. Якщо це станеться вночі, ми вранці відкриємо файл і побачимо точний час злочину.
Приклад 3: Зачатки Моніторингу
Моніторинг — це коли ми не читаємо текст, а дивимось на метрики. Уявимо, що ми рахуємо кількість помилок.
error_counter = 0 # Це наша найпростіша метрика
def process_payment(amount):
global error_counter
try:
if amount < 0:
raise ValueError("Сума не може бути від'ємною")
print(f"Оплата {amount} грн пройшла.")
except Exception as e:
error_counter += 1 # 📈 Збільшуємо метрику
logging.error(f"Помилка оплати: {e}")
# Симуляція роботи
process_payment(100)
process_payment(-50)
process_payment(-20)
# Dashboard (спрощено)
print(f"\n--- МОНІТОРИНГ ---")
print(f"Помилок за останню хвилину: {error_counter}")
if error_counter > 1:
print("🚨 ALERT: Забагато помилок! Надсилаю SMS адміну!")
Що тут відбулося? Ми не просто записали помилку. Ми їх порахували. Якщо лічильник перевищує поріг (threshold) — спрацьовує Alert (тривога). Саме так ви дізнаєтесь про проблему раніше, ніж подзвонять розлючені клієнти.
4. 🛠 Практична частина
Прийшов час забруднити руки! Виконайте ці завдання:
🔹 Завдання 1: "Прощавай, print"
Візьміть будь-який свій старий код (або напишіть функцію, яка відкриває файл). Замініть усі print() на logging.info() та logging.error().
* Мета: Налаштувати basicConfig так, щоб виводився час.
🔹 Завдання 2: "Фільтр шуму"
Змініть налаштування level=logging.WARNING. Запустіть код із Завдання 1.
* Питання: Куди ділися повідомлення logging.info? Чому це корисно на "бойовому" сервері (production)?
🔹 Завдання 3: "Детектив"
Напишіть код, який симулює підключення до бази даних.
1. Зробіть цикл, який намагається підключитися 5 разів.
2. Якщо спроба №3 невдала — пишіть WARNING ("Спроба 3 провалилась, пробуємо ще").
3. Якщо спроба №5 невдала — пишіть CRITICAL ("База лежить, ми падаємо") і завершуйте програму.
🔹 Завдання 4: Міні-кейс "Інтернет-магазин"
Уявіть, що ви пишете функцію "Додати в кошик".
* Що ви залогуєте як INFO? (Товар додано).
* Що ви залогуєте як WARNING? (Товар закінчується на складі, залишилось 2 шт).
* Що ви залогуєте як ERROR? (Товар відсутній, але користувач намагався його купити).
* Реалізуйте це в коді.
5. 💡 Мислення як у розробника
Як відрізнити новачка від профі, дивлячись тільки на логи?
-
Секретні дані: Новачок логує все підряд:
logging.info(f"User login with password: {password}").- 🛑 СТОП! Ніколи, чуєте, НІКОЛИ не пишіть паролі, токени карток чи API-ключі в логи. Це дірка в безпеці. Логи читають багато людей.
-
Занадто багато шуму: Якщо ви поставите
logging.infoу цикл, який крутиться 1000 разів на секунду, ви "заспамите" диск і вб’єте сервер логами.- ✅ Порада: Використовуйте
DEBUGдля циклів, а на продакшн ставте рівеньINFOабоWARNING.
- ✅ Порада: Використовуйте
-
"Я потім подивлюсь": Логування без перегляду логів — це як купити камеру спостереження і не підключити її до монітора.
- ✅ Порада: Якщо сталася помилка
ERROR— ви маєте про це знати. В реальних проектах використовують системи типу Sentry або ELK Stack, які збирають логи і малюють красиві графіки.
- ✅ Порада: Якщо сталася помилка
6. 🧩 Підсумок
Отже, що ми сьогодні зробили? Ми перейшли від "коду, який мовчить" до "коду, який розповідає історію".
- Логування — це історія хвороби вашої програми (Минуле).
- Моніторинг — це пульс вашої програми (Теперішнє).
- Ми знаємо, що
print()— для навчання, аlogging— для роботи. - Ми знаємо рівні:
DEBUG->INFO->WARNING->ERROR->CRITICAL.
Тепер ви вмієте: Залишати сліди, які допоможуть вам (або вашим колегам) врятувати систему, коли вона впаде о 3-й годині ночі.
🔜 У наступній серії: Окей, ми побачили в логах помилку. Ми її виправили. Але як зробити так, щоб після нашого виправлення не зламалося щось інше? Наступна тема: Тестування (Unit Tests). Як довіряти своєму коду.
А поки — це був CS50. (Тобто, наш урок). 😉