Add support for osprofiler in wsgi

To use osprofiler with placement:

* Add a [profiler] section to the placement.conf (and other openstack
  service conf files):

  [profiler]
  connection_string = mysql+pymysql://root:admin@127.0.0.1/osprofiler?charset=utf8
  hmac_keys = my-secret-key
  trace_sqlalchemy = True
  enabled = True

* Include the hmac_keys in your API request

  $ openstack server create --flavor c1 --image cirros-0.4.0-x86_64-disk \
    --os-profile my-secret-key vm --wait

  The openstack client will return the trace id:

  Trace ID: 67428cdd-bfaa-496f-b430-507165729246
  $

* Extrace the trace in html format

  $ osprofiler trace show --html 67428cdd-bfaa-496f-b430-507165729246 \
    --connection-string mysql+pymysql://root:admin@127.0.0.1/osprofiler?charset=utf8

Here is an example trace output for the above server create request
including the placement interactions enabled by this patch:
https://pste.eu/p/ZFsb.html

Story: 2005842
Task: 33616

Change-Id: I5a0e805fe04c00c5e7cf316f0ea8d432b940e560
This commit is contained in:
Balazs Gibizer 2019-06-07 15:36:16 +02:00 committed by Matt Riedemann
parent b04a15cac7
commit 40c97d7346
3 changed files with 33 additions and 0 deletions

View File

@ -15,6 +15,7 @@ import os
from microversion_parse import middleware as mp_middleware
import oslo_middleware
from oslo_utils import importutils
from placement import auth
from placement.db.sqlalchemy import migration
@ -30,6 +31,10 @@ from placement import resource_class_cache as rc_cache
from placement import util
os_profiler = importutils.try_import('osprofiler.profiler')
os_profiler_web = importutils.try_import('osprofiler.web')
PROFILER_OUTPUT = os.environ.get('OS_WSGI_PROFILER')
if PROFILER_OUTPUT:
# If werkzeug is not available this raises ImportError and the
@ -63,6 +68,12 @@ def deploy(conf):
fault_middleware = fault_wrap.FaultWrapper
request_log = requestlog.RequestLog
if os_profiler_web and 'profiler' in conf and conf.profiler.enabled:
osprofiler_middleware = os_profiler_web.WsgiMiddleware.factory(
{}, **conf.profiler)
else:
osprofiler_middleware = None
application = handler.PlacementHandler(config=conf)
# If PROFILER_OUTPUT is set, generate per request profile reports
@ -90,6 +101,7 @@ def deploy(conf):
auth_middleware,
cors_middleware,
req_id_middleware,
osprofiler_middleware,
):
if middleware:
application = middleware(application)

View File

@ -30,6 +30,8 @@ from placement import db_api
from placement import deploy
osprofiler = importutils.try_import('osprofiler')
osprofiler_initializer = importutils.try_import('osprofiler.initializer')
profiler = importutils.try_import('osprofiler.opts')
@ -86,6 +88,16 @@ def _parse_args(config, argv, default_config_files):
default_config_files=default_config_files)
def setup_profiler(config):
if osprofiler and config.profiler.enabled:
osprofiler.initializer.init_from_conf(
conf=config,
context={},
project="placement",
service="placement",
host="??")
def _set_middleware_defaults():
"""Update default configuration options for oslo.middleware."""
cors.set_defaults(
@ -134,5 +146,7 @@ def init_application():
logging.getLogger(__name__),
logging.DEBUG)
setup_profiler(config)
# build and return our WSGI app
return deploy.loadapp(config)

View File

@ -0,0 +1,7 @@
---
fixes:
- |
By fixing bug `story/2005842`_ the OSProfiler support works again in the
placement WSGI.
.. _story/2005842: https://storyboard.openstack.org/#!/story/2005842