Python >> Tutoriel Python >  >> Python

Utilisation de Sentry pour gérer les exceptions Python dans les projets Django

Les applications Web construites dans Django peuvent devenir extrêmement complexes au fil du temps, ce qui est l'une des raisons pour lesquelles la gestion centralisée des erreurs est importante. Ce didacticiel vous guidera dans l'ajout d'une configuration Sentry de base gratuite à un nouveau projet Django.

Lorsque nous aurons terminé, vous pourrez afficher les rapports d'erreurs centralisés dans le tableau de bord Sentry comme vous le voyez dans cette capture d'écran :

Exigences du didacticiel

Tout au long de ce didacticiel, nous allons utiliser les dépendances suivantes, que nous allons installer dans un instant. Assurez-vous également que Python 3, de préférence 3.7 ou une version plus récente, est installé dans votre environnement :

Nous utiliserons les dépendances suivantes pour terminer ce didacticiel :

  • Framework Web Django, version 3.1
  • sentry-sdk, version 0.16.5

Tout le code de cet article de blog est disponible en open source sous licence MIT sur GitHub sous le répertoire sentry-handle-exceptions-django-projects du référentiel blog-code-examples. Utilisez le code source comme vous le souhaitez pour vos propres projets.

Configuration de l'environnement de développement

Accédez au répertoire dans lequel vous conservez vos environnements virtuels Python.Créez un nouvel environnement virtuel pour ce projet à l'aide de la commande suivante.

Démarrez le projet Django en créant un nouvel environnement virtuel à l'aide de la commande suivante. Je recommande d'utiliser un répertoire séparé tel que ~/venvs/ (le tilde est un raccourci pour le home de votre utilisateur répertoire) afin que vous sachiez toujours où se trouvent tous vos environnements virtuels.

python3 -m venv ~/venvs/djsentry

Activez le virtualenv avec le activate script shell :

source ~/venvs/djsentry/bin/activate

Une fois la commande ci-dessus exécutée, l'invite de commande changera de sorte que le nom de virtualenv soit ajouté au format d'invite de commande d'origine, donc si votre invite est simplement $ , il ressemblera maintenant à ceci :

(djsentry) $

N'oubliez pas que vous devez activer votre environnement virtuel dans chaque nouvelle fenêtre de terminal où vous souhaitez utiliser des dépendances dans l'environnement virtuel.

Nous pouvons maintenant installer le Djangopackage dans le virtualenv activé mais autrement vide.

pip install django==3.1 sentry-sdk==0.16.5

Recherchez une sortie similaire à la suivante pour confirmer que les packages appropriés ont été correctement installés à partir de PyPI.

(djsentry) $ pip install django==3.1 sentry-sdk==0.16.5
Collecting django
  Downloading https://files.pythonhosted.org/packages/2b/5a/4bd5624546912082a1bd2709d0edc0685f5c7827a278d806a20cf6adea28/Django-3.1-py3-none-any.whl (7.8MB)
    100% |████████████████████████████████| 7.8MB 6.3MB/s 
Collecting sentry-sdk
  Downloading https://files.pythonhosted.org/packages/f4/4c/49f899856e3a83e02bc88f2c4945aa0bda4f56b804baa9f71e6664a574a2/sentry_sdk-0.16.5-py2.py3-none-any.whl (113kB)
    100% |████████████████████████████████| 122kB 33.7MB/s 
Collecting asgiref~=3.2.10 (from django)
  Using cached https://files.pythonhosted.org/packages/d5/eb/64725b25f991010307fd18a9e0c1f0e6dff2f03622fc4bcbcdb2244f60d6/asgiref-3.2.10-py3-none-any.whl
Collecting sqlparse>=0.2.2 (from django)
  Using cached https://files.pythonhosted.org/packages/85/ee/6e821932f413a5c4b76be9c5936e313e4fc626b33f16e027866e1d60f588/sqlparse-0.3.1-py2.py3-none-any.whl
Collecting pytz (from django)
  Using cached https://files.pythonhosted.org/packages/4f/a4/879454d49688e2fad93e59d7d4efda580b783c745fd2ec2a3adf87b0808d/pytz-2020.1-py2.py3-none-any.whl
Collecting urllib3>=1.10.0 (from sentry-sdk)
  Using cached https://files.pythonhosted.org/packages/9f/f0/a391d1463ebb1b233795cabfc0ef38d3db4442339de68f847026199e69d7/urllib3-1.25.10-py2.py3-none-any.whl
Collecting certifi (from sentry-sdk)
  Using cached https://files.pythonhosted.org/packages/5e/c4/6c4fe722df5343c33226f0b4e0bb042e4dc13483228b4718baf286f86d87/certifi-2020.6.20-py2.py3-none-any.whl
Installing collected packages: asgiref, sqlparse, pytz, django, urllib3, certifi, sentry-sdk
Successfully installed asgiref-3.2.10 certifi-2020.6.20 django-3.1 pytz-2020.1 sentry-sdk-0.16.5 sqlparse-0.3.1 urllib3-1.25.10

