Docker/Baremetal Analytics

This commit is contained in:
Ariel Rin 2025-01-10 08:29:02 +00:00
parent 7033406ba6
commit 3efdb8f12b
7 changed files with 58 additions and 34 deletions

View File

@ -1,15 +1,16 @@
from django.contrib import admin
from .models import AnalyticsIdentifier, AnalyticsTokens
from solo.admin import SingletonModelAdmin
@admin.register(AnalyticsIdentifier)
class AnalyticsIdentifierAdmin(admin.ModelAdmin):
class AnalyticsIdentifierAdmin(SingletonModelAdmin):
search_fields = ['identifier', ]
list_display = ('identifier',)
list_display = ['identifier', ]
@admin.register(AnalyticsTokens)
class AnalyticsTokensAdmin(admin.ModelAdmin):
search_fields = ['name', ]
list_display = ('name', 'type',)
list_display = ['name', 'type', ]

View File

@ -0,0 +1,17 @@
# Generated by Django 4.2.16 on 2024-12-11 02:17
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('analytics', '0009_remove_analyticstokens_ignore_paths_and_more'),
]
operations = [
migrations.AlterModelOptions(
name='analyticsidentifier',
options={'verbose_name': 'Analytics Identifier'},
),
]

View File

@ -1,23 +1,19 @@
from typing import Literal
from django.db import models
from django.core.exceptions import ValidationError
from django.utils.translation import gettext_lazy as _
from solo.models import SingletonModel
from uuid import uuid4
class AnalyticsIdentifier(models.Model):
class AnalyticsIdentifier(SingletonModel):
identifier = models.UUIDField(
default=uuid4,
editable=False)
identifier = models.UUIDField(default=uuid4, editable=False)
def save(self, *args, **kwargs):
if not self.pk and AnalyticsIdentifier.objects.exists():
# Force a single object
raise ValidationError('There is can be only one \
AnalyticsIdentifier instance')
self.pk = self.id = 1 # If this happens to be deleted and recreated, force it to be 1
return super().save(*args, **kwargs)
def __str__(self) -> Literal['Analytics Identifier']:
return "Analytics Identifier"
class Meta:
verbose_name = "Analytics Identifier"
class AnalyticsTokens(models.Model):

View File

@ -5,6 +5,7 @@ from django.apps import apps
from celery import shared_task
from .models import AnalyticsTokens, AnalyticsIdentifier
from .utils import (
existence_baremetal_or_docker,
install_stat_addons,
install_stat_tokens,
install_stat_users)
@ -67,8 +68,8 @@ def analytics_event(namespace: str,
value=value).apply_async(priority=9)
@shared_task()
def analytics_daily_stats():
@shared_task
def analytics_daily_stats() -> None:
"""Celery Task: Do not call directly
Gathers a series of daily statistics
@ -77,6 +78,7 @@ def analytics_daily_stats():
users = install_stat_users()
tokens = install_stat_tokens()
addons = install_stat_addons()
existence_type = existence_baremetal_or_docker()
logger.debug("Running Daily Analytics Upload")
analytics_event(namespace='allianceauth.analytics',
@ -84,6 +86,11 @@ def analytics_daily_stats():
label='existence',
value=1,
event_type='Stats')
analytics_event(namespace='allianceauth.analytics',
task='send_install_stats',
label=existence_type,
value=1,
event_type='Stats')
analytics_event(namespace='allianceauth.analytics',
task='send_install_stats',
label='users',
@ -99,7 +106,6 @@ def analytics_daily_stats():
label='addons',
value=addons,
event_type='Stats')
for appconfig in apps.get_app_configs():
if appconfig.label in [
"django_celery_beat",
@ -135,7 +141,7 @@ def analytics_daily_stats():
event_type='Stats')
@shared_task()
@shared_task
def send_ga_tracking_celery_event(
measurement_id: str,
secret: str,
@ -165,7 +171,7 @@ def send_ga_tracking_celery_event(
}
payload = {
'client_id': AnalyticsIdentifier.objects.get(id=1).identifier.hex,
'client_id': AnalyticsIdentifier.get_solo().identifier.hex,
"user_properties": {
"allianceauth_version": {
"value": __version__

View File

@ -1,9 +1,8 @@
from allianceauth.analytics.models import AnalyticsIdentifier
from django.core.exceptions import ValidationError
from django.test.testcases import TestCase
from uuid import UUID, uuid4
from uuid import uuid4
# Identifiers
@ -14,14 +13,4 @@ uuid_2 = "7aa6bd70701f44729af5e3095ff4b55c"
class TestAnalyticsIdentifier(TestCase):
def test_identifier_random(self):
self.assertNotEqual(AnalyticsIdentifier.objects.get(), uuid4)
def test_identifier_singular(self):
AnalyticsIdentifier.objects.all().delete()
AnalyticsIdentifier.objects.create(identifier=uuid_1)
# Yeah i have multiple asserts here, they all do the same thing
with self.assertRaises(ValidationError):
AnalyticsIdentifier.objects.create(identifier=uuid_2)
self.assertEqual(AnalyticsIdentifier.objects.count(), 1)
self.assertEqual(AnalyticsIdentifier.objects.get(
pk=1).identifier, UUID(uuid_1))
self.assertNotEqual(AnalyticsIdentifier.get_solo(), uuid4)

View File

@ -1,3 +1,4 @@
import os
from django.apps import apps
from allianceauth.authentication.models import User
from esi.models import Token
@ -34,3 +35,16 @@ def install_stat_addons() -> int:
The Number of Installed Apps"""
addons = len(list(apps.get_app_configs()))
return addons
def existence_baremetal_or_docker() -> str:
"""Checks the Installation Type of an install
Returns
-------
str
existence_baremetal or existence_docker"""
docker_tag = os.getenv('AA_DOCKER_TAG')
if docker_tag:
return "existence_docker"
return "existence_baremetal"

View File

@ -27,6 +27,7 @@ Analytics comes preloaded with our Google Analytics token, and the three types o
Our Daily Stats contain the following:
- A phone-in task to identify a server's existence
- A phone-in task to identify if a server is Bare-Metal or Dockerized
- A task to send the Number of User models
- A task to send the Number of Token Models
- A task to send the Number of Installed Apps