diff --git a/app/api/__init__.py b/app/api/__init__.py index ec050431..97f13099 100644 --- a/app/api/__init__.py +++ b/app/api/__init__.py @@ -15,9 +15,9 @@ from app.api.logs import router as logs_router from app.api.onedrive import router as onedrive_router from app.api.openai import router as openai_router from app.api.process import router as process_router +from app.api.queue import router as queue_router from app.api.search import router as search_router from app.api.settings import router as settings_router -from app.api.queue import router as queue_router from app.api.url_upload import router as url_upload_router # Import all the individual routers diff --git a/app/api/queue.py b/app/api/queue.py index a2677678..fdc851af 100644 --- a/app/api/queue.py +++ b/app/api/queue.py @@ -20,6 +20,10 @@ from app.models import FileProcessingStep, FileRecord logger = logging.getLogger(__name__) router = APIRouter(prefix="/queue", tags=["queue"]) +# Constants +CELERY_INSPECT_TIMEOUT = 2.0 +MAX_ARGS_DISPLAY_LENGTH = 200 + def _get_redis_queue_length(redis_client: redis.Redis, queue_name: str) -> int: """Get the number of messages in a Redis-backed Celery queue. @@ -54,7 +58,7 @@ def _get_celery_inspect_stats() -> dict[str, Any]: } try: - inspector = celery.control.inspect(timeout=2.0) + inspector = celery.control.inspect(timeout=CELERY_INSPECT_TIMEOUT) active = inspector.active() or {} reserved = inspector.reserved() or {} @@ -68,7 +72,7 @@ def _get_celery_inspect_stats() -> dict[str, Any]: { "id": task.get("id", ""), "name": task.get("name", "unknown"), - "args": str(task.get("args", []))[:200], + "args": str(task.get("args", []))[:MAX_ARGS_DISPLAY_LENGTH], "started": task.get("time_start"), } ) @@ -79,7 +83,7 @@ def _get_celery_inspect_stats() -> dict[str, Any]: { "id": task.get("id", ""), "name": task.get("name", "unknown"), - "args": str(task.get("args", []))[:200], + "args": str(task.get("args", []))[:MAX_ARGS_DISPLAY_LENGTH], } ) diff --git a/docs/API.md b/docs/API.md index 4255f02b..f0d6f87e 100644 --- a/docs/API.md +++ b/docs/API.md @@ -437,6 +437,57 @@ Errors follow standard HTTP status codes with descriptive messages: } ``` +## Queue Monitoring + +### GET /api/queue/stats + +Get comprehensive queue and processing statistics, including Redis queue lengths, Celery worker inspection data, and database-level processing summaries. + +**Authentication:** Required + +**Response (200 OK):** +```json +{ + "queues": { + "document_processor": 12, + "default": 0, + "celery": 0 + }, + "total_queued": 12, + "celery": { + "active": [ + {"id": "abc123", "name": "process_document", "args": "[42]", "started": 1700000000} + ], + "reserved": [], + "scheduled": [], + "workers_online": 1 + }, + "db_summary": { + "total_files": 5000, + "processing": 3, + "failed": 1, + "completed": 4900, + "pending": 96, + "recent_processing": [ + {"file_id": 42, "filename": "invoice.pdf", "current_step": "extract_metadata_with_gpt"} + ] + } +} +``` + +### GET /api/queue/pending-count + +Lightweight endpoint returning the total number of queued + in-progress items. Designed for the files page banner indicator. + +**Authentication:** Required + +**Response (200 OK):** +```json +{ + "total_pending": 15 +} +``` + ## Rate Limiting The API implements rate limiting to ensure system stability. If you exceed the limits, you'll receive a `429 Too Many Requests` response. diff --git a/docs/UserGuide.md b/docs/UserGuide.md index 8f1d5921..39c83cb4 100644 --- a/docs/UserGuide.md +++ b/docs/UserGuide.md @@ -92,6 +92,23 @@ The **Files** page provides access to all processed documents: 3. Click on any file to view its details 4. Sort the list by any column by clicking on the column header +> **Tip:** When documents are being processed, a blue banner appears at the top of the Files page showing how many items are queued or currently processing. Files will appear in the list once their processing completes. Admins can click "View Queue" in the banner to open the Queue Monitor dashboard. + +## Queue Monitor (Admin) + +The **Queue Monitor** dashboard provides real-time visibility into the document processing pipeline. It is available to admin users under **Admin → Queue Monitor** in the navigation bar. + +The dashboard shows: +- **Queued Tasks** — number of tasks waiting in Redis-backed Celery queues +- **Active Tasks** — tasks currently being executed by Celery workers +- **Files Processing** — files with at least one in-progress processing step +- **Workers Online** — number of connected Celery worker processes +- **Redis Queues** — per-queue breakdown of pending task counts +- **Processing Pipeline** — database-level summary of file states (completed, processing, pending, failed) +- **Recently Processing Files** — the most recent files being actively processed, with links to their detail pages + +The dashboard auto-refreshes every 10 seconds. + ## Searching Documents DocuElevate provides two ways to search your documents: diff --git a/frontend/templates/queue_dashboard.html b/frontend/templates/queue_dashboard.html index 20f7fdbe..65c9fdea 100644 --- a/frontend/templates/queue_dashboard.html +++ b/frontend/templates/queue_dashboard.html @@ -189,6 +189,7 @@