From 4cc1b79d81f23b51d6200758e501d0595ed4902b Mon Sep 17 00:00:00 2001 From: pablohashescobar Date: Fri, 4 Oct 2024 21:35:13 +0530 Subject: [PATCH] chore: instance tracing --- apiserver/plane/license/bgtasks/tracer.py | 96 +++++++++++++++++++ .../management/commands/register_instance.py | 73 +++++--------- apiserver/plane/settings/common.py | 1 + apiserver/plane/utils/tracer.py | 26 ----- 4 files changed, 121 insertions(+), 75 deletions(-) create mode 100644 apiserver/plane/license/bgtasks/tracer.py delete mode 100644 apiserver/plane/utils/tracer.py diff --git a/apiserver/plane/license/bgtasks/tracer.py b/apiserver/plane/license/bgtasks/tracer.py new file mode 100644 index 000000000..f350e9a45 --- /dev/null +++ b/apiserver/plane/license/bgtasks/tracer.py @@ -0,0 +1,96 @@ +# Third party imports +from celery import shared_task +from opentelemetry import trace + +# Module imports +from plane.license.models import Instance +from plane.db.models import ( + User, + Workspace, + Project, + Issue, + Module, + Cycle, + CycleIssue, + ModuleIssue, + Page, + WorkspaceMember, +) + + +@shared_task +def instance_traces(): + # Get the tracer + tracer = trace.get_tracer(__name__) + + # Check if the instance is registered + instance = Instance.objects.first() + + # If instance is None then return + if instance is None: + return + + if instance.is_telemetry_enabled: + # Instance details + with tracer.start_as_current_span("instance_details") as span: + # Count of all models + workspace_count = Workspace.objects.count() + user_count = User.objects.count() + project_count = Project.objects.count() + issue_count = Issue.objects.count() + module_count = Module.objects.count() + cycle_count = Cycle.objects.count() + cycle_issue_count = CycleIssue.objects.count() + module_issue_count = ModuleIssue.objects.count() + page_count = Page.objects.count() + + # Set span attributes + span.set_attribute("instance_id", instance.instance_id) + span.set_attribute("instance_name", instance.instance_name) + span.set_attribute("current_version", instance.current_version) + span.set_attribute("latest_version", instance.latest_version) + span.set_attribute( + "is_telemetry_enabled", instance.is_telemetry_enabled + ) + span.set_attribute("user_count", user_count) + span.set_attribute("workspace_count", workspace_count) + span.set_attribute("project_count", project_count) + span.set_attribute("issue_count", issue_count) + span.set_attribute("module_count", module_count) + span.set_attribute("cycle_count", cycle_count) + span.set_attribute("cycle_issue_count", cycle_issue_count) + span.set_attribute("module_issue_count", module_issue_count) + span.set_attribute("page_count", page_count) + + # Workspace details + for workspace in Workspace.objects.all(): + # Count of all models + project_count = Project.objects.filter(workspace=workspace).count() + issue_count = Issue.objects.filter(workspace=workspace).count() + module_count = Module.objects.filter(workspace=workspace).count() + cycle_count = Cycle.objects.filter(workspace=workspace).count() + cycle_issue_count = CycleIssue.objects.filter( + workspace=workspace + ).count() + module_issue_count = ModuleIssue.objects.filter( + workspace=workspace + ).count() + page_count = Page.objects.filter(workspace=workspace).count() + member_count = WorkspaceMember.objects.filter( + workspace=workspace + ).count() + + # Set span attributes + with tracer.start_as_current_span("workspace_details") as span: + span.set_attribute("workspace_id", str(workspace.id)) + span.set_attribute("workspace_slug", workspace.slug) + span.set_attribute("project_count", project_count) + span.set_attribute("issue_count", issue_count) + span.set_attribute("module_count", module_count) + span.set_attribute("cycle_count", cycle_count) + span.set_attribute("cycle_issue_count", cycle_issue_count) + span.set_attribute("module_issue_count", module_issue_count) + span.set_attribute("page_count", page_count) + span.set_attribute("member_count", member_count) + + return diff --git a/apiserver/plane/license/management/commands/register_instance.py b/apiserver/plane/license/management/commands/register_instance.py index 314d47520..09d13441c 100644 --- a/apiserver/plane/license/management/commands/register_instance.py +++ b/apiserver/plane/license/management/commands/register_instance.py @@ -11,19 +11,8 @@ from django.conf import settings from plane.license.models import Instance from plane.db.models import ( User, - Workspace, - Project, - Issue, - Module, - Cycle, - CycleIssue, - ModuleIssue, - Page, ) - -from opentelemetry import trace - -tracer = trace.get_tracer(__name__) +from plane.license.bgtasks.tracer import instance_traces class Command(BaseCommand): @@ -35,16 +24,24 @@ class Command(BaseCommand): "machine_signature", type=str, help="Machine signature" ) + def read_package_json(self): + with open("package.json", "r") as file: + # Load JSON content from the file + data = json.load(file) + + payload = { + "instance_key": settings.INSTANCE_KEY, + "version": data.get("version", 0.1), + "user_count": User.objects.filter(is_bot=False).count(), + } + return payload + def handle(self, *args, **options): # Check if the instance is registered instance = Instance.objects.first() # If instance is None then register this instance if instance is None: - with open("package.json", "r") as file: - # Load JSON content from the file - data = json.load(file) - machine_signature = options.get( "machine_signature", "machine-signature" ) @@ -52,12 +49,7 @@ class Command(BaseCommand): if not machine_signature: raise CommandError("Machine signature is required") - payload = { - "instance_key": settings.INSTANCE_KEY, - "version": data.get("version", 0.1), - "machine_signature": machine_signature, - "user_count": User.objects.filter(is_bot=False).count(), - } + payload = self.read_package_json() instance = Instance.objects.create( instance_name="Plane Community Edition", @@ -74,32 +66,15 @@ class Command(BaseCommand): self.stdout.write( self.style.SUCCESS("Instance already registered") ) + payload = self.read_package_json() + # Update the instance details + instance.last_checked_at = timezone.now() + instance.user_count = payload.get("user_count", 0) + instance.current_version = payload.get("version") + instance.latest_version = payload.get("version") + instance.save() - if instance.is_telemetry_enabled: - with tracer.start_as_current_span("instance_details") as span: - workspace_count = Workspace.objects.count() - user_count = User.objects.count() - project_count = Project.objects.count() - issue_count = Issue.objects.count() - module_count = Module.objects.count() - cycle_count = Cycle.objects.count() - cycle_issue_count = CycleIssue.objects.count() - module_issue_count = ModuleIssue.objects.count() - page_count = Page.objects.count() + # Call the instance traces task + instance_traces.delay() - span.set_attribute("instance_id", instance.instance_id) - span.set_attribute("instance_name", instance.instance_name) - span.set_attribute("current_version", instance.current_version) - span.set_attribute("latest_version", instance.latest_version) - span.set_attribute( - "is_telemetry_enabled", instance.is_telemetry_enabled - ) - span.set_attribute("user_count", user_count) - span.set_attribute("workspace_count", workspace_count) - span.set_attribute("project_count", project_count) - span.set_attribute("issue_count", issue_count) - span.set_attribute("module_count", module_count) - span.set_attribute("cycle_count", cycle_count) - span.set_attribute("cycle_issue_count", cycle_issue_count) - span.set_attribute("module_issue_count", module_issue_count) - span.set_attribute("page_count", page_count) + return diff --git a/apiserver/plane/settings/common.py b/apiserver/plane/settings/common.py index 2504cc3e3..5e1ea39a4 100644 --- a/apiserver/plane/settings/common.py +++ b/apiserver/plane/settings/common.py @@ -303,6 +303,7 @@ CELERY_IMPORTS = ( "plane.bgtasks.file_asset_task", "plane.bgtasks.email_notification_task", "plane.bgtasks.api_logs_task", + "plane.license.bgtasks.tracer", # management tasks "plane.bgtasks.dummy_data_task", ) diff --git a/apiserver/plane/utils/tracer.py b/apiserver/plane/utils/tracer.py deleted file mode 100644 index 831472cbf..000000000 --- a/apiserver/plane/utils/tracer.py +++ /dev/null @@ -1,26 +0,0 @@ -from opentelemetry import trace -from django.conf import settings -from functools import wraps - -tracer = trace.get_tracer(__name__) - - -def trace_operation(operation_name, **attributes): - def wrapper(func): - @wraps(func) - def traced_func(*args, **kwargs): - if settings.TELEMETRY_ENABLED: - with tracer.start_as_current_span(operation_name) as span: - for key, value in attributes.items(): - span.set_attribute(key, value) - result = func(*args, **kwargs) - span.add_event( - "operation_completed", {"result": str(result)} - ) - return result - else: - return func(*args, **kwargs) - - return traced_func - - return wrapper