.. _profiling: .. index:: single: Profiling single: Django Silk single: Performance single: Report Profiling mit Django Silk ************************** Für den reibunglosen Ablauf einer Applikation ist es notwendig, ein Profiling der Anwendung zu machen. Dafür bietet sich das Djanjo-Paket ``django-silk`` an. Silk ist ein Live-Profilerstellungs- und Inspektionstool für Django. Silk fängt HTTP-Requests und Datenbankabfragen ab und speichert sie, bevor sie in einer Benutzeroberfläche zur weiteren Untersuchung angezeigt werden können. Installation ================ Wir müssen ``django-silk`` via pip installieren: .. code-block:: bash (eventenv) pip install django-silk und dann in der Middlewar in den Settings registieren. Dafür öffnen wir ``event_manager/event_manager/settings/base.py`` und fügen die Silk-Middleware am Besten ganz oben ein: .. code-block:: python MIDDLEWARE = [ "silk.middleware.SilkyMiddleware", "whitenoise.middleware.WhiteNoiseMiddleware", "django.middleware.security.SecurityMiddleware", "django.contrib.sessions.middleware.SessionMiddleware", "django.middleware.locale.LocaleMiddleware", "django.middleware.common.CommonMiddleware", "django.middleware.csrf.CsrfViewMiddleware", "django.contrib.auth.middleware.AuthenticationMiddleware", "django.contrib.messages.middleware.MessageMiddleware", "django.middleware.clickjacking.XFrameOptionsMiddleware", ] Darüberhinaus müssen wir ``silk`` noch in den ``INSTALLED_APPS`` registrieren, damit das System die App auch erkennt. .. code-block:: python INSTALLED_APPS = [ [..] "rest_framework", "rest_framework.authtoken", "silk", ] Um das Silk-Backend via Browser aufrufen zu können, legen wir nun die URLs fest. Dazu öffnen wir ``event_manager/event_manager/urls.py`` und fügen die URLs zum Silk-backend hinzu: .. code-block:: python urlpatterns = [ ... path('silk/', include('silk.urls', namespace='silk')), ] Nun können wir die Datenmigration durchführen: .. code-block:: bash python manage.py migrate python manage.py collectstatic Wir können das Backend nun unter ``http://127.0.0.1:8000/silk`` aufrufe aufrufen. Was kann Silk? ================== Die Hauptaufgaben von Silk sind: * Middleware zum Abfangen von HTTP-Requests und Responses * Ein SQL-Wrapper um Datenbankanfragen zu profilen * Ein Context Manager/decorator um Code-Blocks und Funktionen zu profilen * Ein graphisches User Interface für die Visualisierung des Profilings .. admonition:: Live-Profiling Bevor das Profiling im Produktiv-Betrieb eingesetzt wird, sollte es erstmal im lokalen Betrieb getestet werden. Bei sehr vielen Anfagen kann sich Profiling auf diese Art negativ auf die Performance auswirken. Datenbank-Abfragen analysieren ---------------------------------- Unter ``Summary`` finden sich alle durchgeführten Anfragen an das System. Mit Klick auf eine dieser Anfragen lässt sich die Datenbank-Performance und die Anzahl der Joins untersuchen: .. image:: /images/silk_1.png .. image:: /images/silk_2.png .. image:: /images/silk_3.png .. image:: /images/silk_4.png Code-Abschnitte profilen ------------------------- Interessanter wird es, wenn wir Codebereiche und Funktionen profilen wollen. Dazu bietet ``Silk`` mehrere möglichkeiten: einen Kontext-Manager, einen Decorator und dynamisches Profing über die Settings. In den Einstellung muss SILKY_PYTHON_PROFILER aktiviert werden, um den integrierten cProfile-Profiler von Python zu verwenden. Jede Anfrage wird separat untersucht und die Ausgabe des Profilers ist auf der Seite „Profiling“ der Anfrage in der Silk-Benutzeroberfläche verfügbar. in die ``event_manager/event_manager/settings/base.py`` tragen wir folgenes ein: .. code-block:: python SILKY_PYTHON_PROFILER = True SILKY_PYTHON_PROFILER_BINARY = True Zusätzlich dekorieren wir die ``categories`` aus den ``event_manager/events/views.py`` mit dem ``silk_profile-Dekorator``, um das sogenannte ``Silk-Profiling`` für diese View zu erstellen. Ohne den Dekorator würde standardmäßig nur das cProfiling gemacht. .. code-block:: python # importieren des silk_profile Decorators from silk.profiling.profiler import silk_profile # anderer code ... @silk_profile() def categories(request): .. Wenn wir jetzt erneut die Route ``http://127.0.0.1:8000/events/categories/`` aufrufen, finden wir im Silk-Backend das Profiling für diese Funktion (categories). .. image:: /images/silk_5.png .. image:: /images/silk_6.png Zusätzlich sollte ein Graph zu sehen sein: .. image:: /images/silk_7.png Zusätzliche Settings ----------------------- Um zu verhindern, dass das Silk-Backend öffentlich aufrufbar ist, müssen wir noch folgende Einträge in der ``event_manager/event_manager/settings/base.py`` machen: .. code-block:: python SILKY_AUTHENTICATION = True # User must login SILKY_AUTHORISATION = True # User must have permissions Nun können nur noch eingeloggte User mit Staff-Status das Silk-Backend aufrufen. Silk speichert immer den kompletten Response-Body ab. Das ist ist im Live-Betrieb unperformant. Deshalb sollte man das im Livebetrieb verhinden. Wir wollen nur einen Teil des Response-Bodys speichern, und zwar die ersten 1024 Byte. Ebenfalls in der ``event_manager/event_manager/settings/prod.py`` tragen wir ein: .. code-block:: python # der Defaultwert ist -1 und bedeutet: kein Limit. SILKY_MAX_RESPONSE_BODY_SIZE = 1024 Ein weiteres Problem im Live-Betrieb ist, dass wir bei vielen Anfragen nicht alle Anfragen untersuchen können. Oft reicht es, nur einen Teil der Anfragen zu loggen. Ebenso brauchen wir nicht alle Request speichern, sondern können einen Maximalwert an gespeicherten Requests angeben. Zwei weitere Settings in den Produktiv-Settings unter ``event_manager/event_manager/settings/prod.py`` sind also: .. code-block:: python # 20% der Anfragen loggen SILKY_INTERCEPT_PERCENT = 20 SILKY_MAX_RECORDED_REQUESTS = 10_000 Geloggte Daten löschen --------------------------- mit dem folgenden Management-Command können alle geloggten Daten gelöscht werden: .. code-block:: bash (eventenv) python manage.py silk_clear_request_log Weiterführende Informationen ============================= weiterführende Infos zu ``django-silk`` findet man hier: - ``_ - ``_