a662f053c4
* Add osprofiler wsgi middleware. This middleware is used for 2 things: 1) It checks that person who wants to trace is trusted and knows secret HMAC key. 2) It starts tracing in case of proper trace headers and adds first wsgi trace point, with info about HTTP request * Traces HTTP API calls * Traces DB (SQLAlchemy) calls Demo: https://tovin07.github.io/aodh/alarm_delete.html HOW TO TEST? 1. Install devstack with aodh as usual 2. Install osprofiler pip install osprofiler 3. Add these line to /etc/aodh/aodh.conf [profiler] enabled = true hmac_keys = SECRET_KEY connection_string = redis://localhost:6379 # example when using redis 4. Pass HMAC_KEYS to client commands - aodh client with `--profile <HMAC_KEYS>` - openstack client with `--os-profiler <HMAC_KEYS>` Output will look like this: To display trace use the command: osprofiler trace show --html <TRACE_ID> 5. Use osprofiler to get the trace osprofiler trace show \ --connection-string redis://localhost:6379 \ --out out.html \ --html <TRACE_ID> 6. Open that html file with browser and view the result Change-Id: I44bf27413af2133451cbd84d908631ce6a2fe1f7
77 lines
2.2 KiB
Python
77 lines
2.2 KiB
Python
# Copyright 2017 Fujitsu Ltd.
|
|
# All Rights Reserved.
|
|
#
|
|
# 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.
|
|
|
|
import socket
|
|
|
|
from oslo_log import log
|
|
from oslo_utils import importutils
|
|
import webob.dec
|
|
|
|
profiler = importutils.try_import('osprofiler.profiler')
|
|
profiler_initializer = importutils.try_import('osprofiler.initializer')
|
|
profiler_web = importutils.try_import('osprofiler.web')
|
|
|
|
LOG = log.getLogger(__name__)
|
|
|
|
|
|
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)
|
|
|
|
def filter_(app):
|
|
return cls(app)
|
|
|
|
return filter_
|
|
|
|
@webob.dec.wsgify
|
|
def __call__(self, request):
|
|
return request.get_response(self.application)
|
|
|
|
|
|
def setup(conf):
|
|
if hasattr(conf, 'profiler') and conf.profiler.enabled:
|
|
profiler_initializer.init_from_conf(
|
|
conf=conf,
|
|
context={},
|
|
project=conf.project,
|
|
service=conf.prog,
|
|
host=socket.gethostbyname(socket.gethostname()))
|
|
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:
|
|
trace_decorator = profiler.trace_cls(name, **kwargs)
|
|
return trace_decorator(cls)
|
|
return cls
|
|
|
|
return decorator
|