2525from cliff import command
2626from cliff import complete
2727from cliff import help
28+ from oslo_utils import importutils
2829from oslo_utils import strutils
2930
3031import openstackclient
3738
3839from os_client_config import config as cloud_config
3940
41+ osprofiler_profiler = importutils .try_import ("osprofiler.profiler" )
42+
4043
4144DEFAULT_DOMAIN = 'default'
4245
@@ -101,6 +104,8 @@ def __init__(self):
101104 self .client_manager = None
102105 self .command_options = None
103106
107+ self .do_profile = False
108+
104109 def configure_logging (self ):
105110 """Configure logging for the app."""
106111 self .log_configurator = logs .LogConfigurator (self .options )
@@ -125,6 +130,39 @@ def run(self, argv):
125130 finally :
126131 self .log .info ("END return value: %s" , ret_val )
127132
133+ def init_profile (self ):
134+ self .do_profile = osprofiler_profiler and self .options .profile
135+ if self .do_profile :
136+ osprofiler_profiler .init (self .options .profile )
137+
138+ def close_profile (self ):
139+ if self .do_profile :
140+ trace_id = osprofiler_profiler .get ().get_base_id ()
141+
142+ # NOTE(dbelova): let's use warning log level to see these messages
143+ # printed. In fact we can define custom log level here with value
144+ # bigger than most big default one (CRITICAL) or something like
145+ # that (PROFILE = 60 for instance), but not sure we need it here.
146+ self .log .warning ("Trace ID: %s" % trace_id )
147+ self .log .warning ("To display trace use next command:\n "
148+ "osprofiler trace show --html %s " % trace_id )
149+
150+ def run_subcommand (self , argv ):
151+ self .init_profile ()
152+ try :
153+ ret_value = super (OpenStackShell , self ).run_subcommand (argv )
154+ finally :
155+ self .close_profile ()
156+ return ret_value
157+
158+ def interact (self ):
159+ self .init_profile ()
160+ try :
161+ ret_value = super (OpenStackShell , self ).run_subcommand ()
162+ finally :
163+ self .close_profile ()
164+ return ret_value
165+
128166 def build_option_parser (self , description , version ):
129167 parser = super (OpenStackShell , self ).build_option_parser (
130168 description ,
@@ -190,6 +228,19 @@ def build_option_parser(self, description, version):
190228 help = "Print API call timing info" ,
191229 )
192230
231+ # osprofiler HMAC key argument
232+ if osprofiler_profiler :
233+ parser .add_argument ('--profile' ,
234+ metavar = 'hmac-key' ,
235+ help = 'HMAC key to use for encrypting context '
236+ 'data for performance profiling of operation. '
237+ 'This key should be the value of one of the '
238+ 'HMAC keys configured in osprofiler '
239+ 'middleware in the projects user would like '
240+ 'to profile. It needs to be specified in '
241+ 'configuration files of the required '
242+ 'projects.' )
243+
193244 return clientmanager .build_plugin_option_parser (parser )
194245
195246 def initialize_app (self , argv ):
0 commit comments