django-processinfo: Statistiken von laufenden Django-Apps...

Du hast eine Idee für ein Projekt?
Antworten
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

[EDIT: Projekt Webseite: https://github.com/jedie/django-processinfo ]

Hab mal so eine Idee für eine art profiler Applikation.

Es sollen Informationen gesammelt werden von laufenden Django Instanzen.

Mögliche Informationen:
- Response Zeiten
- Speicherverbrauch
- Anzahl Request pro Stunde/Tage
- Aktive os.geteuid()
- getpass.getuser()
- os.getloadavg()

Diese Informationen sollten alle in ein und der selben DB-Tabelle gesammelt werden. So das man einen Überblick bekommt, in einem Multi-SITE_ID (Also mehrere laufende Instanzen/Prozesse) und Multi-Threaded-Umgebung

Den Speicherverbrauch ermitteln, ist allerdings IMHO nicht so leicht.
Ich hab dazu zwar in https://github.com/jedie/PyLucid-system ... manager.py mal was gemacht. Das läuft auch, aber es durchkämmt das /proc/ Verzeichnis. Ist also sehr Low-Level.
Es spuckt u.a. Informationen aus wie:

Code: Alles auswählen

    total processes: 153
    total treads: 282
    user processes: 4
    user threads: 19
    filtered by user ID: 5019
    current process ID: 28547

pid 	Peak virtual memory size 	Peak resident set size 	Threads 	Programm 	kill
28535 	180552 kB 	70936 kB 	6 	/var/www/clients/client3/web33/web/python index.fcgi 	
28547 	306684 kB 	73764 kB 	6 	/var/www/clients/client3/web33/web/python index.fcgi 	
28548 	246872 kB 	72448 kB 	6 	/var/www/clients/client3/web33/web/python index.fcgi 	

Process name 	VmPeak 	VmHWM
python 	716.9 MB 	212.1 MB
[EDIT1: Aber man könnte vielleicht nur /proc/self/status auswerten, siehe: http://stackoverflow.com/questions/8979 ... -get-usage ]


Was es nicht soll:
* Informationen sammeln, die auch in der Apache Log drin stehen oder die sowas wie Piwik liefern kann.
* die laufende Instanz sollte nicht zu sehr gebremst werden. Also möglichst wenig loggen/sammeln

Das ganze sollte nicht echtes Profiling zu Optimierungszwecke werden. Dazu gibt es schon ein paar Dinge, z.B.:
https://github.com/django-debug-toolbar ... ug-toolbar
https://github.com/django-extensions/django-extensions
siehe auch: https://code.djangoproject.com/wiki/ProfilingDjango

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

So, ich habe nun mit http://www.python-forum.de/viewtopic.php?f=11&t=27178 die Möglichkeit Informationen aus /proc/$$/status zu lesen.
Außerdem gibt es noch http://docs.python.org/library/resource.html

Doch welche Informationen sind wirklich interessant???

Ich denke auf jeden Fall ru_utime, ru_stime...

Beim Speicherverbrauch bin ich mir aber nicht sicher, was interessant ist. Im Netz finde ich wenig Informationen dazu. Angaben aus der manpage sagen mir auch weniger was:
* VmPeak: Peak virtual memory size.
* VmSize: Virtual memory size.
* VmLck: Locked memory size.
* VmHWM: Peak resident set size ("high water mark").
* VmRSS: Resident set size.
* VmData, VmStk, VmExe: Size of data, stack, and text segments.
* VmLib: Shared library code size.
* VmPTE: Page table entries size (since Linux 2.6.10).

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Hab mal die Werte aus /proc/$$/status mit den aus dem Gnome "Systemüberwachung" verglichen. Er zeigt u.a. diese an:
* VmRSS - Resident set size - "Nicht auslagerbarer Speicher"
* VmPeak - Peak virtual memory size - "Virtueller Speicher"

In der Spalte "Speicher" zeigt die "Systemüberwachung" allerdings etwas an, was nicht direkt in der /proc/$$/status steht?!?

htop zeigt wohl VmSize (VIRT) und VmRSS (RES) an...

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

So... Sieht nun so aus:

Site statistics:
Bild

Process statistics:
Bild

Wie man in den Bildern unten sehen kann, dauert das sammeln der Daten wohl ca. 10ms...
Es wird auch nur eine /proc/$$/status gelesen und zwei Einträge in der DB gemacht.

Wer mal selber testen möchte, eine knappe Anleitung enthalten beide Seiten:

Sourcen: https://github.com/jedie/django-processinfo
PyPi: http://pypi.python.org/pypi/django-processinfo

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Mir ist aufgefallen, das zum einen in den "Site statistics" model die Daten falsch sind. Es müßten die Daten aller Prozesse aufaddiert werden, die zu der jeweiligen site gehören ;)

Dabei fällt auf, das ich eigentlich einige Daten doppelt speicher. Bzw. das man einige Site-Daten aus den existierenden Prozess Daten errechnen kann...

Um das ganze noch einen Mehrwert zu geben, könnte man die Statistik nicht nur auf Site/Prozess runterbrechen, sondern auf zusätzliche Informationen. Mir würden spontan einfallen:
  • * User-Typ (Anonymous, login, staff, superuser)
    * jeder einzelne User
    * Django Admin Bereich ja/nein
    * gesendeter mime-type
    * jeweilige URL
Aber, wenn man all dieses nutzten würde, würde man die Datenbank mit sehr, sehr vielen Daten füllen... Zwar dürfte der Speicher erstmal nicht knapp werden, aber das dauert immer länger. Der Overhead soll aber möglichst gering sein.

Evtl. könnte man Call-Backs machen und jeder kann selber entscheiden, was einem interessiert...

Meinungen dazu?

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

v0.2 sieht nun so aus:

Bild
Bild

Aber ich glaube ein paar Werte sind dabei falsch :?

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

jens hat geschrieben:Aber ich glaube ein paar Werte sind dabei falsch :?
Das müßte nun in v0.3 stimmen ;) z.B. wurden die Anzahl der Prozesse pro site falsch addiert. Daraus ergaben sich dann auch andere falsche Werte...

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Wer die Aktuelle Version mal Live sehen will: http://demo.pylucid.org/ User: test Passwort: 12345678

