diff --git a/cvat/apps/events/event.py b/cvat/apps/events/event.py index 9f3f31fbda38..361bd19984a2 100644 --- a/cvat/apps/events/event.py +++ b/cvat/apps/events/event.py @@ -4,6 +4,9 @@ from rest_framework.renderers import JSONRenderer from datetime import datetime, timezone +from typing import Optional + +from cvat.apps.engine.log import vlogger def event_scope(action, resource): return f"{action}:{resource}" @@ -31,22 +34,33 @@ def select(cls, resources): for action in cls.RESOURCES.get(resource, []) ] -def create_event(scope, - source, - **kwargs): - payload = kwargs.pop('payload', {}) - timestamp = kwargs.pop('timestamp', str(datetime.now(timezone.utc).timestamp())) +def record_server_event( + *, + scope: str, + request_id: Optional[str], + payload: Optional[dict] = None, + **kwargs, +) -> None: + payload = payload or {} + + payload_with_request_id = { + **payload, + "request": { + **payload.get("request", {}), + "id": request_id, + }, + } data = { "scope": scope, - "timestamp": timestamp, - "source": source, + "timestamp": str(datetime.now(timezone.utc).timestamp()), + "source": "server", + "payload": JSONRenderer().render(payload_with_request_id).decode('UTF-8'), **kwargs, } - if payload: - data["payload"] = JSONRenderer().render(payload).decode('UTF-8') - return data + vlogger.info(JSONRenderer().render(data).decode('UTF-8')) + class EventScopeChoice: @classmethod diff --git a/cvat/apps/events/handlers.py b/cvat/apps/events/handlers.py index e125869c80c4..9617410bb70d 100644 --- a/cvat/apps/events/handlers.py +++ b/cvat/apps/events/handlers.py @@ -3,11 +3,9 @@ # SPDX-License-Identifier: MIT from copy import deepcopy -from datetime import datetime, timezone import traceback import rq -from rest_framework.renderers import JSONRenderer from rest_framework.views import exception_handler from rest_framework import status from crum import get_current_user, get_current_request @@ -35,9 +33,8 @@ from cvat.apps.engine.models import ShapeType from cvat.apps.organizations.models import Membership, Organization, Invitation from cvat.apps.organizations.serializers import OrganizationReadSerializer, MembershipReadSerializer, InvitationReadSerializer -from cvat.apps.engine.log import vlogger -from .event import event_scope, create_event +from .event import event_scope, record_server_event from .cache import get_cache def project_id(instance): @@ -263,16 +260,6 @@ def get_serializer_without_url(instance): serializer.fields.pop("url", None) return serializer -def set_request_id(payload=None, **kwargs): - _payload = payload or {} - return { - **_payload, - "request": { - **_payload.get("request", {}), - "id": request_id(**kwargs), - }, - } - def handle_create(scope, instance, **kwargs): oid = organization_id(instance) oslug = organization_slug(instance) @@ -290,11 +277,11 @@ def handle_create(scope, instance, **kwargs): payload = {} payload = _cleanup_fields(obj=payload) - event = create_event( + record_server_event( scope=scope, + request_id=request_id(), obj_id=getattr(instance, 'id', None), obj_name=_get_object_name(instance), - source='server', org_id=oid, org_slug=oslug, project_id=pid, @@ -303,11 +290,8 @@ def handle_create(scope, instance, **kwargs): user_id=uid, user_name=uname, user_email=uemail, - payload=set_request_id(payload), + payload=payload, ) - message = JSONRenderer().render(event).decode('UTF-8') - - vlogger.info(message) def handle_update(scope, instance, old_instance, **kwargs): oid = organization_id(instance) @@ -323,16 +307,14 @@ def handle_update(scope, instance, old_instance, **kwargs): serializer = get_serializer_without_url(instance=instance) diff = get_instance_diff(old_data=old_serializer.data, data=serializer.data) - timestamp = str(datetime.now(timezone.utc).timestamp()) for prop, change in diff.items(): change = _cleanup_fields(change) - event = create_event( + record_server_event( scope=scope, - timestamp=timestamp, + request_id=request_id(), obj_name=prop, obj_id=getattr(instance, f'{prop}_id', None), obj_val=str(change["new_value"]), - source='server', org_id=oid, org_slug=oslug, project_id=pid, @@ -341,14 +323,9 @@ def handle_update(scope, instance, old_instance, **kwargs): user_id=uid, user_name=uname, user_email=uemail, - payload=set_request_id({ - "old_value": change["old_value"], - }), + payload={"old_value": change["old_value"]}, ) - message = JSONRenderer().render(event).decode('UTF-8') - vlogger.info(message) - def handle_delete(scope, instance, store_in_deletion_cache=False, **kwargs): deletion_cache = get_cache() if store_in_deletion_cache: @@ -383,11 +360,11 @@ def handle_delete(scope, instance, store_in_deletion_cache=False, **kwargs): uname = user_name(instance) uemail = user_email(instance) - event = create_event( + record_server_event( scope=scope, + request_id=request_id(), obj_id=getattr(instance, 'id', None), obj_name=_get_object_name(instance), - source='server', org_id=oid, org_slug=oslug, project_id=pid, @@ -396,11 +373,7 @@ def handle_delete(scope, instance, store_in_deletion_cache=False, **kwargs): user_id=uid, user_name=uname, user_email=uemail, - payload=set_request_id(), ) - message = JSONRenderer().render(event).decode('UTF-8') - - vlogger.info(message) def handle_annotations_change(instance, annotations, action, **kwargs): _annotations = deepcopy(annotations) @@ -428,9 +401,9 @@ def filter_shape_data(shape): tags = [filter_shape_data(tag) for tag in _annotations.get("tags", [])] if tags: - event = create_event( + record_server_event( scope=event_scope(action, "tags"), - source='server', + request_id=request_id(), count=len(tags), org_id=oid, org_slug=oslug, @@ -440,12 +413,8 @@ def filter_shape_data(shape): user_id=uid, user_name=uname, user_email=uemail, - payload=set_request_id({ - "tags": tags, - }), + payload={"tags": tags}, ) - message = JSONRenderer().render(event).decode('UTF-8') - vlogger.info(message) shapes_by_type = {shape_type[0]: [] for shape_type in ShapeType.choices()} for shape in _annotations.get("shapes", []): @@ -454,10 +423,10 @@ def filter_shape_data(shape): scope = event_scope(action, "shapes") for shape_type, shapes in shapes_by_type.items(): if shapes: - event = create_event( + record_server_event( scope=scope, + request_id=request_id(), obj_name=shape_type, - source='server', count=len(shapes), org_id=oid, org_slug=oslug, @@ -467,12 +436,8 @@ def filter_shape_data(shape): user_id=uid, user_name=uname, user_email=uemail, - payload=set_request_id({ - "shapes": shapes, - }), + payload={"shapes": shapes}, ) - message = JSONRenderer().render(event).decode('UTF-8') - vlogger.info(message) tracks_by_type = {shape_type[0]: [] for shape_type in ShapeType.choices()} for track in _annotations.get("tracks", []): @@ -486,10 +451,10 @@ def filter_shape_data(shape): scope = event_scope(action, "tracks") for track_type, tracks in tracks_by_type.items(): if tracks: - event = create_event( + record_server_event( scope=scope, + request_id=request_id(), obj_name=track_type, - source='server', count=len(tracks), org_id=oid, org_slug=oslug, @@ -499,12 +464,8 @@ def filter_shape_data(shape): user_id=uid, user_name=uname, user_email=uemail, - payload=set_request_id({ - "tracks": tracks, - }), + payload={"tracks": tracks}, ) - message = JSONRenderer().render(event).decode('UTF-8') - vlogger.info(message) def handle_rq_exception(rq_job, exc_type, exc_value, tb): oid = rq_job.meta.get("org_id", None) @@ -522,9 +483,9 @@ def handle_rq_exception(rq_job, exc_type, exc_value, tb): "stack": ''.join(tb_strings), } - event = create_event( + record_server_event( scope="send:exception", - source='server', + request_id=request_id(instance=rq_job), count=1, org_id=oid, org_slug=oslug, @@ -534,10 +495,8 @@ def handle_rq_exception(rq_job, exc_type, exc_value, tb): user_id=uid, user_name=uname, user_email=uemail, - payload=set_request_id(payload, instance=rq_job), + payload=payload, ) - message = JSONRenderer().render(event).decode('UTF-8') - vlogger.info(message) return False @@ -568,17 +527,14 @@ def handle_viewset_exception(exc, context): "status_code": status_code, } - event = create_event( + record_server_event( scope="send:exception", - source='server', + request_id=request_id(), count=1, user_id=getattr(request.user, "id", None), user_name=getattr(request.user, "username", None), user_email=getattr(request.user, "email", None), - payload=set_request_id(payload), + payload=payload, ) - message = JSONRenderer().render(event).decode('UTF-8') - vlogger.info(message) - return response