Plain is headed towards 1.0! Subscribe for development updates →

  1from functools import cached_property
  2
  3from plain.admin.toolbar import ToolbarPanel, register_toolbar_panel
  4from plain.admin.views import (
  5    AdminModelDetailView,
  6    AdminModelListView,
  7    AdminViewset,
  8    register_viewset,
  9)
 10
 11from .core import Observer
 12from .models import Span, Trace
 13
 14
 15@register_viewset
 16class TraceViewset(AdminViewset):
 17    class ListView(AdminModelListView):
 18        nav_section = "Observer"
 19        model = Trace
 20        fields = [
 21            "trace_id",
 22            "request_id",
 23            "session_id",
 24            "user_id",
 25            "start_time",
 26        ]
 27        allow_global_search = False
 28        # Actually want a button to delete ALL! not possible yet
 29        # actions = ["Delete"]
 30
 31        # def perform_action(self, action: str, target_pks: list):
 32        #     if action == "Delete":
 33        #         Trace.objects.filter(id__in=target_pks).delete()
 34
 35    class DetailView(AdminModelDetailView):
 36        model = Trace
 37        template_name = "admin/observer/trace_detail.html"
 38
 39        def get_template_context(self):
 40            context = super().get_template_context()
 41            trace_id = self.url_kwargs["pk"]
 42            context["trace"] = Trace.objects.get(pk=trace_id)
 43            context["show_delete_button"] = False
 44            return context
 45
 46
 47@register_viewset
 48class SpanViewset(AdminViewset):
 49    class ListView(AdminModelListView):
 50        nav_section = "Observer"
 51        model = Span
 52        fields = [
 53            "name",
 54            "kind",
 55            "status",
 56            "span_id",
 57            "parent_id",
 58            "start_time",
 59        ]
 60        queryset_order = ["-pk"]
 61        allow_global_search = False
 62        displays = ["Parents only"]
 63        search_fields = ["name", "span_id", "parent_id"]
 64
 65        def get_objects(self):
 66            return (
 67                super()
 68                .get_objects()
 69                .only(
 70                    "name",
 71                    "kind",
 72                    "span_id",
 73                    "parent_id",
 74                    "start_time",
 75                )
 76            )
 77
 78        def get_initial_queryset(self):
 79            queryset = super().get_initial_queryset()
 80            if self.display == "Parents only":
 81                queryset = queryset.filter(parent_id="")
 82            return queryset
 83
 84    class DetailView(AdminModelDetailView):
 85        model = Span
 86
 87
 88@register_toolbar_panel
 89class ObserverToolbarPanel(ToolbarPanel):
 90    name = "Observer"
 91    template_name = "toolbar/observer.html"
 92    button_template_name = "toolbar/observer_button.html"
 93
 94    @cached_property
 95    def observer(self):
 96        """Get the Observer instance for this request."""
 97        return Observer(self.request)
 98
 99    def get_template_context(self):
100        context = super().get_template_context()
101        context["observer"] = self.observer
102        return context