Nous pouvons commencer à coder l'application maintenant que toutes nos dépendances requises sont installées.

Codage de l'application initiale

Nous avons tout ce dont nous avons besoin pour commencer à créer notre application.

Nous pouvons utiliser le Django django-admin outil pour créer la structure de code passe-partout pour lancer notre projet. Allez dans le répertoire où vous développez vos applications. Par exemple, j'utilise généralement /Users/matt/devel/py/ pour tous les projets myPython. Exécutez ensuite la commande suivante pour démarrer un projet Django nommé djsentry :

django-admin.py startproject djsentry

Notez que dans ce didacticiel, nous utilisons le même nom pour le répertoire du projet virtualenv et Django, mais ils peuvent avoir des noms différents si vous préférez cela pour organiser vos propres projets.

Le django-admin la commande crée un répertoire nommé djsentry ainsi que plusieurs sous-répertoires que vous devriez connaître si vous avez déjà travaillé avec Django.

Modifiez les répertoires dans le nouveau projet.

cd djsentry

Créer une nouvelle application Django dans djsentry .

python manage.py startapp errors

Django va générer un nouveau dossier nommé errors pour le projet. Nous devons mettre à jour les URL afin que l'application soit accessible avant d'écrire notre views.py code.

Ouvrir djsentry/djsentry/urls.py . Ajoutez les lignes en surbrillance pour que le résolveur d'URL vérifie le errors apppour des routes supplémentaires à faire correspondre avec les URL qui sont demandées à cette application Django.

# djsentry/djsentry/urls.py
from django.conf.urls import include
from django.contrib import admin
from django.urls import path


urlpatterns = [
    path('', include('errors.urls')),
    path('admin/', admin.site.urls),
]

Économisez djsentry/djsentry/urls.py et ouvrezdjsentry/djsentry/settings.py .Ajouter le errors application à settings.py en insérant la ligne en surbrillance :

# djsentry/djsentry/settings.py
# Application definition

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'errors',
]

Assurez-vous de changer le DEBUG par défaut et SECRET_KEY valeurs en settings.py avant de déployer du code en production. Sécurisez correctement votre application avec les informations des checklists de déploiement Djangoproduction afin de ne pas ajouter votre projet à la liste des applications piratées sur le web.

Enregistrez et fermez settings.py .

Prochain changement dans le djsentry/errors annuaire. Créez un nouveau fichier nommé urls.py pour contenir les itinéraires pour le errors application.

Ajoutez toutes ces lignes au djsentry/errors/urls.py vide fichier.

# djsentry/errors/urls.py
from django.conf.urls import url
from . import views

urlpatterns = [
    url(r'^$', views.errors_index, name="index"),
]

Économisez djsentry/errors/urls.py . Ouvrirdjsentry/errors/views.py pour ajouter les deux lignes en surbrillance suivantes. Vous pouvez conserver le commentaire passe-partout "# Créez vos vues ici." ou supprimer comme je le fais habituellement.

# djsentry/errors/views.py
from django.shortcuts import render


def errors_index(request):
    return render(request, 'index.html', {})

Ensuite, créez un répertoire pour vos fichiers de modèle nommé templates sous le djmaps/maps répertoire de l'application.

mkdir templates

Créez un nouveau fichier nommé index.html dans djsentry/errors/templates qui contient le balisage de langage de modèle Django suivant.

<!DOCTYPE html>
<html>
  <head>
    <title>First step for errors</title>
  </head>
  <body>
   <h1>Hello, world!</h1>
  </body>
</html>

Nous pouvons tester cette page statique pour nous assurer que tout notre code est correct avant de commencer à ajouter l'essentiel de la fonctionnalité au projet. Allez dans le répertoire de base de votre projet Django où se trouve le manage.py fichier est localisé. Exécutez le serveur de développement avec la commande suivante :

python manage.py runserver

Le serveur de développement Django devrait démarrer sans problème autre qu'un avertissement de migrations non appliquées.

Watching for file changes with StatReloader
Performing system checks...

System check identified no issues (0 silenced).

You have 18 unapplied migration(s). Your project may not work properly until you apply the migrations for app(s): admin, auth, contenttypes, sessions.
Run 'python manage.py migrate' to apply them.
August 15, 2020 - 17:26:57
Django version 3.1, using settings 'djsentry.settings'
Starting development server at http://127.0.0.1:8000/
Quit the server with CONTROL-C.

Ouvrez un navigateur Web et accédez à localhost:8000 .

Notre code fonctionne, mais il ne fait certainement pas grand-chose pour le moment. Addentry-sdk afin que nous puissions comprendre comment cela fonctionne.

Ajout de Sentry et de la bibliothèque sentry-sdk

Nous pouvons maintenant ajouter Sentry et le tester avec un tas d'erreurs pour nous assurer qu'il fonctionne correctement.

