Monitorowanie i logowanie błędów w aplikacjach webowych

Kacper Sieradziński
Kacper Sieradziński
24 maja 2025Edukacja5 min czytania

W środowisku produkcyjnym nie ma miejsca na zgadywanie. Każdy wyjątek, opóźnienie czy spike CPU powinien być zarejestrowany, opisany i — najlepiej — zgłoszony automatycznie. Dlatego monitorowanie i logowanie błędów to kluczowy element utrzymania aplikacji webowych w Pythonie. W tym przewodniku poznasz, jak prawidłowo skonfigurować logowanie w Django, Flask i FastAPI, jak używać Sentry do trackingu błędów oraz jak monitorować metryki wydajności aplikacji.

Obraz główny Monitorowanie i logowanie błędów w aplikacjach webowych

Czym jest monitorowanie aplikacji?

Monitorowanie to proces zbierania i analizowania danych o działaniu aplikacji. Obejmuje:

  • logowanie błędów i wyjątków — rejestrowanie wszystkich nieoczekiwanych sytuacji,
  • śledzenie metryk wydajności — CPU, RAM, czas odpowiedzi, liczba requestów,
  • alertowanie w czasie rzeczywistym — automatyczne powiadomienia o problemach,
  • analizę trendów — długoterminowe obserwowanie zmian w zachowaniu aplikacji.

Celem monitoringu nie jest „mieć dashboard", tylko szybko wykrywać i diagnozować problemy, zanim zauważy je użytkownik. Dobrze skonfigurowany system monitorowania pozwala na proaktywne reagowanie na problemy, zamiast czekania na zgłoszenia użytkowników.

Logowanie błędów w Pythonie

Python ma wbudowany moduł logging, który wystarcza do większości przypadków — o ile jest dobrze skonfigurowany. Moduł logging oferuje elastyczny system poziomów logowania (DEBUG, INFO, WARNING, ERROR, CRITICAL) i różne handlery do zapisu logów.

Przykład konfiguracji logowania

Python
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 import logging logging.basicConfig( level=logging.INFO, format="%(asctime)s [%(levelname)s] %(name)s: %(message)s", handlers=[ logging.FileHandler("app.log"), logging.StreamHandler() ] ) logger = logging.getLogger(__name__) try: result = 1 / 0 except Exception as e: logger.exception("Błąd w obliczeniach")

Funkcja logger.exception() automatycznie dodaje pełny stack trace do logu, co jest kluczowe przy debugowaniu. Dzięki logging.FileHandler logi są zapisywane do pliku, a StreamHandler wyświetla je w konsoli.

Zaawansowana konfiguracja logowania

Dla bardziej zaawansowanych zastosowań możesz użyć konfiguracji słownikowej:

