Browse Source

HUE-1176 [jb] List task attempts of a MR2 task

Romain Rigaux 9 years ago
parent
commit
f176112

+ 64 - 3
apps/jobbrowser/src/jobbrowser/apis/job_api.py

@@ -143,11 +143,13 @@ class YarnMapReduceTaskApi(Api):
   def apps(self):
     return [self._massage_task(task) for task in NativeYarnApi(self.user).get_tasks(jobid=self.app_id, pagenum=1)]
 
+
   def app(self, appid):
     task = NativeYarnApi(self.user).get_task(jobid=self.app_id, task_id=appid)
 
     common = self._massage_task(task)
     common['properties'] = {
+      'attempts': []
     }
 
     return common
@@ -163,9 +165,10 @@ class YarnMapReduceTaskApi(Api):
 
 
   def profile(self, appid, app_type, app_property):
-    if app_property == 'task_attemps':
-      response = tasks(self.request, job=appid)
-      return json.loads(response.content)
+    if app_property == 'attempts':
+      return {
+          'task_list': YarnMapReduceTaskAttemptApi(self.user, appid).apps(),
+      }
 
     return {}
 
@@ -182,6 +185,64 @@ class YarnMapReduceTaskApi(Api):
     }
 
 
+class YarnMapReduceTaskAttemptApi(Api):
+
+  def __init__(self, user, app_id):
+    Api.__init__(self, user)
+    self.app_id = '_'.join(app_id.replace('task_', 'application_').split('_')[:3])
+    self.task_id = app_id
+
+  def apps(self):
+    return [self._massage_task(task) for task in NativeYarnApi(self.user).get_task(jobid=self.app_id, task_id=self.task_id).attempts]
+
+
+  def app(self, appid):
+    task = NativeYarnApi(self.user).get_task(jobid=self.app_id, task_id=appid)
+
+    common = self._massage_task(task)
+    common['properties'] = {
+      'attempts': []
+    }
+
+    return common
+
+
+  def logs(self, appid, app_type):
+    if app_type == 'MAPREDUCE':
+      response = job_attempt_logs_json(MockDjangoRequest(self.user), job=appid)
+      logs = json.loads(response.content)['log']
+    else:
+      logs = None
+    return {'progress': 0, 'logs': {'default': logs}}
+
+
+  def profile(self, appid, app_type, app_property):
+    if app_property == 'attempts':
+      task = NativeYarnApi(self.user).get_task(jobid=self.app_id, task_id=appid)
+      return task.attempts
+
+    return {}
+
+  def _massage_task(self, task):
+    return {
+#         "elapsedMergeTime" : task.elapsedMergeTime,
+#         "shuffleFinishTime" : task.shuffleFinishTime,
+        "assignedContainerId" : task.assignedContainerId,
+        "progress" : task.progress,
+        "elapsedTime" : task.elapsedTime,
+        "state" : task.state,
+#         "elapsedShuffleTime" : task.elapsedShuffleTime,
+#         "mergeFinishTime" : task.mergeFinishTime,
+        "rack" : task.rack,
+#         "elapsedReduceTime" : task.elapsedReduceTime,
+        "nodeHttpAddress" : task.nodeHttpAddress,
+        "type" : task.type,
+        "startTime" : task.startTime,
+        "id" : task.id,
+        "finishTime" : task.finishTime
+    }
+
+
 class YarnAtsApi(Api):
   pass
 

+ 81 - 1
apps/jobbrowser/src/jobbrowser/templates/apps.mako

@@ -372,8 +372,88 @@ ${ commonheader("Job Browser", "jobbrowser", user, request) | n,unicode }
 
 </script>
 
+
 <script type="text/html" id="job-mapreduce-task-page">
