mirror of
https://github.com/netbox-community/netbox.git
synced 2024-05-10 07:54:54 +00:00
@ -69,5 +69,5 @@ class JobSerializer(BaseModelSerializer):
|
|||||||
model = Job
|
model = Job
|
||||||
fields = [
|
fields = [
|
||||||
'id', 'url', 'display', 'object_type', 'object_id', 'name', 'status', 'created', 'scheduled', 'interval',
|
'id', 'url', 'display', 'object_type', 'object_id', 'name', 'status', 'created', 'scheduled', 'interval',
|
||||||
'started', 'completed', 'user', 'data', 'job_id',
|
'started', 'completed', 'user', 'data', 'error', 'job_id',
|
||||||
]
|
]
|
||||||
|
@ -25,7 +25,7 @@ def sync_datasource(job, *args, **kwargs):
|
|||||||
job.terminate()
|
job.terminate()
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
job.terminate(status=JobStatusChoices.STATUS_ERRORED)
|
job.terminate(status=JobStatusChoices.STATUS_ERRORED, error=str(e))
|
||||||
DataSource.objects.filter(pk=datasource.pk).update(status=DataSourceStatusChoices.FAILED)
|
DataSource.objects.filter(pk=datasource.pk).update(status=DataSourceStatusChoices.FAILED)
|
||||||
if type(e) in (SyncError, JobTimeoutException):
|
if type(e) in (SyncError, JobTimeoutException):
|
||||||
logging.error(e)
|
logging.error(e)
|
||||||
|
18
netbox/core/migrations/0006_job_add_error_field.py
Normal file
18
netbox/core/migrations/0006_job_add_error_field.py
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
# Generated by Django 4.2.6 on 2023-10-23 20:28
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('core', '0005_job_created_auto_now'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='job',
|
||||||
|
name='error',
|
||||||
|
field=models.TextField(blank=True, editable=False),
|
||||||
|
),
|
||||||
|
]
|
@ -92,6 +92,11 @@ class Job(models.Model):
|
|||||||
null=True,
|
null=True,
|
||||||
blank=True
|
blank=True
|
||||||
)
|
)
|
||||||
|
error = models.TextField(
|
||||||
|
verbose_name=_('error'),
|
||||||
|
editable=False,
|
||||||
|
blank=True
|
||||||
|
)
|
||||||
job_id = models.UUIDField(
|
job_id = models.UUIDField(
|
||||||
verbose_name=_('job ID'),
|
verbose_name=_('job ID'),
|
||||||
unique=True
|
unique=True
|
||||||
@ -158,7 +163,7 @@ class Job(models.Model):
|
|||||||
# Handle webhooks
|
# Handle webhooks
|
||||||
self.trigger_webhooks(event=EVENT_JOB_START)
|
self.trigger_webhooks(event=EVENT_JOB_START)
|
||||||
|
|
||||||
def terminate(self, status=JobStatusChoices.STATUS_COMPLETED):
|
def terminate(self, status=JobStatusChoices.STATUS_COMPLETED, error=None):
|
||||||
"""
|
"""
|
||||||
Mark the job as completed, optionally specifying a particular termination status.
|
Mark the job as completed, optionally specifying a particular termination status.
|
||||||
"""
|
"""
|
||||||
@ -168,6 +173,8 @@ class Job(models.Model):
|
|||||||
|
|
||||||
# Mark the job as completed
|
# Mark the job as completed
|
||||||
self.status = status
|
self.status = status
|
||||||
|
if error:
|
||||||
|
self.error = error
|
||||||
self.completed = timezone.now()
|
self.completed = timezone.now()
|
||||||
self.save()
|
self.save()
|
||||||
|
|
||||||
|
@ -47,7 +47,7 @@ class JobTable(NetBoxTable):
|
|||||||
model = Job
|
model = Job
|
||||||
fields = (
|
fields = (
|
||||||
'pk', 'id', 'object_type', 'object', 'name', 'status', 'created', 'scheduled', 'interval', 'started',
|
'pk', 'id', 'object_type', 'object', 'name', 'status', 'created', 'scheduled', 'interval', 'started',
|
||||||
'completed', 'user', 'job_id',
|
'completed', 'user', 'error', 'job_id',
|
||||||
)
|
)
|
||||||
default_columns = (
|
default_columns = (
|
||||||
'pk', 'id', 'object_type', 'object', 'name', 'status', 'created', 'started', 'completed', 'user',
|
'pk', 'id', 'object_type', 'object', 'name', 'status', 'created', 'started', 'completed', 'user',
|
||||||
|
@ -59,7 +59,7 @@ class Command(BaseCommand):
|
|||||||
logger.error(f"Exception raised during script execution: {e}")
|
logger.error(f"Exception raised during script execution: {e}")
|
||||||
clear_webhooks.send(request)
|
clear_webhooks.send(request)
|
||||||
job.data = ScriptOutputSerializer(script).data
|
job.data = ScriptOutputSerializer(script).data
|
||||||
job.terminate(status=JobStatusChoices.STATUS_ERRORED)
|
job.terminate(status=JobStatusChoices.STATUS_ERRORED, error=str(e))
|
||||||
|
|
||||||
logger.info(f"Script completed in {job.duration}")
|
logger.info(f"Script completed in {job.duration}")
|
||||||
|
|
||||||
|
@ -40,8 +40,8 @@ def run_report(job, *args, **kwargs):
|
|||||||
|
|
||||||
try:
|
try:
|
||||||
report.run(job)
|
report.run(job)
|
||||||
except Exception:
|
except Exception as e:
|
||||||
job.terminate(status=JobStatusChoices.STATUS_ERRORED)
|
job.terminate(status=JobStatusChoices.STATUS_ERRORED, error=str(e))
|
||||||
logging.error(f"Error during execution of report {job.name}")
|
logging.error(f"Error during execution of report {job.name}")
|
||||||
finally:
|
finally:
|
||||||
# Schedule the next job if an interval has been set
|
# Schedule the next job if an interval has been set
|
||||||
@ -230,7 +230,7 @@ class Report(object):
|
|||||||
stacktrace = traceback.format_exc()
|
stacktrace = traceback.format_exc()
|
||||||
self.log_failure(None, f"An exception occurred: {type(e).__name__}: {e} <pre>{stacktrace}</pre>")
|
self.log_failure(None, f"An exception occurred: {type(e).__name__}: {e} <pre>{stacktrace}</pre>")
|
||||||
logger.error(f"Exception raised during report execution: {e}")
|
logger.error(f"Exception raised during report execution: {e}")
|
||||||
job.terminate(status=JobStatusChoices.STATUS_ERRORED)
|
job.terminate(status=JobStatusChoices.STATUS_ERRORED, error=str(e))
|
||||||
|
|
||||||
# Perform any post-run tasks
|
# Perform any post-run tasks
|
||||||
self.post_run()
|
self.post_run()
|
||||||
|
@ -519,7 +519,7 @@ def run_script(data, request, job, commit=True, **kwargs):
|
|||||||
logger.error(f"Exception raised during script execution: {e}")
|
logger.error(f"Exception raised during script execution: {e}")
|
||||||
script.log_info("Database changes have been reverted due to error.")
|
script.log_info("Database changes have been reverted due to error.")
|
||||||
job.data = ScriptOutputSerializer(script).data
|
job.data = ScriptOutputSerializer(script).data
|
||||||
job.terminate(status=JobStatusChoices.STATUS_ERRORED)
|
job.terminate(status=JobStatusChoices.STATUS_ERRORED, error=str(e))
|
||||||
clear_webhooks.send(request)
|
clear_webhooks.send(request)
|
||||||
|
|
||||||
logger.info(f"Script completed in {job.duration}")
|
logger.info(f"Script completed in {job.duration}")
|
||||||
|
@ -35,6 +35,12 @@
|
|||||||
<th scope="row">{% trans "Status" %}</th>
|
<th scope="row">{% trans "Status" %}</th>
|
||||||
<td>{% badge object.get_status_display object.get_status_color %}</td>
|
<td>{% badge object.get_status_display object.get_status_color %}</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
{% if object.error %}
|
||||||
|
<tr>
|
||||||
|
<th scope="row">{% trans "Error" %}</th>
|
||||||
|
<td>{{ object.error }}</td>
|
||||||
|
</tr>
|
||||||
|
{% endif %}
|
||||||
<tr>
|
<tr>
|
||||||
<th scope="row">{% trans "Created By" %}</th>
|
<th scope="row">{% trans "Created By" %}</th>
|
||||||
<td>{{ object.user|placeholder }}</td>
|
<td>{{ object.user|placeholder }}</td>
|
||||||
|
Reference in New Issue
Block a user