All checks were successful
Deploy Plane Project Tracker / Deploy to cisystem (push) Successful in 6m47s
60 lines
1.9 KiB
Python
60 lines
1.9 KiB
Python
# Copyright (c) 2023-present Plane Software, Inc. and contributors
|
|
# SPDX-License-Identifier: AGPL-3.0-only
|
|
# See the LICENSE file for details.
|
|
|
|
import json
|
|
import logging
|
|
|
|
from rest_framework import status
|
|
from rest_framework.permissions import AllowAny
|
|
from rest_framework.response import Response
|
|
from rest_framework.views import APIView
|
|
|
|
from plane.utils.ip_address import get_client_ip
|
|
|
|
client_logger = logging.getLogger("plane.client")
|
|
|
|
|
|
class ClientLogsEndpoint(APIView):
|
|
"""
|
|
Receives frontend client-side errors and user action telemetry from the browser
|
|
and writes them into the server logs for easy debugging.
|
|
"""
|
|
|
|
permission_classes = [AllowAny]
|
|
|
|
def post(self, request):
|
|
try:
|
|
if request.content_type and "application/json" in request.content_type:
|
|
data = request.data
|
|
else:
|
|
data = json.loads(request.body.decode("utf-8")) if request.body else {}
|
|
except Exception:
|
|
data = {"raw": str(request.body)[:1000]}
|
|
|
|
user_id = (
|
|
request.user.id
|
|
if getattr(request, "user") and getattr(request.user, "is_authenticated", False)
|
|
else None
|
|
)
|
|
|
|
log_type = data.get("type", "error")
|
|
message = data.get("message", "Client event")
|
|
url = data.get("url", "")
|
|
stack = data.get("stack", "")
|
|
|
|
client_logger.info(
|
|
f"[Frontend {log_type.upper()}] {message} - URL: {url}",
|
|
extra={
|
|
"source": "frontend",
|
|
"type": log_type,
|
|
"message": message,
|
|
"stack": stack,
|
|
"url": url,
|
|
"user_id": str(user_id) if user_id else None,
|
|
"ip": get_client_ip(request),
|
|
"user_agent": request.META.get("HTTP_USER_AGENT", ""),
|
|
"extra": data.get("extra", {}),
|
|
},
|
|
)
|
|
return Response({"status": "ok"}, status=status.HTTP_200_OK)
|