diff options
author | Zhi Yan Liu <zhiyanl@cn.ibm.com> | 2014-08-25 23:19:41 +0800 |
---|---|---|
committer | Zhi Yan Liu <lzy.dev@gmail.com> | 2014-12-10 03:41:18 +0800 |
commit | 1cd92286473d5737cfa19ac4c850519e4ec64c72 (patch) | |
tree | efb2cd03ac926fae7f2da7db558ce802b64bc331 /troveclient | |
parent | 4d8e1567ec35ebda8071862bbc5c6818685a5205 (diff) | |
download | python-troveclient-1cd92286473d5737cfa19ac4c850519e4ec64c72.tar.gz |
Add profiling support to Trove client
To be able to create profiling traces for Trove, client should be
able to send special HTTP header that contains trace info.
This patch is as well important to be able to make cross project
traces. (Typical case horizon calls Trove via python client, if
profiler is initialized, Trove client will add extra header, that
will be parsed by special osprofiler middleware in Trove api)
Don't worry no security issue here, trace information is signed
by HMAC key that is setted in api-paste.ini. So only person that
knows HMAC key is able to send proper header.
Main patch in Trove is: I580cce8d2b3c4ec9ce625ac09de6f14e1249f6f5
We prepared a common BP in oslo-spec due to integration change is
similar to all projects: I95dccdc9f274661767d2659c18b96da169891f30
Currently there are 2 other projects are using osprofiler: Glance &
Cinder, and some others are working in progress.
Change-Id: I5a76e11d428c63d33f6d2c2021426090ebf8340c
Signed-off-by: Zhi Yan Liu <zhiyanl@cn.ibm.com>
Diffstat (limited to 'troveclient')
-rw-r--r-- | troveclient/client.py | 5 | ||||
-rw-r--r-- | troveclient/shell.py | 31 |
2 files changed, 35 insertions, 1 deletions
diff --git a/troveclient/client.py b/troveclient/client.py index d9dcc48..0acf246 100644 --- a/troveclient/client.py +++ b/troveclient/client.py @@ -28,6 +28,7 @@ import requests from keystoneclient import adapter from troveclient.openstack.common.apiclient import client from troveclient.openstack.common.apiclient import exceptions +from troveclient.openstack.common import importutils from troveclient import service_catalog try: @@ -50,6 +51,8 @@ if not hasattr(urlparse, 'parse_qsl'): import cgi urlparse.parse_qsl = cgi.parse_qsl +osprofiler_web = importutils.try_import("osprofiler.web") + class TroveClientMixin(object): @@ -157,6 +160,8 @@ class HTTPClient(TroveClientMixin): kwargs.setdefault('headers', kwargs.get('headers', {})) kwargs['headers']['User-Agent'] = self.USER_AGENT kwargs['headers']['Accept'] = 'application/json' + if osprofiler_web: + kwargs['headers'].update(osprofiler_web.get_trace_id_headers()) if 'body' in kwargs: kwargs['headers']['Content-Type'] = 'application/json' kwargs['data'] = json.dumps(kwargs['body']) diff --git a/troveclient/shell.py b/troveclient/shell.py index 3738d30..c1ad793 100644 --- a/troveclient/shell.py +++ b/troveclient/shell.py @@ -44,6 +44,7 @@ from troveclient import client from troveclient.openstack.common.apiclient import exceptions as exc from troveclient.openstack.common import gettextutils as gtu from troveclient.openstack.common.gettextutils import _ # noqa +from troveclient.openstack.common import importutils from troveclient.openstack.common import strutils from troveclient import utils from troveclient.v1 import shell as shell_v1 @@ -54,6 +55,7 @@ DEFAULT_TROVE_ENDPOINT_TYPE = 'publicURL' DEFAULT_TROVE_SERVICE_TYPE = 'database' logger = logging.getLogger(__name__) +osprofiler_profiler = importutils.try_import("osprofiler.profiler") class TroveClientArgumentParser(argparse.ArgumentParser): @@ -173,6 +175,22 @@ class OpenStackTroveShell(object): help='Output JSON instead of prettyprint. ' 'Defaults to env[OS_JSON_OUTPUT].') + if osprofiler_profiler: + parser.add_argument('--profile', + metavar='HMAC_KEY', + default=utils.env('OS_PROFILE_HMACKEY', + default=None), + help='HMAC key to use for encrypting context ' + 'data for performance profiling of operation. ' + 'This key should be the value of HMAC key ' + 'configured in osprofiler middleware in ' + 'Trove, it is specified in paste ' + 'configure file at /etc/trove/api-paste.ini. ' + 'Without key the profiling will not be ' + 'triggered even if osprofiler is enabled ' + 'on server side. ' + 'Defaults to env[OS_PROFILE_HMACKEY].') + self._append_global_identity_args(parser) return parser @@ -452,6 +470,10 @@ class OpenStackTroveShell(object): project_domain_id=args.os_project_domain_id, project_domain_name=args.os_project_domain_name) + profile = osprofiler_profiler and options.profile + if profile: + osprofiler_profiler.init(options.profile) + self.cs = client.Client(options.os_database_api_version, os_username, os_password, os_tenant_name, os_auth_url, insecure, region_name=os_region_name, @@ -498,7 +520,14 @@ class OpenStackTroveShell(object): else: utils.json_output = False - args.func(self.cs, args) + try: + args.func(self.cs, args) + finally: + if profile: + trace_id = osprofiler_profiler.get().get_base_id() + print("Trace ID: %s" % trace_id) + print("To display trace use next command:\n" + "osprofiler trace show --html %s" % trace_id) def _run_extension_hooks(self, hook_type, *args, **kwargs): """Run hooks for all registered extensions.""" |