Skip to content

Commit 252410c

Browse files
authored
Keep task results if available and update logs/counter (#1559)
1 parent c290576 commit 252410c

File tree

2 files changed

+46
-28
lines changed

2 files changed

+46
-28
lines changed

turbinia/state_manager.py

Lines changed: 16 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -174,7 +174,7 @@ def get_task(self, task_id: str) -> dict:
174174
task_id (str): The ID of the stored task.
175175
176176
Returns:
177-
task_dict (dict): Dict containing task attributes.
177+
task_dict (dict): Dict containing task attributes.
178178
"""
179179
task_key = ':'.join(('TurbiniaTask', task_id))
180180
task_dict = {}
@@ -265,7 +265,7 @@ def get_task_data(
265265

266266
def update_request_task(self, task) -> None:
267267
"""Adds a Turbinia task to the corresponding request list.
268-
268+
269269
Args:
270270
task (TurbiniaTask): Turbinia task object.
271271
"""
@@ -315,7 +315,9 @@ def write_new_task(self, task) -> Optional[str]:
315315
Returns:
316316
task_key Optional[str]: The key corresponding for the task.
317317
"""
318-
log.info(f'Writing metadata for new task {task.name:s} with id {task.id:s}')
318+
log.info(
319+
f'Writing metadata for new task {task.name:s} with id {task.id:s} '
320+
f'and request ID {task.request_id}')
319321
try:
320322
task_key = self.redis_client.build_key_name('task', task.id)
321323
except ValueError as exception:
@@ -359,7 +361,7 @@ def update_task_helper(self, task) -> Dict[str, Any]:
359361

360362
def update_task(self, task) -> Optional[str]:
361363
"""Updates a Turbinia task key.
362-
364+
363365
Args:
364366
task: A TurbiniaTask object.
365367
@@ -400,7 +402,7 @@ def write_evidence(self, evidence_dict: dict[str]) -> str:
400402
401403
Returns:
402404
evidence_key (str): The key corresponding to the evidence in Redis
403-
405+
404406
Raises:
405407
TurbiniaException: If the attribute deserialization fails.
406408
"""
@@ -443,7 +445,7 @@ def get_evidence_data(self, evidence_id: str) -> dict:
443445
evidence_id (str): The ID of the stored evidence.
444446
445447
Returns:
446-
evidence_dict (dict): Dict containing evidence attributes.
448+
evidence_dict (dict): Dict containing evidence attributes.
447449
"""
448450
evidence_key = ':'.join(('TurbiniaEvidence', evidence_id))
449451
evidence_dict = {}
@@ -462,7 +464,7 @@ def get_evidence_summary(
462464
output (str): Output of the function (keys | content | count).
463465
464466
Returns:
465-
summary (dict | list | int): Object containing evidences.
467+
summary (dict | list | int): Object containing evidences.
466468
"""
467469
if output == 'count' and not group:
468470
return sum(1 for _ in self.redis_client.iterate_keys('Evidence'))
@@ -494,7 +496,7 @@ def query_evidence(
494496
output (str): Output of the function (keys | content | count).
495497
496498
Returns:
497-
query_result (list | int): Result of the query.
499+
query_result (list | int): Result of the query.
498500
"""
499501
keys = []
500502
for evidence_key in self.redis_client.iterate_keys('Evidence'):
@@ -517,7 +519,7 @@ def get_evidence_key_by_hash(self, file_hash: str) -> str | None:
517519
file_hash (str): The hash of the stored evidence.
518520
519521
Returns:
520-
key (str | None): Key of the stored evidence.
522+
key (str | None): Key of the stored evidence.
521523
"""
522524
try:
523525
if file_hash:
@@ -533,7 +535,7 @@ def get_evidence_by_hash(self, file_hash: str) -> dict:
533535
file_hash (str): The hash of the stored evidence.
534536
535537
Returns:
536-
evidence_dict (dict): Dict containing evidence attributes.
538+
evidence_dict (dict): Dict containing evidence attributes.
537539
"""
538540
evidence_id = self.get_evidence_key_by_hash(file_hash).split(':')[1]
539541
return self.get_evidence_data(evidence_id)
@@ -544,12 +546,12 @@ def write_request(self, request_dict: dict, overwrite=False):
544546
Args:
545547
request_dict (dict[str]): A dictionary containing the serialized
546548
request attributes that will be saved.
547-
overwrite (bool): Allows overwriting previous key and blocks writing new
549+
overwrite (bool): Allows overwriting previous key and blocks writing new
548550
ones.
549551
550552
Returns:
551553
request_key (str): The key corresponding to the evidence in Redis
552-
554+
553555
Raises:
554556
TurbiniaException: If the attribute deserialization fails or tried to
555557
overwrite an existing key without overwrite=True
@@ -589,7 +591,7 @@ def get_request_data(self, request_id: str) -> dict:
589591
request_id (str): The ID of the stored request.
590592
591593
Returns:
592-
request_dict (dict): Dict containing request attributes.
594+
request_dict (dict): Dict containing request attributes.
593595
"""
594596
request_key = self.redis_client.build_key_name('request', request_id)
595597
request_dict = {}
@@ -637,7 +639,7 @@ def query_requests(
637639
output (str): Output of the function (keys | content | count).
638640
639641
Returns:
640-
query_result (list | int): Result of the query.
642+
query_result (list | int): Result of the query.
641643
"""
642644
keys = []
643645
for request_key in self.redis_client.iterate_keys('request'):

turbinia/task_manager.py

Lines changed: 30 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,9 @@
7878
turbinia_server_task_timeout_total = Counter(
7979
'turbinia_server_task_timeout_total',
8080
'Total number of Tasks that have timed out on the Server.')
81+
turbinia_server_task_fail_total = Counter(
82+
'turbinia_server_task_fail_total',
83+
'Total number of Tasks that have failed according to the Server.')
8184
turbinia_result_success_invalid = Counter(
8285
'turbinia_result_success_invalid',
8386
'The result returned from the Task had an invalid success status of None')
@@ -623,18 +626,30 @@ def close_failed_task(self, task):
623626
Returns:
624627
TurbiniaTask: The updated Task.
625628
"""
626-
result = workers.TurbiniaTaskResult(
627-
request_id=task.request_id, no_output_manager=True,
628-
no_state_manager=True)
629-
result.setup(task)
630-
if task.stub.traceback:
631-
result.status = (
632-
f'Task {task.id} failed with exception: {task.stub.traceback}')
633-
else:
634-
result.status = f'Task {task.id} failed.'
635-
result.successful = False
636-
result.closed = True
637-
task.result = result
629+
if not task.result:
630+
result = workers.TurbiniaTaskResult(
631+
request_id=task.request_id, no_output_manager=True,
632+
no_state_manager=True)
633+
result.setup(task)
634+
task.result = result
635+
636+
if not task.result.status:
637+
if task.stub.traceback:
638+
task.result.status = (
639+
f'Task {task.id} failed with exception: {task.stub.traceback}')
640+
else:
641+
task.result.status = f'Task {task.id} failed.'
642+
# Record the traceback in the status if we have one otherwise it won't
643+
# be visible for the user.
644+
elif task.result.status and task.stub.traceback:
645+
new_status = (
646+
f'{task.result.status} (Task failure exception: '
647+
f'{task.stub.traceback})')
648+
task.result.status = new_status
649+
650+
task.result.successful = False
651+
task.result.closed = True
652+
turbinia_server_task_fail_total.inc()
638653
return task
639654

640655
def timeout_task(self, task, timeout):
@@ -813,8 +828,9 @@ def get_evidence(self):
813828

814829
def enqueue_task(self, task, evidence_, timeout):
815830
log.info(
816-
f'Adding Celery task {task.name:s} with evidence {evidence_.name:s}'
817-
f' to queue with base task timeout {timeout}')
831+
f'Adding Celery task {task.name:s} for request id {task.request_id} '
832+
f'with evidence {evidence_.name:s} to queue with base task '
833+
f'timeout {timeout}')
818834
# https://docs.celeryq.dev/en/stable/userguide/configuration.html#task-time-limit
819835
# Hard limit in seconds, the worker processing the task will be killed and
820836
# replaced with a new one when this is exceeded.

0 commit comments

Comments
 (0)