-  Attempts | Metadata | Counters
+
+  <ul class="nav nav-tabs">
+    <li class="active"><a href="#job-mapreduce-task-page-logs" data-toggle="tab">${ _('Logs') }</a></li>
+    <li><a href="#job-mapreduce-task-page-attempts" data-toggle="tab">${ _('Attempts') }</a></li>
+    <li><a href="#job-mapreduce-task-page-metadata" data-toggle="tab">${ _('Metadata') }</a></li>
+    <li><a href="#job-mapreduce-task-page-counters" data-toggle="tab">${ _('Counters') }</a></li>
+  </ul>
+
+  <div class="tab-content">
+    <div class="tab-pane active" id="job-mapreduce-task-page-logs">
+      % for name in ['stdout', 'stderr', 'syslog']:
+        <a href="javascript:void(0)" data-bind="click: fetchLogs, text: '${ name }'"></a>
+      % endfor
+      </br>
+
+      <pre data-bind="html: logs['default']"></pre>
+    </div>
+
+    <div class="tab-pane" id="job-mapreduce-task-page-attempts">
+      <a href="javascript:void(0)" data-bind="click: function() { return fetchProfile('attempts'); }">Load</a>
+      </br>
+
+      ${_('Filter')} <input type="text" class="input-xlarge search-query" placeholder="${_('Filter by id, name, user...')}" value="user:${ user.username }">
+      <span class="btn-group">
+        <class="btn-group">
+          <a class="btn btn-status btn-success" data-value="completed">${ _('Succeeded') }</a>
+          <a class="btn btn-status btn-warning" data-value="running">${ _('Running') }</a>
+          <a class="btn btn-status btn-danger disable-feedback" data-value="failed">${ _('Failed') }</a>
+        </span>
+      </span>
+
+      <div class="btn-toolbar pull-right" style="display: inline; vertical-align: middle; margin-left: 10px; font-size: 12px">
+        <span class="loader hide"><i class="fa fa-2x fa-spinner fa-spin muted"></i></span>
+        <button class="btn bulkToolbarBtn bulk-resume" data-operation="resume" title="${ _('Resume selected') }" disabled="disabled" type="button"><i class="fa fa-play"></i><span class="hide-small"> ${ _('View') }</span></button>
+      </div>
+
+      <table class="table table-condensed">
+        <thead>
+        <tr>
+          <th width="1%"><div class="select-all hueCheckbox fa"></div></th>
+          <th>${_('assignedContainerId')}</th>
+          <th>${_('progress')}</th>
+          <th>${_('elapsedTime')}</th>
+          <th>${_('state')}</th>
+          <th>${_('rack')}</th>
+          <th>${_('nodeHttpAddress')}</th>
+          <th>${_('type')}</th>
+          <th>${_('startTime')}</th>
+          <th>${_('id')}</th>
+          <th>${_('finishTime')}</th>
+        </tr>
+        </thead>
+        <tbody data-bind="foreach: properties['attempts']()['task_list']">
+          <tr data-bind="click: function() { $root.job().id(id); $root.job().fetchJob(); }">
+            <td><div class="hueCheckbox fa"></div></td>
+            <td data-bind="text: assignedContainerId"></td>            
+            <td data-bind="text: progress"></td>
+            <td data-bind="text: elapsedTime"></td>            
+            <td data-bind="text: state"></td>
+            <td data-bind="text: rack"></td>
+            <td data-bind="text: nodeHttpAddress"></td>
+            <td data-bind="text: startTime"></td>
+            <td data-bind="text: id"></td>
+            <td data-bind="text: finishTime"></td>
+          </tr>
+        </tbody>
+      </table>
+    </div>
+
+    <div class="tab-pane" id="job-mapreduce-task-page-metadata">
+      <table class="table table-condensed">
+      </table>
+    </div>
+
+    <div class="tab-pane" id="job-mapreduce-task-page-counters">
+      <table class="table table-condensed">
+      </table>
+    </div>
+  </div>
+
 </script>
 
 <script type="text/html" id="job-mapreduce-task-attempt-page">