Sentry peut soit être auto-hébergé, soit être utilisé comme service cloud via Sentry.io. Dans ce didacticiel, nous utiliserons la version hébergée dans le cloud car elle est plus rapide que la configuration de votre propre serveur et gratuite pour les petits projets.

Accédez à la page d'accueil de Sentry.io.

Connectez-vous à votre compte ou créez un nouveau compte gratuit. Vous serez sur le tableau de bord du compte principal après vous être connecté ou avoir terminé le processus d'inscription Sentry.

Il n'y a pas encore d'erreurs enregistrées sur le tableau de bord de notre compte, ce qui est normal car nous n'avons pas encore connecté notre compte à notre projet Django.

Créez un nouveau projet Sentry uniquement pour cette application en cliquant sur "Projets" dans la barre latérale gauche pour accéder à la page Projets.

Sur la page Projets, cliquez sur le bouton "Créer un projet" dans le coin supérieur droit de la page.

Vous pouvez choisir "Django" ou sélectionner "Python". Je choisis généralement "Python" si je ne sais pas encore quel framework je vais utiliser pour construire mon application. Ensuite, donnez un nom à votre nouveau projet, puis appuyez sur le bouton "Créer un projet". Notre nouveau projet est prêt à être intégré à notre code Python.

Nous avons besoin de l'identifiant unique de notre compte et de notre projet pour autoriser notre code Python à envoyer des erreurs à cette instance Sentry. Le moyen le plus simple d'obtenir ce dont nous avons besoin est d'aller sur la page de documentation de Python+Django et de lire comment configurer le SDK.

Copiez le paramètre de chaîne pour le init et définissez-la comme une variable d'environnement plutôt que de l'exposer dans le code de votre projet.

export SENTRY_DSN='https://yourkeygoeshere.ingest.sentry.io/project-number'

Assurez-vous de remplacer "votreclévaici" par votre propre identifiant unique et "numéro de projet" par l'ID qui correspond au projet que vous venez de créer.

Vérifiez que le SENTRY_DSN est défini correctement dans votre shell en utilisant le echo commande :

echo $SENTRY_DSN

Ensuite, mettez à jour settings.py avec les nouvelles lignes en surbrillance suivantes :

# settings.py
import os
import sentry_sdk

from pathlib import Path
from sentry_sdk.integrations.django import DjangoIntegration


# Build paths inside the project like this: BASE_DIR / 'subdir'.
BASE_DIR = Path(__file__).resolve(strict=True).parent.parent

En bas du fichier après la ligne avec STATIC_URL , ajoutez la configuration Sentry :

STATIC_URL = '/static/'

sentry_sdk.init(
    dsn=os.getenv('SENTRY_DSN'),
    integrations=[DjangoIntegration()],

    # If you wish to associate users to errors (assuming you are using
    # django.contrib.auth) you may enable sending PII data.
    send_default_pii=True
)

Maintenant que nous avons la configuration en place, nous pouvons délibérément faire des erreurs pour tester la connexion au service de Sentry.

Test de la détection d'erreurs de Sentry

Nous allons modifier une partie du code existant pour lancer délibérément des exceptions afin de nous assurer que tout fonctionne correctement.

Commencez par ouvrir errors/views.py et la mettre à jour avec une nouvelle ligne en surbrillance qui lèvera automatiquement une exception générique lorsque cette fonction est appelée.

# djsentry/errors/views.py
from django.shortcuts import render


def errors_index(request):
    raise Exception('testing exception')
    return render(request, 'index.html', {})

Aller à localhost:8000 dans votre navigateur et vous obtiendrez immédiatement cette page d'exception lors de l'exécution du serveur de développement :

Nous pouvons également essayer du code qui ne se contente pas de déclencher une exception, mais qui en crée une lors de son exécution, comme cette opération de division par zéro :

# djsentry/errors/views.py
from django.shortcuts import render


def errors_index(request):
    division_by_zero = 1 / 0
    return render(request, 'index.html', {})

Si ces exceptions apparaissent toutes les deux dans le tableau de bord Sentry comme ceci, vous êtes prêt :

Les exceptions ci-dessus n'étaient que quelques façons génériques de tester que tout fonctionne pour envoyer des informations d'erreur à Sentry. Cette configuration gérera également de nombreuses autres exceptions Django que vous rencontrerez probablement lors de la construction du reste de votre projet Django.

Ressources supplémentaires

Nous venons de terminer la construction d'un projet Django qui utilise Sentry pour la gestion centralisée des erreurs.

Ensuite, essayez quelques-uns de ces autres didacticiels Django connexes :

  • Suivre les données utilisateur quotidiennes dans Django avec django-user-visit
  • Utiliser rapidement Bootstrap 4 dans un modèle Django avec un CDN
  • Comment ajouter des cartes aux projets d'application Web Django avec Mapbox

Si vous avez des questions ou des commentaires sur ce didacticiel, veuillez me contacter via Twitter @fullstackpython, ou sur GitHub @mattmakai. Vous voyez quelque chose qui ne va pas avec ce message ? La source de cette page sur GitHuband soumet une pull request.