Optionally run a wsgi profiler when asked
This is the code used to run placement with the wsgi profiling described in a blog post [1]. It has proven useful enough that we may wish to include it in the released code. It is added in a way that is off by default and makes no changes to requirements. Brief docs are included in testing.rst. They are brief because it's assumed that someone who wants to do this already mostly knows what they want to do and merely needs the specifics on how to do it in this environment. [1] https://anticdent.org/profiling-wsgi-apps.html Change-Id: I342512732b94bc19bd711684ba3ec9480cc51f81
This commit is contained in:
parent
7db53444fb
commit
88c6ad9cb4
@ -115,11 +115,36 @@ example in devstack. See `gabbi-run`_ to get started. If you don't want to
|
||||
go to the trouble of using devstack, but do want a live server see
|
||||
:doc:`quick-dev`.
|
||||
|
||||
Profiling
|
||||
---------
|
||||
|
||||
If you wish to profile requests to the placement service, to get an idea of
|
||||
which methods are consuming the most CPU or are being used repeatedly, it is
|
||||
possible to enable a ProfilerMiddleware_ to output per-request python profiling
|
||||
dumps. The environment (:doc:`quick-dev` is a good place to start) in which
|
||||
the service is running will need to have Werkzeug_ added.
|
||||
|
||||
* If the service is already running, stop it.
|
||||
* Install Werkzeug.
|
||||
* Set an environment variable, ``OS_WSGI_PROFILER``, to a directory where
|
||||
profile results will be written.
|
||||
* Make sure the directory exists.
|
||||
* Start the service, ensuring the environment variable is passed to it.
|
||||
* Make an HTTP request that exercises the code you wish to profile.
|
||||
|
||||
The profiling results will be in the directory named by ``OS_WSGI_PROFILER``.
|
||||
There are many ways to analyze the files. See `Profiling WSGI Apps`_ for an
|
||||
example.
|
||||
|
||||
|
||||
.. _bug: https://github.com/cdent/gabbi/issues
|
||||
.. _fixtures: http://gabbi.readthedocs.io/en/latest/fixtures.html
|
||||
.. _gabbi: https://gabbi.readthedocs.io/
|
||||
.. _gabbi-run: http://gabbi.readthedocs.io/en/latest/runner.html
|
||||
.. _JSONPath: http://goessner.net/articles/JsonPath/
|
||||
.. _ProfilerMiddleware: https://werkzeug.palletsprojects.com/en/master/middleware/profiler/
|
||||
.. _Profiling WSGI Apps: https://anticdent.org/profiling-wsgi-apps.html
|
||||
.. _syntax: https://gabbi.readthedocs.io/en/latest/format.html
|
||||
.. _telemetry: http://specs.openstack.org/openstack/telemetry-specs/specs/kilo/declarative-http-tests.html
|
||||
.. _Werkzeug: https://palletsprojects.com/p/werkzeug/
|
||||
.. _wsgi-intercept: http://wsgi-intercept.readthedocs.io/
|
||||
|
@ -11,6 +11,8 @@
|
||||
# under the License.
|
||||
"""Deployment handling for Placmenent API."""
|
||||
|
||||
import os
|
||||
|
||||
from microversion_parse import middleware as mp_middleware
|
||||
import oslo_middleware
|
||||
from oslo_middleware import cors
|
||||
@ -29,6 +31,14 @@ from placement import resource_class_cache as rc_cache
|
||||
from placement import util
|
||||
|
||||
|
||||
PROFILER_OUTPUT = os.environ.get('OS_WSGI_PROFILER')
|
||||
if PROFILER_OUTPUT:
|
||||
# If werkzeug is not available this raises ImportError and the
|
||||
# process will not continue. This is intentional: we do not want
|
||||
# to make a permanent dependency on werkzeug.
|
||||
from werkzeug.contrib import profiler
|
||||
|
||||
|
||||
def deploy(conf):
|
||||
"""Assemble the middleware pipeline leading to the placement app."""
|
||||
if conf.api.auth_strategy == 'noauth2':
|
||||
@ -57,6 +67,13 @@ def deploy(conf):
|
||||
request_log = requestlog.RequestLog
|
||||
|
||||
application = handler.PlacementHandler(config=conf)
|
||||
|
||||
# If PROFILER_OUTPUT is set, generate per request profile reports
|
||||
# to the directory named therein.
|
||||
if PROFILER_OUTPUT:
|
||||
application = profiler.ProfilerMiddleware(
|
||||
application, profile_dir=PROFILER_OUTPUT)
|
||||
|
||||
# configure microversion middleware in the old school way
|
||||
application = microversion_middleware(
|
||||
application, microversion.SERVICE_TYPE, microversion.VERSIONS,
|
||||
|
Loading…
Reference in New Issue
Block a user