Browse Source

HUE-2284 [impala] Provide Impala Thrift API implementation of GetRuntimeProfile

POST /impala/api/query/<query_history_id>/runtime_profile

query_history_id must reference an HS2 session/operation

Returns a JSON response with 'status' and 'profile'. 'profile' is a string that can be printed to display the formatted runtime profile.

Jenny Kim 10 years ago
parent
commit
8bc0076

+ 23 - 0
apps/impala/src/impala/api.py

@@ -88,3 +88,26 @@ def get_exec_summary(request, query_history_id):
     response['summary'] = summary
 
   return JsonResponse(response)
+
+
+@require_POST
+@error_handler
+def get_runtime_profile(request, query_history_id):
+  query_server = dbms.get_query_server_config()
+  db = beeswax_dbms.get(request.user, query_server=query_server)
+
+  response = {'status': -1}
+  query_history = authorized_get_query_history(request, query_history_id, must_exist=True)
+
+  if query_history is None:
+    response['message'] = _('get_runtime_profile requires a valid query_history_id')
+  else:
+    session = Session.objects.get_session(request.user, query_server['server_name'])
+    operation_handle = query_history.get_handle().get_rpc_handle()
+    session_handle = session.get_handle()
+    profile = db.get_runtime_profile(operation_handle, session_handle)
+    response['status'] = 0
+    response['profile'] = profile
+
+  return JsonResponse(response)
+

+ 4 - 0
apps/impala/src/impala/dbms.py

@@ -155,6 +155,10 @@ class ImpalaDbms(HiveServer2Dbms):
     return self.client._client.get_exec_summary(query_handle, session_handle)
 
 
+  def get_runtime_profile(self, query_handle, session_handle):
+    return self.client._client.get_runtime_profile(query_handle, session_handle)
+
+
   def _get_beeswax_tables(self, database):
     beeswax_query_server = dbms.get(user=self.client.user, query_server=beeswax_query_server_config(name='beeswax'))
     return beeswax_query_server.get_tables(database=database)

+ 18 - 0
apps/impala/src/impala/server.py

@@ -51,6 +51,24 @@ class ImpalaServerClient(HiveServerClient):
     return self._serialize_exec_summary(resp.summary)
 
 
+  def get_runtime_profile(self, operation_handle, session_handle):
+    """
+    Calls Impala HS2 API's GetRuntimeProfile method on the given query handle
+    :return: TExecSummary object serialized as a dict
+    """
+    req = ImpalaHiveServer2Service.TGetRuntimeProfileReq(operationHandle=operation_handle, sessionHandle=session_handle)
+
+    # TGetRuntimeProfileReq() only works for closed queries
+    try:
+      self.close_operation(operation_handle)
+    except QueryServerException, e:
+      LOG.warn('Failed to close operation for query handle, query may be invalid or already closed.')
+
+    resp = self.call(self._client.GetRuntimeProfile, req)
+
+    return resp.profile
+
+
   def _serialize_exec_summary(self, summary):
     try:
       summary_dict = {

+ 17 - 0
apps/impala/src/impala/tests.py

@@ -322,6 +322,23 @@ class TestImpalaIntegration:
     assert_true(len(data['summary']['nodes']) > 0, data['summary']['nodes'])
 
 
+  def test_get_runtime_profile(self):
+    query = """
+      SELECT COUNT(1) FROM tweets;
+    """
+
+    response = _make_query(self.client, query, database=self.DATABASE, local=False, server_name='impala')
+    content = json.loads(response.content)
+    query_history = QueryHistory.get(content['id'])
+
+    wait_for_query_to_finish(self.client, response, max=180.0)
+
+    resp = self.client.post(reverse('impala:get_runtime_profile', kwargs={'query_history_id': query_history.id}))
+    data = json.loads(resp.content)
+    assert_equal(0, data['status'], data)
+    assert_true('Execution Profile' in data['profile'], data)
+
+
 # Could be refactored with SavedQuery.create_empty()
 def create_saved_query(app_name, owner):
     query_type = SavedQuery.TYPES_MAPPING[app_name]

+ 1 - 0
apps/impala/src/impala/urls.py

@@ -24,6 +24,7 @@ urlpatterns = patterns('impala.api',
   url(r'^api/invalidate$', 'invalidate', name='invalidate'),
   url(r'^api/refresh/(?P<database>\w+)/(?P<table>\w+)$', 'refresh_table', name='refresh_table'),
   url(r'^api/query/(?P<query_history_id>\d+)/exec_summary$', 'get_exec_summary', name='get_exec_summary'),
+  url(r'^api/query/(?P<query_history_id>\d+)/runtime_profile', 'get_runtime_profile', name='get_runtime_profile'),
 )
 
 urlpatterns += patterns('impala.dashboards',