mirror of
https://gitlab.com/allianceauth/allianceauth.git
synced 2025-07-08 20:10:17 +02:00
Docker/Baremetal Analytics
This commit is contained in:
parent
7033406ba6
commit
3efdb8f12b
@ -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', ]
|
||||
|
@ -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'},
|
||||
),
|
||||
]
|
@ -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):
|
||||
|
@ -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__
|
||||
|
@ -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)
|
||||
|
@ -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"
|
||||
|
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user