Commit 688d79ac authored by Chris McDonough's avatar Chris McDonough

Make 'publisher-profile-file' configuration file setting work. Note that the...

Make 'publisher-profile-file' configuration file setting work.  Note that the environment variable "PROFILE_PUBLISHER" has been banished with this change.  We also change the core of Publish.py to not conditionally define functions in order to have a bit more control over the process.
parent 45aff1f7
...@@ -62,11 +62,11 @@ Python profiler documentation</a>. ...@@ -62,11 +62,11 @@ Python profiler documentation</a>.
<dtml-else> <dtml-else>
<br /> <br />
<div class="form-text"> <div class="form-text">
Profiling is not currently enabled or there is not yet any profiling Profiling is not currently enabled or there is not yet any profiling
data to report. To enable profiling, restart the Zope process with data to report. To enable profiling, restart the Zope process with
the environment variable PROFILE_PUBLISHER defined. The value of this the configuration setting 'publisher-profile-file' defined. The value
variable should be the full system path to a file that will be used of this variable should be the full system path to a file that will be
to dump a profile report when the process restarts or exits. used to dump a profile report when the process restarts or exits.
</div> </div>
</dtml-if> </dtml-if>
</dtml-let> </dtml-let>
......
...@@ -12,8 +12,8 @@ ...@@ -12,8 +12,8 @@
############################################################################## ##############################################################################
__doc__="""Python Object Publisher -- Publish Python objects on web servers __doc__="""Python Object Publisher -- Publish Python objects on web servers
$Id: Publish.py,v 1.164 2003/04/18 13:51:21 andreasjung Exp $""" $Id: Publish.py,v 1.165 2003/10/21 14:10:16 chrism Exp $"""
__version__='$Revision: 1.164 $'[11:-2] __version__='$Revision: 1.165 $'[11:-2]
import sys, os import sys, os
from Response import Response from Response import Response
...@@ -142,7 +142,7 @@ def publish(request, module_name, after_list, debug=0, ...@@ -142,7 +142,7 @@ def publish(request, module_name, after_list, debug=0,
else: raise else: raise
def publish_module(module_name, def publish_module_standard(module_name,
stdin=sys.stdin, stdout=sys.stdout, stderr=sys.stderr, stdin=sys.stdin, stdout=sys.stdout, stderr=sys.stderr,
environ=os.environ, debug=0, request=None, response=None): environ=os.environ, debug=0, request=None, response=None):
must_die=0 must_die=0
...@@ -295,66 +295,77 @@ class DefaultTransactionsManager: ...@@ -295,66 +295,77 @@ class DefaultTransactionsManager:
if auth_user is not None: if auth_user is not None:
T.setUser(auth_user, request_get('AUTHENTICATION_PATH')) T.setUser(auth_user, request_get('AUTHENTICATION_PATH'))
# profiling support
# ZPublisher profiler support _pfile = None # profiling filename
# --------------------------- _plock=allocate_lock() # profiling lock
_pfunc=publish_module_standard
if os.environ.get('PROFILE_PUBLISHER', None): _pstat=None
def install_profiling(filename):
global _pfile
_pfile = filename
def pm(module_name, stdin, stdout, stderr,
environ, debug, request, response):
try:
r=_pfunc(module_name, stdin=stdin, stdout=stdout,
stderr=stderr, environ=environ, debug=debug,
request=request, response=response)
except: r=None
sys._pr_=r
def publish_module_profiled(module_name, stdin=sys.stdin, stdout=sys.stdout,
stderr=sys.stderr, environ=os.environ, debug=0,
request=None, response=None):
import profile, pstats import profile, pstats
global _pstat
_plock.acquire()
try:
if request is not None:
path_info=request.get('PATH_INFO')
else: path_info=environ.get('PATH_INFO')
if path_info[-14:]=='manage_profile':
return _pfunc(module_name, stdin=stdin, stdout=stdout,
stderr=stderr, environ=environ, debug=debug,
request=request, response=response)
pobj=profile.Profile()
pobj.runcall(pm, module_name, stdin, stdout, stderr,
environ, debug, request, response)
result=sys._pr_
pobj.create_stats()
if _pstat is None:
_pstat=sys._ps_=pstats.Stats(pobj)
else: _pstat.add(pobj)
finally:
_plock.release()
_pfile=os.environ['PROFILE_PUBLISHER'] if result is None:
_plock=allocate_lock()
_pfunc=publish_module
_pstat=None
def pm(module_name, stdin, stdout, stderr,
environ, debug, request, response):
try:
r=_pfunc(module_name, stdin=stdin, stdout=stdout,
stderr=stderr, environ=environ, debug=debug,
request=request, response=response)
except: r=None
sys._pr_=r
def publish_module(module_name, stdin=sys.stdin, stdout=sys.stdout,
stderr=sys.stderr, environ=os.environ, debug=0,
request=None, response=None):
global _pstat
_plock.acquire()
try: try:
if request is not None: error=sys.exc_info()
path_info=request.get('PATH_INFO') file=open(_pfile, 'w')
else: path_info=environ.get('PATH_INFO') file.write(
if path_info[-14:]=='manage_profile': "See the url "
return _pfunc(module_name, stdin=stdin, stdout=stdout, "http://www.python.org/doc/current/lib/module-profile.html"
stderr=stderr, environ=environ, debug=debug, "\n for information on interpreting profiler statistics.\n\n"
request=request, response=response) )
pobj=profile.Profile() sys.stdout=file
pobj.runcall(pm, module_name, stdin, stdout, stderr, _pstat.strip_dirs().sort_stats('cumulative').print_stats(250)
environ, debug, request, response) _pstat.strip_dirs().sort_stats('time').print_stats(250)
result=sys._pr_ file.flush()
pobj.create_stats() file.close()
if _pstat is None: except: pass
_pstat=sys._ps_=pstats.Stats(pobj) raise error[0], error[1], error[2]
else: _pstat.add(pobj) return result
finally:
_plock.release() def publish_module(module_name,
stdin=sys.stdin, stdout=sys.stdout, stderr=sys.stderr,
if result is None: environ=os.environ, debug=0, request=None, response=None):
try: """ publish a Python module, with or without profiling enabled """
error=sys.exc_info() if _pfile: # profiling is enabled
file=open(_pfile, 'w') return publish_module_profiled(module_name, stdin, stdout, stderr,
file.write( environ, debug, request, response)
"See the url " else:
"http://www.python.org/doc/current/lib/module-profile.html" return publish_module_standard(module_name, stdin, stdout, stderr,
"\n for information on interpreting profiler statistics.\n\n" environ, debug, request, response)
)
sys.stdout=file
_pstat.strip_dirs().sort_stats('cumulative').print_stats(250)
_pstat.strip_dirs().sort_stats('time').print_stats(250)
file.flush()
file.close()
except: pass
raise error[0], error[1], error[2]
return result
...@@ -10,10 +10,10 @@ ...@@ -10,10 +10,10 @@
# FOR A PARTICULAR PURPOSE # FOR A PARTICULAR PURPOSE
# #
############################################################################## ##############################################################################
from ZPublisher import publish_module
class ZServerPublisher: class ZServerPublisher:
def __init__(self, accept): def __init__(self, accept):
from ZPublisher import publish_module
while 1: while 1:
try: try:
name, request, response=accept() name, request, response=accept()
......
...@@ -103,6 +103,8 @@ def maximum_security_manager_stack_size(value): ...@@ -103,6 +103,8 @@ def maximum_security_manager_stack_size(value):
def publisher_profile_file(value): def publisher_profile_file(value):
value is not None and _setenv('PROFILE_PUBLISHER', value) value is not None and _setenv('PROFILE_PUBLISHER', value)
from ZPublisher.Publish import install_profiling
install_profiling(value)
return value return value
def http_realm(value): def http_realm(value):
......
...@@ -428,6 +428,21 @@ instancehome $INSTANCE ...@@ -428,6 +428,21 @@ instancehome $INSTANCE
# #
# maximum-security-manager-stack-size 200 # maximum-security-manager-stack-size 200
# Directive: publisher-profile-file
#
# Description:
# Names a file on the filesystem which causes Zope's Python
# profiling capabilities to be enabled. For more information, see
# the Debug Information - > Profiling tab of Zope's Control_Panel
# via the Zope Management Interface. IMPORTANT: setting this
# filename will cause Zope code to be executed much more slowly
# than normal. This should not be enabled in production. #
# Default: unset
#
# Example:
#
# publisher-profile-file $INSTANCE/var/profile.dat
# Directive: security-policy-implementation # Directive: security-policy-implementation
# #
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment