mirror of
https://gitlab.com/allianceauth/allianceauth.git
synced 2025-07-09 12:30:15 +02:00
Docker/Baremetal Analytics
This commit is contained in:
parent
7033406ba6
commit
3efdb8f12b
@ -1,15 +1,16 @@
|
|||||||
from django.contrib import admin
|
from django.contrib import admin
|
||||||
|
|
||||||
from .models import AnalyticsIdentifier, AnalyticsTokens
|
from .models import AnalyticsIdentifier, AnalyticsTokens
|
||||||
|
from solo.admin import SingletonModelAdmin
|
||||||
|
|
||||||
|
|
||||||
@admin.register(AnalyticsIdentifier)
|
@admin.register(AnalyticsIdentifier)
|
||||||
class AnalyticsIdentifierAdmin(admin.ModelAdmin):
|
class AnalyticsIdentifierAdmin(SingletonModelAdmin):
|
||||||
search_fields = ['identifier', ]
|
search_fields = ['identifier', ]
|
||||||
list_display = ('identifier',)
|
list_display = ['identifier', ]
|
||||||
|
|
||||||
|
|
||||||
@admin.register(AnalyticsTokens)
|
@admin.register(AnalyticsTokens)
|
||||||
class AnalyticsTokensAdmin(admin.ModelAdmin):
|
class AnalyticsTokensAdmin(admin.ModelAdmin):
|
||||||
search_fields = ['name', ]
|
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.db import models
|
||||||
from django.core.exceptions import ValidationError
|
|
||||||
from django.utils.translation import gettext_lazy as _
|
from django.utils.translation import gettext_lazy as _
|
||||||
|
from solo.models import SingletonModel
|
||||||
from uuid import uuid4
|
from uuid import uuid4
|
||||||
|
|
||||||
|
|
||||||
class AnalyticsIdentifier(models.Model):
|
class AnalyticsIdentifier(SingletonModel):
|
||||||
|
|
||||||
identifier = models.UUIDField(
|
identifier = models.UUIDField(default=uuid4, editable=False)
|
||||||
default=uuid4,
|
|
||||||
editable=False)
|
|
||||||
|
|
||||||
def save(self, *args, **kwargs):
|
def __str__(self) -> Literal['Analytics Identifier']:
|
||||||
if not self.pk and AnalyticsIdentifier.objects.exists():
|
return "Analytics Identifier"
|
||||||
# Force a single object
|
|
||||||
raise ValidationError('There is can be only one \
|
class Meta:
|
||||||
AnalyticsIdentifier instance')
|
verbose_name = "Analytics Identifier"
|
||||||
self.pk = self.id = 1 # If this happens to be deleted and recreated, force it to be 1
|
|
||||||
return super().save(*args, **kwargs)
|
|
||||||
|
|
||||||
|
|
||||||
class AnalyticsTokens(models.Model):
|
class AnalyticsTokens(models.Model):
|
||||||
|
@ -5,6 +5,7 @@ from django.apps import apps
|
|||||||
from celery import shared_task
|
from celery import shared_task
|
||||||
from .models import AnalyticsTokens, AnalyticsIdentifier
|
from .models import AnalyticsTokens, AnalyticsIdentifier
|
||||||
from .utils import (
|
from .utils import (
|
||||||
|
existence_baremetal_or_docker,
|
||||||
install_stat_addons,
|
install_stat_addons,
|
||||||
install_stat_tokens,
|
install_stat_tokens,
|
||||||
install_stat_users)
|
install_stat_users)
|
||||||
@ -67,8 +68,8 @@ def analytics_event(namespace: str,
|
|||||||
value=value).apply_async(priority=9)
|
value=value).apply_async(priority=9)
|
||||||
|
|
||||||
|
|
||||||
@shared_task()
|
@shared_task
|
||||||
def analytics_daily_stats():
|
def analytics_daily_stats() -> None:
|
||||||
"""Celery Task: Do not call directly
|
"""Celery Task: Do not call directly
|
||||||
|
|
||||||
Gathers a series of daily statistics
|
Gathers a series of daily statistics
|
||||||
@ -77,6 +78,7 @@ def analytics_daily_stats():
|
|||||||
users = install_stat_users()
|
users = install_stat_users()
|
||||||
tokens = install_stat_tokens()
|
tokens = install_stat_tokens()
|
||||||
addons = install_stat_addons()
|
addons = install_stat_addons()
|
||||||
|
existence_type = existence_baremetal_or_docker()
|
||||||
logger.debug("Running Daily Analytics Upload")
|
logger.debug("Running Daily Analytics Upload")
|
||||||
|
|
||||||
analytics_event(namespace='allianceauth.analytics',
|
analytics_event(namespace='allianceauth.analytics',
|
||||||
@ -84,6 +86,11 @@ def analytics_daily_stats():
|
|||||||
label='existence',
|
label='existence',
|
||||||
value=1,
|
value=1,
|
||||||
event_type='Stats')
|
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',
|
analytics_event(namespace='allianceauth.analytics',
|
||||||
task='send_install_stats',
|
task='send_install_stats',
|
||||||
label='users',
|
label='users',
|
||||||
@ -99,7 +106,6 @@ def analytics_daily_stats():
|
|||||||
label='addons',
|
label='addons',
|
||||||
value=addons,
|
value=addons,
|
||||||
event_type='Stats')
|
event_type='Stats')
|
||||||
|
|
||||||
for appconfig in apps.get_app_configs():
|
for appconfig in apps.get_app_configs():
|
||||||
if appconfig.label in [
|
if appconfig.label in [
|
||||||
"django_celery_beat",
|
"django_celery_beat",
|
||||||
@ -135,7 +141,7 @@ def analytics_daily_stats():
|
|||||||
event_type='Stats')
|
event_type='Stats')
|
||||||
|
|
||||||
|
|
||||||
@shared_task()
|
@shared_task
|
||||||
def send_ga_tracking_celery_event(
|
def send_ga_tracking_celery_event(
|
||||||
measurement_id: str,
|
measurement_id: str,
|
||||||
secret: str,
|
secret: str,
|
||||||
@ -165,7 +171,7 @@ def send_ga_tracking_celery_event(
|
|||||||
}
|
}
|
||||||
|
|
||||||
payload = {
|
payload = {
|
||||||
'client_id': AnalyticsIdentifier.objects.get(id=1).identifier.hex,
|
'client_id': AnalyticsIdentifier.get_solo().identifier.hex,
|
||||||
"user_properties": {
|
"user_properties": {
|
||||||
"allianceauth_version": {
|
"allianceauth_version": {
|
||||||
"value": __version__
|
"value": __version__
|
||||||
|
@ -1,9 +1,8 @@
|
|||||||
from allianceauth.analytics.models import AnalyticsIdentifier
|
from allianceauth.analytics.models import AnalyticsIdentifier
|
||||||
from django.core.exceptions import ValidationError
|
|
||||||
|
|
||||||
from django.test.testcases import TestCase
|
from django.test.testcases import TestCase
|
||||||
|
|
||||||
from uuid import UUID, uuid4
|
from uuid import uuid4
|
||||||
|
|
||||||
|
|
||||||
# Identifiers
|
# Identifiers
|
||||||
@ -14,14 +13,4 @@ uuid_2 = "7aa6bd70701f44729af5e3095ff4b55c"
|
|||||||
class TestAnalyticsIdentifier(TestCase):
|
class TestAnalyticsIdentifier(TestCase):
|
||||||
|
|
||||||
def test_identifier_random(self):
|
def test_identifier_random(self):
|
||||||
self.assertNotEqual(AnalyticsIdentifier.objects.get(), uuid4)
|
self.assertNotEqual(AnalyticsIdentifier.get_solo(), 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))
|
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
import os
|
||||||
from django.apps import apps
|
from django.apps import apps
|
||||||
from allianceauth.authentication.models import User
|
from allianceauth.authentication.models import User
|
||||||
from esi.models import Token
|
from esi.models import Token
|
||||||
@ -34,3 +35,16 @@ def install_stat_addons() -> int:
|
|||||||
The Number of Installed Apps"""
|
The Number of Installed Apps"""
|
||||||
addons = len(list(apps.get_app_configs()))
|
addons = len(list(apps.get_app_configs()))
|
||||||
return addons
|
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:
|
Our Daily Stats contain the following:
|
||||||
|
|
||||||
- A phone-in task to identify a server's existence
|
- 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 User models
|
||||||
- A task to send the Number of Token Models
|
- A task to send the Number of Token Models
|
||||||
- A task to send the Number of Installed Apps
|
- A task to send the Number of Installed Apps
|
||||||
|
Loading…
x
Reference in New Issue
Block a user