92 lines
4.4 KiB
Python
92 lines
4.4 KiB
Python
from rest_framework import viewsets, permissions, status
|
|
from rest_framework.response import Response
|
|
from rest_framework.decorators import action
|
|
from django.db.models import Avg, Count, Q
|
|
from django.utils import timezone
|
|
from datetime import timedelta
|
|
|
|
from api.models import InferenceAuditLog
|
|
from api.serializers.audit_serializer import InferenceAuditLogSerializer
|
|
# นำเข้า Permission ที่จำเป็น
|
|
from permissions.permission_classes import IsAdminOrOperator, IsViewerOrHigher
|
|
|
|
from drf_spectacular.utils import extend_schema, extend_schema_view
|
|
|
|
@extend_schema_view(
|
|
list=extend_schema(tags=['2. Application Service']),
|
|
get_summary=extend_schema(tags=['2. Application Service']),
|
|
retrieve=extend_schema(tags=['2. Application Service']),
|
|
)
|
|
class AuditLogViewSet(viewsets.ReadOnlyModelViewSet):
|
|
"""
|
|
API สำหรับการเข้าถึง Inference Audit Log และสถิติรวม (รวมการดึง Summary ด้วย)
|
|
"""
|
|
queryset = InferenceAuditLog.objects.all()
|
|
serializer_class = InferenceAuditLogSerializer
|
|
permission_classes = [permissions.IsAuthenticated]
|
|
|
|
lookup_field = 'id'
|
|
lookup_url_kwarg = 'id'
|
|
|
|
def retrieve(self, request, *args, **kwargs):
|
|
# บังคับให้ Lookup Key (pk) เป็น String
|
|
kwargs[self.lookup_url_kwarg] = str(kwargs[self.lookup_url_kwarg])
|
|
return super().retrieve(request, *args, **kwargs)
|
|
|
|
def get_queryset(self):
|
|
# คืน Log ล่าสุด 10 รายการ (สำหรับ Recent Events ใน Dashboard)
|
|
return self.queryset.select_related('user').order_by('-timestamp')[:10] # 📌 เพิ่ม order_by เพื่อให้ได้ล่าสุดจริง ๆ
|
|
|
|
# -----------------------------------------------
|
|
# Custom Action: ดึงสถิติรวม Dynamic (สำหรับ Viewer, Operator, Admin)
|
|
# Endpoint: GET /api/v1/audit/summary/
|
|
# -----------------------------------------------
|
|
@action(
|
|
detail=False,
|
|
methods=['get'],
|
|
url_path='summary',
|
|
# อนุญาตให้เข้าถึงสำหรับทุก Role ใน Dashboard
|
|
permission_classes=[IsViewerOrHigher]
|
|
)
|
|
def get_summary(self, request):
|
|
user = request.user
|
|
|
|
# 1. ตรวจสอบ Role เพื่อกำหนดขอบเขตข้อมูลที่จะแสดง (Dynamic View)
|
|
# ตรวจสอบว่าผู้ใช้เป็น ADMIN หรือ OPERATOR หรือไม่
|
|
is_high_privilege = user.role in ['ADMIN', 'OPERATOR']
|
|
|
|
# กำหนดขีดจำกัดและข้อมูลที่จะรวม
|
|
log_limit = 10 if is_high_privilege else 5
|
|
include_latency = is_high_privilege # Latency เป็นข้อมูลเชิงเทคนิค
|
|
|
|
one_day_ago = timezone.now() - timedelta(hours=24)
|
|
queryset = self.queryset.filter(timestamp__gte=one_day_ago)
|
|
|
|
# 2. คำนวณสถิติพื้นฐาน (ใช้ร่วมกัน)
|
|
metrics = queryset.aggregate(
|
|
total_runs=Count('id'),
|
|
success_count=Count('id', filter=Q(is_success=True)),
|
|
# คำนวณ Avg Latency เฉพาะถ้าผู้ใช้มีสิทธิ์สูง
|
|
avg_latency_ms=Avg('latency_ms') if include_latency else None
|
|
)
|
|
|
|
# 3. คำนวณ Success Rate
|
|
total = metrics.get('total_runs', 0)
|
|
success = metrics.get('success_count', 0)
|
|
success_rate = (success / total) * 100 if total > 0 else 0
|
|
|
|
# 4. ดึง Log ล่าสุดตามสิทธิ์
|
|
last_logs = self.queryset.select_related('user').order_by('-timestamp')[:log_limit]
|
|
|
|
response_data = {
|
|
"time_window": "24 hours",
|
|
"total_runs": total,
|
|
"success_rate": round(success_rate, 2),
|
|
"last_logs": InferenceAuditLogSerializer(last_logs, many=True).data
|
|
}
|
|
|
|
# 5. เพิ่ม Latency เข้าไปใน Response เฉพาะ Role ที่มีสิทธิ์สูง
|
|
if include_latency:
|
|
response_data['avg_latency_ms'] = round(metrics.get('avg_latency_ms', 0) or 0, 2)
|
|
|
|
return Response(response_data) |