Files
designate/designate/common/profiler.py
T
kpdev 9541a29761 Integrate OSprofiler and Designate
*) Add osprofiler wsgi middleware

This middleware is used for 2 things:
1) It checks that person who want to trace is trusted and knows
secret HMAC key.
2) It start tracing in case of proper trace headers and add
first wsgi trace point, with info about HTTP request
*) Add initialization of osprofiler at start of serivce.

You should use python-designateclient with this patch:

https://review.opendev.org/#/c/773575

Run any command with --os-profile SECRET_KEY

  $ openstack zone create --email <email_id> <zone_name> \
    --os-profile SECRET_KEY
  # it will print <Trace ID>

Get pretty HTML with traces:

  $ osprofiler trace show --html <Trace ID> --connection-string \
   <connection_string> --out <output.html>
  e.g. --connection-string can be redis://localhost:6379

Note that osprofiler should be run from admin user name & tenant.

Implements: blueprint designate-os-profiler
Change-Id: I2a3787b6428d679555a9add3a57ffe8c2112b6d3
2022-02-07 07:12:18 +00:00

89 lines
2.7 KiB
Python

#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
from oslo_log import log as logging
from oslo_utils import importutils
import designate.conf
from designate.context import DesignateContext
import webob.dec
profiler = importutils.try_import("osprofiler.profiler")
profiler_initializer = importutils.try_import("osprofiler.initializer")
profiler_opts = importutils.try_import('osprofiler.opts')
profiler_web = importutils.try_import("osprofiler.web")
CONF = designate.conf.CONF
LOG = logging.getLogger(__name__)
if profiler_opts:
profiler_opts.set_defaults(CONF)
class WsgiMiddleware(object):
def __init__(self, application, **kwargs):
self.application = application
@classmethod
def factory(cls, global_conf, **local_conf):
if profiler_web:
return profiler_web.WsgiMiddleware.factory(global_conf,
**local_conf)
def filter_(app):
return cls(app, **local_conf)
return filter_
@webob.dec.wsgify
def __call__(self, request):
return request.get_response(self.application)
def setup_profiler(binary, host):
if hasattr(CONF, 'profiler') and not CONF.profiler.enabled:
return
if (profiler_initializer is None or profiler is None or
profiler_opts is None):
LOG.debug('osprofiler is not present')
return
profiler_initializer.init_from_conf(
conf=CONF,
context=DesignateContext.get_admin_context().to_dict(),
project="designate",
service=binary,
host=host)
LOG.info("osprofiler is enabled")
def trace_cls(name, **kwargs):
"""Wrap the OSprofiler trace_cls.
Wrap the OSprofiler trace_cls decorator so that it will not try to
patch the class unless OSprofiler is present.
:param name: The name of action. For example, wsgi, rpc, db, ...
:param kwargs: Any other keyword args used by profiler.trace_cls
"""
def decorator(cls):
if profiler and hasattr(CONF, 'profiler') and CONF.profiler.enabled:
trace_decorator = profiler.trace_cls(name, kwargs)
return trace_decorator(cls)
return cls
return decorator