Esempio n. 1
0
    def __init__(self, prefix, instance: Task, initial):
        super().__init__()
        self.fields['name'].initial = instance.name

        logs = list()
        # on this stage it was quite hard to implement proper formatting in templates
        # so putting some html/js right here.
        # TODO: Refactor, put formatting to the templates

        # Main problem is that this form's template uses some base template which replaces \n with <br />
        for record in instance.get_task_log_from_elasticsearch():
            color = 'green'
            if record.log_level == 'WARN':
                color = 'yellow'
            elif record.log_level == 'ERROR':
                color = 'red'

            if not record.timestamp:
                ts = ''
            else:
                ts = record.timestamp.strftime('%Y-%m-%d %H:%M:%S')

            level = record.log_level or 'INFO'
            message = record.message
            if message and '\n' in message:
                message = '<br />' + message

            log_add = f'<b><span style="color: {color}">{level}</span> {ts} | {record.task_name or "no task"} |</b> ' \
                      f'{message}'

            logs.append(log_add)

            if record.stack_trace:
                # Adding JS to toggle stack trace showing/hiding
                stack = record.stack_trace.replace('\n', '<br />')
                uid = str(fast_uuid())
                uid_toggle = uid + '_toggle'
                show_hide = f'''e = document.getElementById('{uid}');
                                e.style.display = e.style.display === 'block' ? 'none' : 'block';
                                document.getElementById('{uid_toggle}').innerText 
                                        = e.style.display === 'block' ? '[-] Stack trace:' : '[+] Stack trace';
                            '''.replace('\n', '')
                logs.append(
                    f'<a id="{uid_toggle}" onclick="{show_hide}">[+] Stack trace:</a>'
                )
                logs.append(
                    f'<div id="{uid}" style="display: none; border-left: 1px solid grey; padding-left: 16px">'
                    f'{stack}</div>')

        self.fields['log'].initial = '\n'.join(logs)
 def get_task_detail(cls, task: Task) -> TaskRecord:
     reason = f'is started at {task.date_work_start} and not finished yet' if task.status == PENDING else 'is failed'
     r = TaskRecord(task.pk, task.name, reason, task.status,
                    task.date_work_start or task.date_start,
                    task.date_done or task.own_date_done,
                    task.user_id)
     for record in task.get_task_log_from_elasticsearch():
         r.kibana_ref = kibana_root_url(record.record_id, record.file_index, add_protocol=False)
         if not hasattr(record, 'stack_trace') or not hasattr(record, 'message') \
                 or record.log_level != 'ERROR':
             continue
         r.error_message = record.message
         r.stack_trace = record.stack_trace
         break
     return r
Esempio n. 3
0
    def __init__(self, prefix, instance: Task, initial):
        super().__init__()
        display_name = instance.display_name or instance.name
        if display_name != instance.name:
            display_name += f' ({instance.name})'
        if instance.status != SUCCESS:
            display_name += f' STATUS: {instance.status}'
        if instance.progress < 100:
            display_name += f' ({instance.progress}%)'

        self.fields['task'].initial = display_name
        self.fields['parents'].initial = ''
        self.fields['child_tasks'].initial = ''

        logs = list()
        # on this stage it was quite hard to implement proper formatting in templates
        # so putting some html/js right here.
        # TODO: Refactor, put formatting to the templates

        # list ancestors (parent tasks) up to the root
        parents_markup = []
        this_task = instance
        while this_task.parent_task_id:
            parent = this_task.parent_task
            task_name = parent.display_name or parent.name
            url = reverse('task:task-detail', args=[parent.pk])
            color = self.COLOR_BY_STATUS.get(
                parent.status) or self.COLOR_BY_STATUS['default']
            link_name = task_name if parent.progress == 100 else f'{task_name} ({parent.progress}%)'
            parents_markup.append(
                f'<a style="{color}" href="{url}">{link_name}</a>')
            this_task = this_task.parent_task

        markup = ''
        if parents_markup:
            markup = ' &lt;- '.join(parents_markup)
        self.fields['parents'].initial = markup

        # list child tasks
        child_query = Task.objects.filter(parent_task_id=instance.pk)
        children_count = child_query.count()
        children = list(
            child_query.values_list('pk', 'name', 'display_name', 'status',
                                    'progress')[:30])
        children_markup = []
        for pk, name, display_name, status, progress in children:
            url = reverse('task:task-detail', args=[pk])
            color = self.COLOR_BY_STATUS.get(
                status) or self.COLOR_BY_STATUS['default']
            task_name = display_name or name
            link_name = task_name if progress == 100 else f'{task_name} ({progress}%)'
            children_markup.append(
                f'<a style="{color}" href="{url}">{link_name}</a>')
        if children_count > len(children):
            children_markup.append(
                f' ... and {children_count - len(children)} more')
        self.fields['child_tasks'].initial = ', '.join(children_markup)

        # Main problem is that this form's template uses some base template which replaces \n with <br />
        for record in instance.get_task_log_from_elasticsearch():
            color = 'green'
            if record.log_level == 'WARN':
                color = 'yellow'
            elif record.log_level == 'ERROR':
                color = 'red'

            if not record.timestamp:
                ts = ''
            else:
                ts = record.timestamp.strftime('%Y-%m-%d %H:%M:%S')

            level = record.log_level or 'INFO'
            message = record.message
            if message and '\n' in message:
                message = '<br />' + message

            log_add = f'<b><span style="color: {color}">{level}</span> {ts} | {record.task_name or "no task"} |</b> ' \
                      f'{message}'

            logs.append(log_add)

            if record.stack_trace:
                # Adding JS to toggle stack trace showing/hiding
                stack = record.stack_trace.replace('\n', '<br />')
                uid = str(fast_uuid())
                uid_toggle = uid + '_toggle'
                show_hide = f'''e = document.getElementById('{uid}');
                                e.style.display = e.style.display === 'block' ? 'none' : 'block';
                                document.getElementById('{uid_toggle}').innerText 
                                        = e.style.display === 'block' ? '[-] Stack trace:' : '[+] Stack trace';
                            '''.replace('\n', '')
                logs.append(
                    f'<a id="{uid_toggle}" onclick="{show_hide}">[+] Stack trace:</a>'
                )
                logs.append(
                    f'<div id="{uid}" style="display: none; border-left: 1px solid grey; padding-left: 16px">'
                    f'{stack}</div>')

        self.fields['log'].initial = '\n'.join(logs)