Python
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 import logging.config LOGGING_CONFIG = { 'version': 1, 'disable_existing_loggers': False, 'formatters': { 'standard': { 'format': '%(asctime)s [%(levelname)s] %(name)s: %(message)s' }, 'detailed': { 'format': '%(asctime)s [%(levelname)s] %(name)s [%(pathname)s:%(lineno)d]: %(message)s' }, }, 'handlers': { 'file': { 'class': 'logging.handlers.RotatingFileHandler', 'filename': 'app.log', 'maxBytes': 10485760,# 10MB 'backupCount': 5, 'formatter': 'detailed', }, 'console': { 'class': 'logging.StreamHandler', 'formatter': 'standard', }, }, 'loggers': { '': {# root logger 'handlers': ['file', 'console'], 'level': 'INFO', }, }, } logging.config.dictConfig(LOGGING_CONFIG)

RotatingFileHandler automatycznie rotuje pliki logów, gdy osiągną maksymalny rozmiar, co zapobiega przepełnieniu dysku. To szczególnie ważne w aplikacjach produkcyjnych.

Logowanie w Django

Django ma wbudowany system logowania, który można skonfigurować w settings.py. Django automatycznie loguje błędy 500, requesty i inne zdarzenia.

Konfiguracja logowania w Django

Python
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 # settings.py LOGGING = { 'version': 1, 'disable_existing_loggers': False, 'formatters': { 'verbose': { 'format': '{levelname} {asctime} {module} {process:d} {thread:d} {message}', 'style': '{', }, 'simple': { 'format': '{levelname} {message}', 'style': '{', }, }, 'handlers': { 'file': { 'level': 'INFO', 'class': 'logging.handlers.RotatingFileHandler', 'filename': 'logs/django.log', 'maxBytes': 1024*1024*15,# 15MB 'backupCount': 10, 'formatter': 'verbose', }, 'console': { 'level': 'DEBUG', 'class': 'logging.StreamHandler', 'formatter': 'simple' }, }, 'loggers': { 'django': { 'handlers': ['file', 'console'], 'level': 'INFO', }, 'myapp': { 'handlers': ['file', 'console'], 'level': 'DEBUG', }, }, }

Użycie logowania w widokach Django

Python
1 2 3 4 5 6 7 8 9 10 11 12 13 14 import logging logger = logging.getLogger(__name__) def my_view(request): logger.info(f'User {request.user} accessed the view') try: # Logika biznesowa widoku result = some_operation() logger.debug(f'Operation result: {result}') return JsonResponse({'status': 'success'}) except Exception as e: logger.error(f'Error in my_view: {str(e)}', exc_info=True) return JsonResponse({'status': 'error'}, status=500)

Django automatycznie loguje błędy 500 do loggera django.request, więc nie musisz ręcznie logować każdego wyjątku w widoku. Wystarczy, że użyjesz middleware do logowania requestów.

Logowanie w FastAPI

FastAPI nie ma wbudowanego systemu logowania, ale możesz łatwo skonfigurować logowanie używając standardowego modułu logging Pythona.

Konfiguracja logowania w FastAPI

Python
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 import logging from fastapi import FastAPI # Konfiguracja logowania logging.basicConfig( level=logging.INFO, format="%(asctime)s - %(name)s - %(levelname)s - %(message)s", handlers=[ logging.FileHandler("app.log"), logging.StreamHandler() ] ) logger = logging.getLogger(__name__) app = FastAPI() @app.get("/items/{item_id}") async def read_item(item_id: int): logger.info(f"Requested item {item_id}") try: # Logika biznesowa endpointu return {"item_id": item_id} except Exception as e: logger.error(f"Error getting item {item_id}: {str(e)}", exc_info=True) raise

Middleware do logowania requestów

Możesz stworzyć middleware do automatycznego logowania wszystkich requestów:

Python
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 import time import logging from fastapi import Request logger = logging.getLogger(__name__) @app.middleware("http") async def log_requests(request: Request, call_next): start_time = time.time() response = await call_next(request) process_time = time.time() - start_time logger.info( f"{request.method} {request.url.path} - " f"Status: {response.status_code} - " f"Time: {process_time:.3f}s" ) return response

To automatycznie loguje wszystkie requesty z informacją o metodzie HTTP, ścieżce, statusie odpowiedzi i czasie przetwarzania.

Sentry – profesjonalny tracking błędów

Sentry to popularne narzędzie do trackingu błędów, które automatycznie zbiera informacje o wyjątkach, stack traces, kontekście wykonania i informacje o użytkowniku. Sentry oferuje darmowy plan dla małych projektów i płatne plany dla większych aplikacji.

Instalacja Sentry

Bash
1 pip install sentry-sdk

Konfiguracja Sentry w Django

Python
1 2 3 4 5 6 7 8 9 10 11 # settings.py import sentry_sdk from sentry_sdk.integrations.django import DjangoIntegration sentry_sdk.init( dsn="https://your-sentry-dsn@sentry.io/project-id", integrations=[DjangoIntegration()], traces_sample_rate=1.0, send_default_pii=True, environment="production", )

DjangoIntegration automatycznie przechwytuje wszystkie błędy Django. traces_sample_rate kontroluje, jaki procent requestów jest śledzony dla analizy wydajności.

Konfiguracja Sentry w FastAPI

Python
1 2 3 4 5 6 7 8 9 10 11 12 13 import sentry_sdk from sentry_sdk.integrations.fastapi import FastApiIntegration from sentry_sdk.integrations.starlette import StarletteIntegration sentry_sdk.init( dsn="https://your-sentry-dsn@sentry.io/project-id", integrations=[ FastApiIntegration(), StarletteIntegration(), ], traces_sample_rate=1.0, environment="production", )

Po skonfigurowaniu, Sentry automatycznie przechwytuje wszystkie nieobsłużone wyjątki. Możesz też ręcznie raportować błędy:

Python
1 2 3 4 5 6 7 8 9 10 11 import sentry_sdk try: risky_operation() except Exception as e: sentry_sdk.capture_exception(e) # lub z dodatkowym kontekstem with sentry_sdk.push_scope() as scope: scope.set_tag("user_id", user.id) scope.set_extra("operation_data", operation_data) sentry_sdk.capture_exception(e)

Metryki wydajności

Metryki to dane numeryczne o działaniu aplikacji — czas odpowiedzi, wykorzystanie CPU, liczba requestów, błędy itp. Popularne narzędzia do zbierania metryk to Prometheus i Grafana.

Prometheus – zbieranie metryk

Prometheus to system monitorowania i alertowania, który zbiera metryki przez HTTP endpoint. Możesz użyć biblioteki prometheus-client w Pythonie:

Bash
1 pip install prometheus-client
Python
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 from prometheus_client import Counter, Histogram, start_http_server # Licznik requestów request_count = Counter('http_requests_total', 'Total HTTP requests', ['method', 'endpoint']) # Histogram czasu odpowiedzi request_duration = Histogram('http_request_duration_seconds', 'HTTP request duration') @app.middleware("http") async def track_metrics(request: Request, call_next): start_time = time.time() response = await call_next(request) duration = time.time() - start_time request_count.labels(method=request.method, endpoint=request.url.path).inc() request_duration.observe(duration) return response # Uruchom serwer metryk na porcie 8001 start_http_server(8001)

Prometheus będzie zbierać metryki z endpointu http://localhost:8001/metrics. Następnie możesz wizualizować je w Grafanie.

Integracja z Grafana

Grafana to narzędzie do wizualizacji metryk z Prometheusa. Tworzysz dashboardy z wykresami, które pokazują trendy wydajności, wykorzystanie zasobów i inne kluczowe metryki. Dzięki Grafanie możesz szybko zidentyfikować problemy i trendy w działaniu aplikacji.

Alerty i powiadomienia

Alerty to automatyczne powiadomienia o krytycznych problemach — wysokim współczynniku błędów, spowolnieniu aplikacji, braku dostępności itp. Możesz skonfigurować alerty w Sentry, Prometheus/Grafanie lub innych narzędziach monitorowania.

Alerty w Sentry

W Sentry możesz skonfigurować alerty, które wyzwalają się, gdy:

  • występuje określona liczba błędów w czasie,
  • pojawia się nowy typ błędu,
  • błąd wpływa na wielu użytkowników.

Alerty mogą być wysyłane przez e-mail, Slack, PagerDuty lub inne kanały komunikacji.

Alerty w Prometheus/Grafanie

Prometheus pozwala na definiowanie reguł alertów (Alertmanager), które wyzwalają się na podstawie zapytań PromQL:

YAML
1 2 3 4 5 6 7 8 9 groups: - name: application_alerts rules: - alert: HighErrorRate expr: rate(http_requests_total{status=~"5.."}[5m]) > 0.05 for: 5m annotations: summary: "High error rate detected" description: "Error rate is above 5% for 5 minutes"

Grafana również oferuje alerty, które mogą powiadamiać Cię o przekroczeniu progów metryk bezpośrednio z dashboardów.

Dobre praktyki monitorowania

Przy implementowaniu monitorowania warto pamiętać o kilku kluczowych zasadach:

  1. Loguj kontekst, nie tylko błędy — dodawaj informacje o użytkowniku, request ID, parametry funkcji. To ułatwia debugowanie.

  2. Używaj odpowiednich poziomów logowania — DEBUG dla szczegółów deweloperskich, INFO dla normalnych operacji, WARNING dla potencjalnych problemów, ERROR dla błędów wymagających uwagi.

  3. Strukturyzuj logi — używaj JSON formatów dla łatwiejszej analizy (np. structlog w Pythonie):

Python
1 2 3 4 import structlog logger = structlog.get_logger() logger.info("user_login", user_id=123, ip="192.168.1.1")
  1. Nie loguj wrażliwych danych — hasła, tokeny, numery kart kredytowych nigdy nie powinny trafiać do logów.

  2. Rotuj logi — używaj RotatingFileHandler lub podobnych, aby uniknąć przepełnienia dysku.

  3. Monitoruj same logi — śledź liczbę błędów, rozmiar plików logów, tempo rotacji.

  4. Korzystaj z agregacji — narzędzia takie jak ELK Stack (Elasticsearch, Logstash, Kibana) lub Loki pozwalają na centralizację i analizę logów z wielu źródeł.

  5. Ustaw odpowiednie progi alertów — zbyt czułe alerty prowadzą do zmęczenia alertami, zbyt mało czułe — do przegapienia problemów.

Podsumowanie

Monitorowanie i logowanie błędów to niezbędne elementy utrzymania profesjonalnej aplikacji webowej. Właściwie skonfigurowany system monitorowania pozwala na szybkie wykrywanie i diagnozowanie problemów, zanim wpłyną one na doświadczenia użytkowników. Połączenie logowania w Pythonie, Sentry do trackingu błędów oraz Prometheus/Grafany do metryk wydajności daje pełny obraz działania aplikacji.

Zacznij od podstawowego logowania w Pythonie, dodaj Sentry do trackingu błędów, a następnie rozbuduj system o metryki i alerty w miarę potrzeb projektu. Pamiętaj, że monitorowanie to inwestycja w stabilność i niezawodność aplikacji — im lepiej monitorujesz, tym szybciej możesz reagować na problemy.