Bases: ModelAdmin
Read-only admin interface for browsing application logs.
Provides two views:
- Cards view (default): one card per logger with error/warning badges and a
color-coded timeline strip across the selected time range.
- Table view: standard Django changelist with filters and search, shown when
any admin filter or search parameter is present.
changelist_view(request, extra_context=None)
Show the cards dashboard unless Django admin filters/search are active.
Source code in log_panel/admin.py
| def changelist_view(
self, request: HttpRequest, extra_context: dict | None = None
) -> HttpResponse:
"""Show the cards dashboard unless Django admin filters/search are active."""
if set(request.GET.keys()).issubset(CARDS_PARAMS):
backend: LogsBackend | None = conf.get_backend()
context: dict = self._logger_cards_context(request, backend, error=None)
return TemplateResponse(
request, "admin/log_panel/panel/cards.html", context
)
self.list_per_page: Any = conf.get_setting(
key="TABLE_PAGE_SIZE"
) # pragma: no cover
return super().changelist_view(request, extra_context) # pragma: no cover
|
get_urls()
Add a read-only full-message view for chunked log payloads.
Source code in log_panel/admin.py
| def get_urls(self) -> list:
"""Add a read-only full-message view for chunked log payloads."""
return [
path(
"<path:object_id>/message/",
self.admin_site.admin_view(self.message_view),
name="log_panel_log_message",
),
*super().get_urls(),
]
|
message_view(request, object_id)
Render the complete log message for a single log entry.
Source code in log_panel/admin.py
| def message_view(self, request: HttpRequest, object_id: str) -> TemplateResponse:
"""Render the complete log message for a single log entry."""
log: Log = get_object_or_404(
Log.objects.prefetch_related("message_chunks"),
pk=object_id,
)
return TemplateResponse(
request,
"admin/log_panel/panel/message.html",
{
**self.admin_site.each_context(request),
"title": f"{conf.get_setting(key='TITLE')} — {log.logger_name}",
"opts": self.model._meta,
"log": log,
"log_message": log.get_full_message(),
"level_colors": conf.get_level_colors(),
},
)
|
short_message(obj)
Render the message preview with a link to the full payload for chunked entries.
Source code in log_panel/admin.py
| @admin.display(description="Message")
def short_message(self, obj: Log) -> str:
"""Render the message preview with a link to the full payload for chunked entries."""
if obj.message_chunked:
url: str = reverse(viewname="admin:log_panel_log_message", args=[obj.pk])
return format_html(
'{} <a href="{}">[full message ({} chars)]</a>',
obj.message,
url,
obj.message_size,
)
return obj.message
|