2013-09-26 2 views

Antwort

11

coverage gunicorn <params> funktioniert nicht, weil Gunicorn Arbeitsprozesse erstellt, und das Modul coverage kann nicht über Gabeln (im Grunde, Erstellung neuer Prozesse) funktionieren. Sie können the coverage API, obwohl verwenden, zum Beispiel in dem Python-Modul, die WSGI-Anwendung enthält:

# wsgi_with_coverage.py 
import atexit 
import sys 
import coverage 
cov = coverage.coverage() 
cov.start() 

from wsgi import application # adjust to python module containing your wsgi application 


def save_coverage(): 
    print >> sys.stderr, "saving coverage" 
    cov.stop() 
    cov.save() 

atexit.register(save_coverage) 

Dann gunicorn -w 1 wsgi_with_coverage:application <other params> laufen.

Das Problem ist, die atexit Funktionen werden nicht aufgerufen, wenn Sie den Gunicorn-Prozess zum Beispiel über STRG + C beenden. Aber sie sind aufgerufen SIGHUP, wenn Sie also kill -HUP $(cat <gunicorn_pidfile_here>) tun, sollten die Coverage-Daten gespeichert werden (standardmäßig auf ".coverage" im aktuellen Verzeichnis).

Eine mögliche Einschränkung ist, dass dies nicht mit mehr als einem Gunicorn-Arbeiter funktioniert, weil sie alle die ".coverage" -Datei überschreiben würden. Wenn Sie unbedingt mehr als einen Worker benötigen, können Sie unter ".coverage-%d" % os.getpid() (geben Sie den Dateinamen via the data_file parameter to the coverage constructor) und the combine() method verwenden, um die einzelnen Messungen zusammenzuführen.

Dies sollte auch auf anderen WSGI-Servern funktionieren, je nachdem, ob sie ihren Worker-Prozessen ermöglichen, über die Methode atexit zu bereinigen.

+0

Die SIGHUP Beratung ist nicht so gut :). Gunicorn lädt die Arbeitsprozesse beim Abrufen von SIGHUP erneut. Das heißt, die erfassten Coverage-Daten werden nicht genau gespeichert, sondern mit den Daten überschrieben, die nur beim Laden auftreten. Das Senden von SIGTER dagegen löst den atexit-Handler ordnungsgemäß aus und schließt Gunicorn sauber ab. –