PyRunner / core /views /logs.py
Akoda35's picture
Upload 18 files
1f6c983 verified
Raw
History Blame Contribute Delete
3.91 kB
"""
Log viewer views for the control panel.
"""
import logging
from datetime import datetime
from django.contrib.auth.decorators import login_required
from django.http import HttpRequest, HttpResponse, JsonResponse
from django.shortcuts import render
from django.views.decorators.http import require_POST
from core.services.log_service import LogService
logger = logging.getLogger(__name__)
@login_required
def logs_view(request: HttpRequest) -> HttpResponse:
"""Display logs with filtering options."""
# Get filter parameters
level_filter = request.GET.get("level")
search_query = request.GET.get("search", "").strip()
date_from = request.GET.get("date_from")
date_to = request.GET.get("date_to")
page = int(request.GET.get("page", 1))
per_page = 100
# Parse dates
start_date = None
end_date = None
if date_from:
try:
start_date = datetime.fromisoformat(date_from)
except ValueError:
pass
if date_to:
try:
end_date = datetime.fromisoformat(date_to)
except ValueError:
pass
# Calculate offset
offset = (page - 1) * per_page
# Get filtered logs
entries, total_count = LogService.read_logs(
level_filter=level_filter if level_filter in LogService.LOG_LEVELS else None,
search_query=search_query if search_query else None,
start_date=start_date,
end_date=end_date,
limit=per_page,
offset=offset,
)
# Calculate pagination
total_pages = (total_count + per_page - 1) // per_page if total_count > 0 else 1
# Get log file stats
log_files = LogService.get_log_files()
total_size = LogService.get_log_file_size()
return render(
request,
"cpanel/logs.html",
{
"entries": entries,
"total_count": total_count,
"page": page,
"per_page": per_page,
"total_pages": total_pages,
"level_filter": level_filter,
"search_query": search_query,
"date_from": date_from,
"date_to": date_to,
"log_levels": LogService.LOG_LEVELS,
"log_files_count": len(log_files),
"total_size": total_size,
},
)
@login_required
def logs_api_view(request: HttpRequest) -> JsonResponse:
"""API endpoint for real-time log updates."""
lines = int(request.GET.get("lines", 50))
lines = min(lines, 200) # Cap at 200 for performance
entries = LogService.tail_logs(lines=lines)
return JsonResponse(
{
"success": True,
"entries": [
{
"timestamp": entry.timestamp.isoformat(),
"level": entry.level,
"logger": entry.logger,
"message": entry.message,
"exception": entry.exception,
}
for entry in entries
],
}
)
@login_required
@require_POST
def logs_clear_view(request: HttpRequest) -> JsonResponse:
"""Clear all log files (superuser only)."""
if not request.user.is_superuser:
return JsonResponse(
{
"success": False,
"error": "Permission denied. Only administrators can clear logs.",
},
status=403,
)
try:
bytes_freed = LogService.clear_logs()
logger.info(f"Logs cleared by {request.user.email}, freed {bytes_freed} bytes")
return JsonResponse(
{
"success": True,
"message": f"Logs cleared. Freed {bytes_freed:,} bytes.",
}
)
except Exception as e:
logger.exception("Failed to clear logs")
return JsonResponse(
{
"success": False,
"error": str(e),
}
)