16đź‘Ť
coverage gunicorn <params>
does not work, because gunicorn creates worker processes, and the coverage
module can’t work across forks (basically, creation of new processes). You can use the coverage API, though, for example in the python module that contains your WSGI application:
# 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)
Then run gunicorn -w 1 wsgi_with_coverage:application <other params>
.
The problem is, the atexit
functions are not called if you kill the gunicorn process, for example via CTRL+C. But they are called on SIGHUP
, so if you do kill -HUP $(cat <gunicorn_pidfile_here>)
, the coverage data should be saved (by default to “.coverage” in the current directory).
A possible caveat is that this won’t work with more than one gunicorn worker, because they would all overwrite the “.coverage” file. If you absolutely need more than one worker, you could write to ".coverage-%d" % os.getpid()
(set the file name via the data_file
parameter to the coverage
constructor) and use the combine()
method to merge the individual measurements.
This should work on other WSGI servers, too, depending on whether they allow their worker processes to clean up via the atexit
method.