diff --git a/django_toosimple_q/admin.py b/django_toosimple_q/admin.py index ed1f00d..2091ba1 100644 --- a/django_toosimple_q/admin.py +++ b/django_toosimple_q/admin.py @@ -72,6 +72,32 @@ class TaskExecAdmin(ReadOnlyAdmin): actions = ["action_requeue"] ordering = ["-created"] readonly_fields = ["task_", "result"] + fieldsets = [ + ( + None, + {"fields": ["icon", "task_name", "state", "task_"]}, + ), + ( + "Arguments", + {"fields": ["args", "kwargs"]}, + ), + ( + "Time", + {"fields": ["due_", "created_", "started_", "finished_"]}, + ), + ( + "Retries", + {"fields": ["retries", "retry_delay", "replaced_by"]}, + ), + ( + "Execution", + {"fields": ["worker", "error"]}, + ), + ( + "Output", + {"fields": ["stdout", "stderr", "result"]}, + ), + ] def arguments_(self, obj): return format_html( @@ -132,6 +158,20 @@ class ScheduleExecAdmin(ReadOnlyAdmin): list_filter = ["name", ScheduleQueueListFilter, "state"] actions = ["action_force_run"] readonly_fields = ["schedule_"] + fieldsets = [ + ( + None, + {"fields": ["icon", "name", "state", "schedule_"]}, + ), + ( + "Time", + {"fields": ["last_due_", "next_due_"]}, + ), + ( + "Execution", + {"fields": ["last_task_"]}, + ), + ] def schedule_(self, obj): if not obj.schedule: @@ -188,6 +228,24 @@ class WorkerStatusAdmin(ReadOnlyAdmin): list_display_links = ["label"] ordering = ["-started", "label"] readonly_fields = ["state"] + fieldsets = [ + ( + None, + {"fields": ["icon", "label"]}, + ), + ( + "Queues", + {"fields": ["included_queues", "excluded_queues"]}, + ), + ( + "Time", + {"fields": ["timeout", "last_tick_", "started_", "stopped_"]}, + ), + ( + "Exit state", + {"fields": ["exit_code", "exit_log"]}, + ), + ] @admin.display(ordering="last_tick") def last_tick_(self, obj): diff --git a/django_toosimple_q/logging.py b/django_toosimple_q/logging.py index 17577dc..6b4fe7e 100644 --- a/django_toosimple_q/logging.py +++ b/django_toosimple_q/logging.py @@ -3,7 +3,7 @@ from .registry import schedules_registry, tasks_registry formatter = logging.Formatter( - "[%(asctime)s %(levelname)s] [toosimpleq] %(message)s", "%Y-%m-%d %H:%M:%S" + "[%(asctime)s][%(levelname)s][toosimpleq] %(message)s", "%Y-%m-%d %H:%M:%S" ) handler = logging.StreamHandler() diff --git a/django_toosimple_q/management/commands/worker.py b/django_toosimple_q/management/commands/worker.py index 71bf96f..dfbf67c 100644 --- a/django_toosimple_q/management/commands/worker.py +++ b/django_toosimple_q/management/commands/worker.py @@ -239,7 +239,7 @@ def do_loop(self) -> bool: with transaction.atomic(): self.cur_task_exec = self._build_due_tasks_qs().first() if self.cur_task_exec: - logger.debug(f"{self.cur_task_exec} is due !") + logger.debug(f"Picking up for execution : {self.cur_task_exec}") self.cur_task_exec.started = now() self.cur_task_exec.state = TaskExec.States.PROCESSING self.cur_task_exec.worker = self.worker_status diff --git a/django_toosimple_q/models.py b/django_toosimple_q/models.py index 3ac11aa..12d19bb 100644 --- a/django_toosimple_q/models.py +++ b/django_toosimple_q/models.py @@ -112,6 +112,7 @@ def icon(self): return TaskExec.States.icon(self.state) def execute(self): + logger.info(f"{self} started") try: # Get the task from the registry task = tasks_registry[self.task_name] @@ -120,6 +121,7 @@ def execute(self): stdout, stderr = io.StringIO(), io.StringIO() with redirect_stderr(stderr), redirect_stdout(stdout): self.result = task.callable(*self.args, **self.kwargs) + logger.info(f"{self} succeeded") self.state = TaskExec.States.SUCCEEDED except Exception: logger.warning(f"{self} failed !") @@ -219,6 +221,7 @@ def execute(self): did_something = False if self.next_dues: + logger.info(f"{self} is due ({len(self.next_dues)} occurences)") self.schedule.execute(self.next_dues) did_something = True self.last_due = self.next_dues[-1] diff --git a/django_toosimple_q/tests/demo/tasks.py b/django_toosimple_q/tests/demo/tasks.py index 8b49eba..dfc9b91 100644 --- a/django_toosimple_q/tests/demo/tasks.py +++ b/django_toosimple_q/tests/demo/tasks.py @@ -10,7 +10,9 @@ from ...models import TaskExec -@schedule_task(cron="* * * * * */30", datetime_kwarg="scheduled_time", queue="demo") +@schedule_task( + cron="* * * * * */30", datetime_kwarg="scheduled_time", queue="demo", catch_up=True +) @register_task(name="say_hi", queue="demo") def say_hi(scheduled_time): if scheduled_time is None: diff --git a/docker-compose.yml b/docker-compose.yml index 4bc36b3..997dcb2 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -30,7 +30,7 @@ services: worker: <<: *default-django - command: worker --queue demo + command: worker --queue demo --verbosity 3 postgres: image: postgres