* Einloggen
* in die "Django Admin Seite" wechseln
* unter "Django_Processinfo" auf "Process statistics" und/oder "Site statistics" klicken

Zwischen "Process statistics" und "Site statistics" kann man dann auch oben in der Breadcrumbs leiste wechseln.

Zur Info: Dort läuft PyLucid in der sog. Standalone Variante, siehe: http://www.python-forum.de/viewtopic.ph ... 06#p205906
und zwar als fast_CGI mit den Parametern:

Code: Alles auswählen

    runfastcgi(
        protocol="fcgi", # fcgi, scgi, ajp, ... (django default: fcgi)
        host=None, # hostname to listen on (django default: None)
        port=None, # port to listen on (django default: None)
        socket=None, # UNIX socket to listen on (django default: None)

        method="threaded", # prefork or threaded (django default: "prefork")
        daemonize="false", # whether to detach from terminal (django default: None)
        umask=None, # umask to use when daemonizing e.g.: "022" (django default: None)
        pidfile=None, # write the spawned process-id to this file (django default: None)
        workdir="/", # change to this directory when daemonizing.  (django default: "/")

        minspare=2, # min number of spare processes / threads (django default:  2)
        maxspare=5, # max number of spare processes / threads (django default:  5)
        maxchildren=50, # hard limit number of processes / threads (django default: 50)
        maxrequests=100, # number of requests before killed/forked (django default: 0 = no limit)
        # maxrequests -> work only in prefork mode

        debug=settings.DEBUG, # Enable flup debug traceback page
        outlog=None, # write stdout to this file (django default: None)
        errlog=None, # write stderr to this file (django default: None)
    )
Siehe auch: https://github.com/jedie/PyLucid/blob/m ... index.fcgi

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Ich hab mir überlegt, das es auch nützlich ist, nicht nur min/avg/max Werte zu haben, sondern einen Verlauf.

Interessant erscheint mit dabei:
* RAM verbrauch
* response time
* system load
* Loads (response time in relation to processor time)

Darüber hinaus wäre auch ein Verlauf mit "requests/sec" interessant.

Generell wäre es gut zu wissen, wie viele Anfragen gibt es überhaupt und wie viel Last erzeugt die App auf dem System.

Gut wären die Werte um einzuschätzen, ob der Server ok ist oder nicht...

Die Frage ist, wie kann man die Werte Ressourcen schonend fest halten?

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
Antworten