diff --git a/doc/source/man/openstack.rst b/doc/source/man/openstack.rst index a33b1891b4..f02705d817 100644 --- a/doc/source/man/openstack.rst +++ b/doc/source/man/openstack.rst @@ -123,6 +123,12 @@ OPTIONS :option:`--os-interface` Interface type. Valid options are `public`, `admin` and `internal`. +:option: `--profile` + HMAC key to use for encrypting context data for performance profiling of + requested operation. This key should be the value of one of the HMAC keys + defined in the configuration files of OpenStack services, user would like + to trace through. + :option:`--log-file` Specify a file to log output. Disabled by default. diff --git a/openstackclient/shell.py b/openstackclient/shell.py index c84e2b1d40..bd13fbb596 100644 --- a/openstackclient/shell.py +++ b/openstackclient/shell.py @@ -25,6 +25,7 @@ from cliff import app from cliff import command from cliff import complete from cliff import help +from oslo_utils import importutils from oslo_utils import strutils import openstackclient @@ -37,6 +38,8 @@ from openstackclient.common import utils from os_client_config import config as cloud_config +osprofiler_profiler = importutils.try_import("osprofiler.profiler") + DEFAULT_DOMAIN = 'default' @@ -101,6 +104,8 @@ class OpenStackShell(app.App): self.client_manager = None self.command_options = None + self.do_profile = False + def configure_logging(self): """Configure logging for the app.""" self.log_configurator = logs.LogConfigurator(self.options) @@ -125,6 +130,39 @@ class OpenStackShell(app.App): finally: self.log.info("END return value: %s", ret_val) + def init_profile(self): + self.do_profile = osprofiler_profiler and self.options.profile + if self.do_profile: + osprofiler_profiler.init(self.options.profile) + + def close_profile(self): + if self.do_profile: + trace_id = osprofiler_profiler.get().get_base_id() + + # NOTE(dbelova): let's use warning log level to see these messages + # printed. In fact we can define custom log level here with value + # bigger than most big default one (CRITICAL) or something like + # that (PROFILE = 60 for instance), but not sure we need it here. + self.log.warning("Trace ID: %s" % trace_id) + self.log.warning("To display trace use next command:\n" + "osprofiler trace show --html %s " % trace_id) + + def run_subcommand(self, argv): + self.init_profile() + try: + ret_value = super(OpenStackShell, self).run_subcommand(argv) + finally: + self.close_profile() + return ret_value + + def interact(self): + self.init_profile() + try: + ret_value = super(OpenStackShell, self).run_subcommand() + finally: + self.close_profile() + return ret_value + def build_option_parser(self, description, version): parser = super(OpenStackShell, self).build_option_parser( description, @@ -190,6 +228,19 @@ class OpenStackShell(app.App): help="Print API call timing info", ) + # osprofiler HMAC key argument + if osprofiler_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 one of the ' + 'HMAC keys configured in osprofiler ' + 'middleware in the projects user would like ' + 'to profile. It needs to be specified in ' + 'configuration files of the required ' + 'projects.') + return clientmanager.build_plugin_option_parser(parser) def initialize_app(self, argv): diff --git a/openstackclient/tests/test_shell.py b/openstackclient/tests/test_shell.py index c4546d89f2..101aadd17b 100644 --- a/openstackclient/tests/test_shell.py +++ b/openstackclient/tests/test_shell.py @@ -109,6 +109,7 @@ global_options = { '--os-default-domain': (DEFAULT_DOMAIN_NAME, True, True), '--os-cacert': ('/dev/null', True, True), '--timing': (True, True, False), + '--profile': ('SECRET_KEY', True, False), '--os-interface': (DEFAULT_INTERFACE, True, True) } diff --git a/releasenotes/notes/add-osprofiler-support-adf5286daf220914.yaml b/releasenotes/notes/add-osprofiler-support-adf5286daf220914.yaml new file mode 100644 index 0000000000..4176ded152 --- /dev/null +++ b/releasenotes/notes/add-osprofiler-support-adf5286daf220914.yaml @@ -0,0 +1,17 @@ +--- +features: + - | + OSprofiler support was added. To initiate OpenStack request tracing + ``--profile `` option needs to be added to the CLI command. This + key needs to present one of the secret keys defined in the OpenStack + projects configuration files (if there is a wish to generate cross-project + trace, the chosen key needs to be presented in all these configuration + files). By default all OpenStack projects, that support OSprofiler, + are using ``SECRET_KEY`` HMAC key. + + To use tracing functionality OSprofiler (and its storage backend) + needs to be installed in the environment. If so, you will be able to + trigger profiling via `openstack --profile SECRET_KEY ` command. + At the end of output there will be message with , and to plot + human-readable HTML chart the following command should be used - + ``osprofiler trace show --html --out result.html``. diff --git a/test-requirements.txt b/test-requirements.txt index 2255cd3b3b..51c660f508 100644 --- a/test-requirements.txt +++ b/test-requirements.txt @@ -17,6 +17,7 @@ testrepository>=0.0.18 # Apache-2.0/BSD testtools>=1.4.0 # MIT WebOb>=1.2.3 # MIT tempest-lib>=0.14.0 # Apache-2.0 +osprofiler>=1.1.0 # Apache-2.0 # Install these to generate sphinx autodocs python-barbicanclient>=3.3.0 # Apache-2.0