From 1c2385ca55d8af0645ef52e10257a013397c9690 Mon Sep 17 00:00:00 2001 From: Tovin Seven Date: Wed, 18 Jan 2017 16:03:39 +0700 Subject: [PATCH] Integrate OSprofiler in Magnum Client Add OSprofiler support in Magnum Client Co-Authored-By: Hieu LE Change-Id: I85f766f636f754fc6ad8e28e3df2793cd02a618e Depends-On: I7d68995aab81d365433950aada078ef1fcd5469b Implements: blueprint osprofiler-support-in-magnum --- magnumclient/common/httpclient.py | 6 ++++++ magnumclient/shell.py | 26 ++++++++++++++++++++++++++ magnumclient/tests/test_shell.py | 2 +- magnumclient/v1/client.py | 13 +++++++++++++ test-requirements.txt | 1 + 5 files changed, 47 insertions(+), 1 deletion(-) diff --git a/magnumclient/common/httpclient.py b/magnumclient/common/httpclient.py index 61ddb7af..31b65942 100644 --- a/magnumclient/common/httpclient.py +++ b/magnumclient/common/httpclient.py @@ -23,11 +23,13 @@ import socket import ssl from keystoneauth1 import adapter +from oslo_utils import importutils import six import six.moves.urllib.parse as urlparse from magnumclient import exceptions +osprofiler_web = importutils.try_import("osprofiler.web") LOG = logging.getLogger(__name__) USER_AGENT = 'python-magnumclient' @@ -330,6 +332,10 @@ class SessionClient(adapter.LegacyJsonAdapter): # Copy the kwargs so we can reuse the original in case of redirects kwargs['headers'] = copy.deepcopy(kwargs.get('headers', {})) kwargs['headers'].setdefault('User-Agent', self.user_agent) + # NOTE(tovin07): osprofiler_web.get_trace_id_headers does not add any + # headers in case if osprofiler is not initialized. + if osprofiler_web: + kwargs['headers'].update(osprofiler_web.get_trace_id_headers()) if self.api_version: version_string = 'container-infra %s' % self.api_version kwargs['headers'].setdefault( diff --git a/magnumclient/shell.py b/magnumclient/shell.py index c7a86665..b54a0e9d 100644 --- a/magnumclient/shell.py +++ b/magnumclient/shell.py @@ -30,9 +30,12 @@ import os import sys from oslo_utils import encodeutils +from oslo_utils import importutils from oslo_utils import strutils import six +profiler = importutils.try_import("osprofiler.profiler") + HAS_KEYRING = False all_errors = ValueError try: @@ -422,6 +425,19 @@ class OpenStackMagnumShell(object): action='store_true', help=_("Do not verify https connections")) + if profiler: + parser.add_argument('--profile', + metavar='HMAC_KEY', + help='HMAC key to use for encrypting context ' + 'data for performance profiling of operation. ' + 'This key should be the value of the HMAC key ' + 'configured for the OSprofiler middleware in ' + 'nova; it is specified in the Nova ' + 'configuration file at "/etc/nova/nova.conf". ' + 'Without the key, profiling will not be ' + 'triggered even if OSprofiler is enabled on ' + 'the server side.') + return parser def get_subcommand_parser(self, version): @@ -619,6 +635,10 @@ class OpenStackMagnumShell(object): if args.os_interface.endswith('URL'): args.os_interface = args.os_interface[:-3] + kwargs = {} + if profiler: + kwargs["profile"] = args.profile + self.cs = client.Client( cloud=args.os_cloud, user_id=args.os_user_id, @@ -638,11 +658,17 @@ class OpenStackMagnumShell(object): interface=args.os_interface, insecure=args.insecure, api_version=args.magnum_api_version, + **kwargs ) self._check_deprecation(args.func, argv) args.func(self.cs, args) + if profiler and args.profile: + trace_id = profiler.get().get_base_id() + print("To display trace use the command:\n\n" + " osprofiler trace show --html %s " % trace_id) + def _check_deprecation(self, func, argv): if not hasattr(func, 'deprecated_groups'): return diff --git a/magnumclient/tests/test_shell.py b/magnumclient/tests/test_shell.py index b61f211d..4da132e7 100644 --- a/magnumclient/tests/test_shell.py +++ b/magnumclient/tests/test_shell.py @@ -215,7 +215,7 @@ class ShellTest(utils.TestCase): def _expected_client_kwargs(self): return { 'password': 'password', 'auth_token': None, - 'auth_url': self.AUTH_URL, + 'auth_url': self.AUTH_URL, 'profile': None, 'cloud': None, 'interface': 'public', 'insecure': False, 'magnum_url': None, 'project_id': None, 'project_name': 'project_name', diff --git a/magnumclient/v1/client.py b/magnumclient/v1/client.py index a00be5f8..60288e1d 100644 --- a/magnumclient/v1/client.py +++ b/magnumclient/v1/client.py @@ -16,6 +16,7 @@ from keystoneauth1.exceptions import catalog from keystoneauth1 import session as ksa_session import os_client_config +from oslo_utils import importutils from magnumclient.common import httpclient from magnumclient.v1 import baymodels @@ -25,6 +26,8 @@ from magnumclient.v1 import cluster_templates from magnumclient.v1 import clusters from magnumclient.v1 import mservices +profiler = importutils.try_import("osprofiler.profiler") + DEFAULT_SERVICE_TYPE = 'container-infra' LEGACY_DEFAULT_SERVICE_TYPE = 'container' @@ -198,3 +201,13 @@ class Client(object): self.cluster_templates = \ cluster_templates.ClusterTemplateManager(self.http_client) self.mservices = mservices.MServiceManager(self.http_client) + + profile = kwargs.pop("profile", None) + if profiler and profile: + # Initialize the root of the future trace: the created trace ID + # will be used as the very first parent to which all related + # traces will be bound to. The given HMAC key must correspond to + # the one set in magnum-api magnum.conf, otherwise the latter + # will fail to check the request signature and will skip + # initialization of osprofiler on the server side. + profiler.init(profile) diff --git a/test-requirements.txt b/test-requirements.txt index 24a5a729..baa5025d 100644 --- a/test-requirements.txt +++ b/test-requirements.txt @@ -10,6 +10,7 @@ python-subunit>=0.0.18 # Apache-2.0/BSD sphinx!=1.3b1,<1.4,>=1.2.1 # BSD oslosphinx>=4.7.0 # Apache-2.0 oslotest>=1.10.0 # Apache-2.0 +osprofiler>=1.4.0 # Apache-2.0 testrepository>=0.0.18 # Apache-2.0/BSD testscenarios>=0.4 # Apache-2.0/BSD testtools>=1.4.0 # MIT