Asyncz Dashboard Logs¶
The dashboard log viewer is built on top of Python's standard logging module. It captures records from the asyncz logger namespace and stores them in a pluggable log storage backend.
Logs are also used by run history. Run lifecycle records include a structured
run_id, and the Logs page can filter directly by that id.
Default behavior¶
When the dashboard is mounted, Asyncz:
- creates or reuses a log storage backend
- installs
TaskLogHandleron theasynczlogger namespace - records structured extras from log records when present
- renders log rows through
/dashboard/logs/and/dashboard/logs/partials/table
Logging from tasks¶
For task-scoped logging, use get_task_logger(...).
from asyncz.contrib.dashboard.logs.handler import get_task_logger
logger = get_task_logger("task-123")
logger.info("starting work")
TaskLogHandler looks for a task id in these record fields:
task_idjob_idasyncz_task_id
That means regular stdlib logging also works:
import logging
logging.getLogger("asyncz.jobs").info("task completed", extra={"job_id": "task-123"})
Custom storage¶
All storage backends implement this interface:
from collections.abc import Iterable
from datetime import datetime
from asyncz.contrib.dashboard.logs.storage import LogEntry
class LogStorage:
def append(self, entry: LogEntry) -> None:
...
def query(
self,
*,
task_id: str | None = None,
run_id: str | None = None,
level: str | None = None,
q: str | None = None,
since: datetime | None = None,
until: datetime | None = None,
limit: int = 200,
) -> Iterable[LogEntry]:
...
The built-in default is MemoryLogStorage.
from asyncz.contrib.dashboard.logs.storage import MemoryLogStorage
storage = MemoryLogStorage(maxlen=20_000)
Pass a custom storage instance into AsynczAdmin:
from asyncz.contrib.dashboard.admin import AsynczAdmin
admin = AsynczAdmin(scheduler=scheduler, log_storage=storage)
Query parameters used by the UI¶
The table partial accepts:
task_idrun_idlevelqlimit
Example:
/dashboard/logs/partials/table?task_id=task-123&level=ERROR&q=timeout
/dashboard/logs/partials/table?run_id=4f0efcc6c8a3d1b112aa
Run-history correlation¶
Run-history detail pages query logs in two passes:
- direct records with
extra["run_id"] == <run_id> - task-scoped records for the same task id in the run window
This means lifecycle records are always available for a recorded run. Task
application logs become visible when they use task_id, job_id, or
asyncz_task_id in standard-library logging extras.