Esempio n. 4
0
 def __init__(self, prefix, instance: Task, initial):
     super().__init__()
     self.fields['name'].initial = instance.name
     self.fields['log'].initial = instance.get_task_log_from_elasticsearch()
Esempio n. 5
0
    def __init__(self, prefix, instance: Task, initial):
        super().__init__()
        display_name = instance.display_name or instance.name
        if display_name != instance.name:
            display_name += f' ({instance.name})'
        if instance.status != SUCCESS:
            display_name += f' STATUS: {instance.status}'
        if instance.progress < 100:
            display_name += f' ({instance.progress}%)'

        self.fields['task'].initial = display_name
        self.fields['parents'].initial = ''
        self.fields['child_tasks'].initial = ''

        logs = list()  # type: List[str]
        # on this stage it was quite hard to implement proper formatting in templates
        # so putting some html/js right here.
        # TODO: Refactor, put formatting to the templates

        # list ancestors (parent tasks) up to the root
        parents_markup = []
        this_task = instance
        while this_task.parent_task_id:
            parent = this_task.parent_task
            task_name = parent.display_name or parent.name
            url = reverse('task:task-detail', args=[parent.pk])
            color = self.COLOR_BY_STATUS.get(parent.status) or self.COLOR_BY_STATUS['default']
            link_name = task_name if parent.progress == 100 else f'{task_name} ({parent.progress}%)'
            parents_markup.append(f'<a style="{color}" href="{url}">{link_name}</a>')
            this_task = this_task.parent_task

        markup = ''
        if parents_markup:
            markup = ' &lt;- '.join(parents_markup)
        self.fields['parents'].initial = markup

        # list child tasks
        child_query = Task.objects.filter(parent_task_id=instance.pk)
        children_count = child_query.count()
        children = list(child_query.values_list(
            'pk', 'name', 'display_name', 'status', 'progress')[:30])
        children_markup = []
        for pk, name, display_name, status, progress in children:
            url = reverse('task:task-detail', args=[pk])
            color = self.COLOR_BY_STATUS.get(status) or self.COLOR_BY_STATUS['default']
            task_name = display_name or name
            link_name = task_name if progress == 100 else f'{task_name} ({progress}%)'
            children_markup.append(f'<a style="{color}" href="{url}">{link_name}</a>')
        if children_count > len(children):
            children_markup.append(f' ... and {children_count - len(children)} more')
        self.fields['child_tasks'].initial = ', '.join(children_markup)

        if this_task.result and 'exc_type' in this_task.result:
            ex_module = this_task.result.get('exc_module') or '-'
            ex_message = this_task.result.get('exc_message') or '-'
            msg = f'<b><span style="color:red">ERROR</span> {this_task.result["exc_type"]} ' + \
                  f'in {ex_module}:\n{ex_message}'
            logs.append(msg)

        # Main problem is that this form's template uses some base template which replaces \n with <br />
        should_search_errors = this_task.status in {FAILURE, REVOKED} or \
            this_task.own_status in {FAILURE, REVOKED}
        all_records = instance.get_task_log_from_elasticsearch(should_search_errors)
        task_records = [r for r in all_records if r.task_name]
        genr_records = [r for r in all_records if not r.task_name]

        for record in task_records:
            color = self.get_task_record_color(record)
            ts = record.timestamp.strftime('%Y-%m-%d %H:%M:%S') if record.timestamp else ''
            level = record.log_level or 'INFO'
            message = record.message or ''
            message = '<br />' + message if '\n' in message else message

            log_add = f'<b><span style="color: {color}">{level}</span> {ts} | {record.task_name or "no task"} |</b> ' \
                      f'{message}'
            logs.append(log_add)

            if record.stack_trace:
                # Adding JS to toggle stack trace showing/hiding
                stack = record.stack_trace.replace('<', '&lt;').replace(
                    '>', '&gt;').replace('\n', '<br />')
                self.render_collapsible_block(logs, stack, 'Stack trace')

        # show system-wide errors in collapsible block
        if genr_records:
            logs.append(f'<br/><h4>{len(genr_records)} error(s) also occurred after completing the task</h4>')
            inner_block = ''
            for record in genr_records:
                color = self.get_task_record_color(record)
                ts = record.timestamp.strftime('%Y-%m-%d %H:%M:%S') if record.timestamp else ''
                level = record.log_level or 'INFO'
                message = record.message or ''
                message = '<br />' + message if '\n' in message else message
                log_add = f'<b><span style="color: {color}">{level}</span> {ts} </b> ' \
                          f'{message}<br/>'
                inner_block += log_add
            self.render_collapsible_block(logs, inner_block, 'System-wide errors')

        self.fields['log'].initial = '\n'.join(logs)