summaryrefslogtreecommitdiff
path: root/troveclient
diff options
context:
space:
mode:
authorZhi Yan Liu <zhiyanl@cn.ibm.com>2014-08-25 23:19:41 +0800
committerZhi Yan Liu <lzy.dev@gmail.com>2014-12-10 03:41:18 +0800
commit1cd92286473d5737cfa19ac4c850519e4ec64c72 (patch)
treeefb2cd03ac926fae7f2da7db558ce802b64bc331 /troveclient
parent4d8e1567ec35ebda8071862bbc5c6818685a5205 (diff)
downloadpython-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.py5
-rw-r--r--troveclient/shell.py31
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."""