You can then do one of a few things. The first is to add in the
following WSGI application to your configuration and delegate it to
the same daemon process group as your existing WSGI application.
import mod_wsgi
import pprint
import StringIO
def application(environ, start_response):
status = '200 OK'
stream = StringIO.StringIO()
pprint.pprint(mod_wsgi.thread_statistics(), stream=stream)
output = stream.getvalue()
response_headers = [('Content-type', 'text/plain'),
('Content-Length', str(len(output)))]
start_response(status, response_headers)
return [output]
Second, you could add a custom handler within your existing
application which calls 'thread_statistics()' from the 'mod_wsgi'
module and then transforms the dictionary it returns into a pretty
formatted HTML page for display.
Finally, you could start a back ground thread running which
periodically calls 'thread_statistics()' from the 'mod_wsgi' module
and dumps the details out to the Apache error log for later analysis.
Note that this feature is only implemented for daemon mode. Also, it
monitors the whole daemon mode process and not just one application.
It doesn't even matter if the application generating the summary to a
HTML page is running in a different application group (interpreter) so
long as it is in same process group.
Also don't assume that it will ship with mod_wsgi 3.0 as is. The code
hasn't even been cleaned up yet let alone any sanity brought to naming
of information it returns or even how the information is accessed.
That all said, for a simple hello world program with a sleep of 0.001
second in it, with only 5 daemon threads and ab concurrency of 10
example results are:
{'threads': [{'id': 0,
'requests_time_average': 0.0014356310160427807,
'requests_time_maximum': 0.066059999999999994,
'requests_time_minimum': 0.0011249999999999999,
'requests_time_total': 3.2215560000000001,
'requests_total': 2244,
'running': False},
{'id': 1,
'requests_time_average': 0.0014802679063360882,
'requests_time_maximum': 0.017203,
'requests_time_minimum': 0.001119,
'requests_time_total': 2.149349,
'requests_total': 1452,
'running': True},
{'id': 2,
'requests_time_average': 0.0014544432432432432,
'requests_time_maximum': 0.048439999999999997,
'requests_time_minimum': 0.001124,
'requests_time_total': 2.6907199999999998,
'requests_total': 1850,
'running': False},
{'id': 3,
'requests_time_average': 0.001393129470348574,
'requests_time_maximum': 0.0092510000000000005,
'requests_time_minimum': 0.001126,
'requests_time_total': 3.077423,
'requests_total': 2209,
'running': False},
{'id': 4,
'requests_time_average': 0.0014082352156514007,
'requests_time_maximum': 0.020750000000000001,
'requests_time_minimum': 0.001122,
'requests_time_total': 3.1671209999999999,
'requests_total': 2249,
'running': False}],
'threads_active': 2,
'threads_active_maximum': 5,
'threads_requests_total': 10004,
'threads_time_average': 0.0014300448820471811,
'threads_time_total': 14.306169000000001}
One final point. The whole point of this statistics gathering is to
monitor you real WSGI application. Some of the results before posted
by some were just monitoring the statistics program itself and what is
the point of that.
I'll be interested in results for some real applications.
Graham
You can do that in Python by using a custom dictionary class and
overriding setter/getter's etc for the class.
Graham
I presume that if I start using '.''s in names that JavaScript will
not like it. Ie., you will scream if have:
{ "process.id": 1234 }
<snip>
Do remember that JavaScript isn't the target of this. The primary user
of it will be Python code. So usability within Python is actually more
important.
> Gert: have you ever heard of a pastebin? And snipping the emails you're
> replying to? :P
He hasn't learnt yet either to save up all his emails until he has
something completely working and so one gets a dribble of mails one
has to sort through until you get to the one where it actually works.
Graham
Do remember that JavaScript isn't the target of this. The primary user
of it will be Python code. So usability within Python is actually more
important.
Please don't get worried overly about use of '.' in name. Mentioning
it was more to stir up Gert as I knew it probably wasn't going to work
for JavaScript. So, am unlikely to do it, although use of dots is
better where this feeds into publish/subscribe system as they usually
have flat namespace with '.' used as separator with name. If though
nested data structures are used, they can convert which ever way you
want.
Graham