Use built-in feature for profilers
Most of the current implementations for profiler setup can be replaced by the ones provided by osprofiler. Change-Id: Ic9349fd7ae8cd73e64829476fc6f466b4fb24193 Signed-off-by: Takashi Kajinami <kajinamit@oss.nttdata.com>
This commit is contained in:
@@ -20,7 +20,6 @@ oslo.context>=4.0.0 # Apache-2.0
|
||||
oslo.db>=11.0.0 # Apache-2.0
|
||||
oslo.i18n>=3.15.3 # Apache-2.0
|
||||
oslo.log>=4.6.1 # Apache-2.0
|
||||
oslo.messaging>=12.5.0 # Apache-2.0
|
||||
oslo.middleware>=3.31.0 # Apache-2.0
|
||||
oslo.reports>=2.2.0 # Apache-2.0
|
||||
oslo.serialization>=4.2.0 # Apache-2.0
|
||||
|
||||
@@ -13,103 +13,18 @@
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
from urllib import parse as urlparse
|
||||
import webob
|
||||
|
||||
from oslo_log import log
|
||||
from osprofiler import _utils as utils
|
||||
from osprofiler import notifier
|
||||
from osprofiler import profiler
|
||||
from osprofiler import initializer
|
||||
from osprofiler import web
|
||||
|
||||
LOG = log.getLogger(__name__)
|
||||
|
||||
|
||||
def setup(conf, binary, host):
|
||||
if conf.profiler.enabled:
|
||||
|
||||
# Note(wangxiyuan): OSprofiler now support some kind of backends, such
|
||||
# as Ceilometer, ElasticSearch, Messaging and MongoDB.
|
||||
# 1. Ceilometer is only used for data collection, and Messaging is only
|
||||
# used for data transfer. So Ceilometer only works when Messaging is
|
||||
# enabled.
|
||||
# 2. ElasticSearch and MongoDB support both data collection and
|
||||
# transfer. So they can be used standalone.
|
||||
# 3. Choose which backend depends on the config option
|
||||
# "connection_string" , and the default value is "messaging://".
|
||||
backend_uri = conf.profiler.connection_string
|
||||
if "://" not in backend_uri:
|
||||
backend_uri += "://"
|
||||
parsed_connection = urlparse.urlparse(backend_uri)
|
||||
backend_type = parsed_connection.scheme
|
||||
if backend_type == "messaging":
|
||||
import oslo_messaging
|
||||
_notifier = notifier.create(
|
||||
backend_uri, oslo_messaging, {},
|
||||
oslo_messaging.get_notification_transport(conf),
|
||||
"Zaqar", binary, host)
|
||||
else:
|
||||
_notifier = notifier.create(backend_uri, project="Zaqar",
|
||||
service=binary, host=host)
|
||||
notifier.set(_notifier)
|
||||
LOG.warning("OSProfiler is enabled.\nIt means that person who "
|
||||
"knows any of hmac_keys that are specified in "
|
||||
"/etc/zaqar/zaqar.conf can trace his requests. \n In "
|
||||
"real life only operator can read this file so there "
|
||||
"is no security issue. Note that even if person can "
|
||||
"trigger profiler, only admin user can retrieve trace "
|
||||
"information.\n"
|
||||
"To disable OSprofiler set in zaqar.conf:\n"
|
||||
"[profiler]\nenabled=false")
|
||||
web.enable(conf.profiler.hmac_keys)
|
||||
else:
|
||||
web.disable()
|
||||
|
||||
|
||||
class ProfileWSGIMiddleware:
|
||||
|
||||
def __init__(self, application, hmac_keys=None, enabled=False):
|
||||
self.application = application
|
||||
self.name = "wsgi"
|
||||
self.enabled = enabled
|
||||
self.hmac_keys = utils.split(hmac_keys or "")
|
||||
|
||||
def _trace_is_valid(self, trace_info):
|
||||
if not isinstance(trace_info, dict):
|
||||
return False
|
||||
trace_keys = set(trace_info.keys())
|
||||
if not all(k in trace_keys for k in web._REQUIRED_KEYS):
|
||||
return False
|
||||
if trace_keys.difference(web._REQUIRED_KEYS + web._OPTIONAL_KEYS):
|
||||
return False
|
||||
return True
|
||||
|
||||
def __call__(self, environ, start_response):
|
||||
request = webob.Request(environ)
|
||||
trace_info = utils.signed_unpack(request.headers.get(web.X_TRACE_INFO),
|
||||
request.headers.get(web.X_TRACE_HMAC),
|
||||
self.hmac_keys)
|
||||
|
||||
if not self._trace_is_valid(trace_info):
|
||||
return self.application(environ, start_response)
|
||||
|
||||
profiler.init(**trace_info)
|
||||
info = {
|
||||
"request": {
|
||||
"path": request.path,
|
||||
"query": request.query_string,
|
||||
"method": request.method,
|
||||
"scheme": request.scheme
|
||||
}
|
||||
}
|
||||
with profiler.Trace(self.name, info=info):
|
||||
return self.application(environ, start_response)
|
||||
initializer.init_from_conf(context=None, project='Zaqar', service=binary,
|
||||
host=host, conf=conf)
|
||||
|
||||
|
||||
def install_wsgi_tracer(app, conf):
|
||||
enabled = conf.profiler.enabled and conf.profiler.trace_wsgi_transport
|
||||
|
||||
if enabled:
|
||||
LOG.debug('Installing osprofiler\'s wsgi tracer')
|
||||
|
||||
return ProfileWSGIMiddleware(app, conf.profiler.hmac_keys, enabled=enabled)
|
||||
return web.WsgiMiddleware(app, enabled=enabled)
|
||||
|
||||
@@ -133,10 +133,7 @@ class Driver(transport.DriverBase):
|
||||
def _init_middleware(self):
|
||||
"""Initialize WSGI middlewarez."""
|
||||
|
||||
# NOTE(zhiyan): Install Profiler
|
||||
if (self._conf.profiler.enabled and
|
||||
self._conf.profiler.trace_wsgi_transport):
|
||||
self.app = profile.install_wsgi_tracer(self.app, self._conf)
|
||||
self.app = profile.install_wsgi_tracer(self.app, self._conf)
|
||||
|
||||
auth_app = self.app
|
||||
# NOTE(flaper87): Install Auth
|
||||
|
||||
Reference in New Issue
Block a user