chore: improve image worker logging
This commit is contained in:
@@ -4,6 +4,7 @@ import uuid
|
||||
from django.conf import settings
|
||||
from django.core.management.base import BaseCommand
|
||||
|
||||
from apps.api.models import ImageGenerationTask
|
||||
from apps.api.image_tasks import reap_stale_image_tasks, run_one_image_task
|
||||
|
||||
|
||||
@@ -56,7 +57,7 @@ class Command(BaseCommand):
|
||||
|
||||
task = run_one_image_task(worker_id=worker_id)
|
||||
if task is not None:
|
||||
self.stdout.write(f"task={task.task_id} status={task.status}")
|
||||
self.stdout.write(format_task_log_line(task, started_at=now))
|
||||
if once:
|
||||
return
|
||||
continue
|
||||
@@ -64,3 +65,18 @@ class Command(BaseCommand):
|
||||
if once:
|
||||
return
|
||||
time.sleep(sleep_seconds)
|
||||
|
||||
|
||||
def format_task_log_line(task: ImageGenerationTask, *, started_at: float) -> str:
|
||||
duration_ms = max(0, int((time.monotonic() - started_at) * 1000))
|
||||
alias = str((task.request_payload or {}).get("model") or "")
|
||||
fields = {
|
||||
"event": "image_task_processed",
|
||||
"task_id": str(task.task_id),
|
||||
"status": task.status,
|
||||
"alias": alias,
|
||||
"duration_ms": str(duration_ms),
|
||||
}
|
||||
if task.status in {ImageGenerationTask.Status.FAILED, ImageGenerationTask.Status.EXPIRED}:
|
||||
fields["error_code"] = task.error_code or "upstream_error"
|
||||
return " ".join(f"{key}={value}" for key, value in fields.items())
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import uuid
|
||||
import base64
|
||||
import io
|
||||
import json
|
||||
import tempfile
|
||||
from datetime import timedelta
|
||||
@@ -13,6 +14,7 @@ from django.conf import settings
|
||||
from django.contrib import admin
|
||||
from django.contrib.auth import get_user_model
|
||||
from django.core.cache import cache
|
||||
from django.core.management import call_command
|
||||
from django.test import TestCase, override_settings
|
||||
from django.urls import path
|
||||
from django.utils import timezone
|
||||
@@ -1585,6 +1587,34 @@ class GenerateApiTests(TestCase):
|
||||
self.assertEqual(poll.data["status"], ImageGenerationTask.Status.FAILED)
|
||||
self.assertEqual(poll.data["error"]["code"], "upstream_timeout")
|
||||
|
||||
def test_run_image_tasks_logs_failed_task_alias_error_and_duration(self):
|
||||
self.provider.image_error = requests.Timeout("image upstream deadline exceeded")
|
||||
response = self.post_with_provider(
|
||||
"/api/v1/generate/image/tasks",
|
||||
{"prompt": "生成图片", "model": self.image_alias, "resolution": "1K"},
|
||||
)
|
||||
out = io.StringIO()
|
||||
|
||||
with patch("apps.api.generation.get_provider", return_value=self.provider):
|
||||
call_command(
|
||||
"run_image_tasks",
|
||||
"--once",
|
||||
"--worker-id",
|
||||
"worker-log",
|
||||
stdout=out,
|
||||
)
|
||||
|
||||
task = ImageGenerationTask.objects.get(task_id=response.data["task_id"])
|
||||
output = out.getvalue()
|
||||
self.assertEqual(task.status, ImageGenerationTask.Status.FAILED)
|
||||
self.assertIn("event=image_task_processed", output)
|
||||
self.assertIn(f"task_id={task.task_id}", output)
|
||||
self.assertIn(f"alias={self.image_alias}", output)
|
||||
self.assertIn("status=failed", output)
|
||||
self.assertIn("error_code=upstream_timeout", output)
|
||||
self.assertRegex(output, r"duration_ms=\d+")
|
||||
self.assertNotIn("生成图片", output)
|
||||
|
||||
def test_async_image_reaper_fails_stale_running_task_and_refunds(self):
|
||||
response = self.post_with_provider(
|
||||
"/api/v1/generate/image/tasks",
|
||||
|
||||
Reference in New Issue
Block a user