В этой статье мы рассмотрим, как создать собственную систему аналитики для веб-приложений, используя Django, PostgreSQL с расширением TimescaleDB и Chart.js для визуализации данных. Мы пройдем путь от настройки трекинга пользовательских действий до построения информативных дашбордов.
Зачем нужна собственная аналитическая система?
Собственная аналитика позволяет:
- Контролировать данные пользователей, обеспечивая их безопасность.
- Настраивать метрики под конкретные бизнес-задачи.
- Снижать затраты на сторонние сервисы, такие как Google Analytics.
- Интегрировать аналитику с внутренними системами.
Шаг 1: Настройка окружения
Для начала создадим проект на Django и подключим TimescaleDB для хранения временных рядов.
Установка зависимостей
Убедитесь, что у вас установлен PostgreSQL с расширением TimescaleDB. Для Django установите необходимые пакеты:
pip install django psycopg2-binary
Настройка базы данных
В файле settings.py добавьте конфигурацию для PostgreSQL:
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresql',
'NAME': 'analytics_db',
'USER': 'your_user',
'PASSWORD': 'your_password',
'HOST': 'localhost',
'PORT': '5432',
}
}
Создайте базу данных и включите расширение TimescaleDB:
CREATE DATABASE analytics_db;
CREATE EXTENSION IF NOT EXISTS timescaledb CASCADE;
Шаг 2: Модель для трекинга событий
Создадим модель для хранения событий. В файле models.py приложения добавьте:
from django.db import models
class Event(models.Model):
event_type = models.CharField(max_length=100)
user_id = models.IntegerField(null=True)
timestamp = models.DateTimeField(auto_now_add=True)
metadata = models.JSONField(default=dict)
class Meta:
indexes = [
models.Index(fields=['event_type']),
models.Index(fields=['timestamp']),
]
Преобразуем таблицу в гипертаблицу TimescaleDB для оптимизации работы с временными рядами:
SELECT create_hypertable('app_name_event', 'timestamp');
Шаг 3: Трекинг пользовательских действий
Создадим API-эндпоинт для записи событий. В views.py:
from django.http import JsonResponse
from .models import Event
from django.views.decorators.csrf import csrf_exempt
import json
@csrf_exempt
def track_event(request):
if request.method == 'POST':
data = json.loads(request.body)
Event.objects.create(
event_type=data.get('event_type'),
user_id=data.get('user_id'),
metadata=data.get('metadata', {})
)
return JsonResponse({'status': 'success'})
return JsonResponse({'status': 'error'}, status=400)
Добавьте URL в urls.py:
from django.urls import path
from . import views
urlpatterns = [
path('track/', views.track_event, name='track_event'),
]
На стороне клиента отправляйте события через JavaScript:
fetch('/track/', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
event_type: 'page_view',
user_id: 123,
metadata: { page: window.location.pathname }
})
});
Шаг 4: Агрегация данных
Для анализа данных создадим агрегирующие запросы. Например, подсчет событий по типу за день:
from django.db.models import Count
from django.utils import timezone
from datetime import timedelta
def get_daily_events():
end_time = timezone.now()
start_time = end_time - timedelta(days=1)
return Event.objects.filter(
timestamp__range=(start_time, end_time)
).values('event_type').annotate(count=Count('event_type'))
Шаг 5: Визуализация с Chart.js
Добавим дашборд с графиками. Подключите Chart.js в шаблоне Django:
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
<canvas id="eventsChart" width="400" height="200"></canvas>
<script>
fetch('/analytics/daily-events/')
.then(response => response.json())
.then(data => {
const ctx = document.getElementById('eventsChart').getContext('2d');
new Chart(ctx, {
type: 'bar',
data: {
labels: data.map(item => item.event_type),
datasets: [{
label: 'События за день',
data: data.map(item => item.count),
backgroundColor: 'rgba(75, 192, 192, 0.2)',
borderColor: 'rgba(75, 192, 192, 1)',
borderWidth: 1
}]
},
options: {
scales: {
y: { beginAtZero: true }
}
}
});
});
</script>
Создайте эндпоинт для получения данных графика:
from django.http import JsonResponse
def daily_events(request):
events = get_daily_events()
return JsonResponse(list(events), safe=False)
Добавьте URL:
path('analytics/daily-events/', views.daily_events, name='daily_events'),
Шаг 6: Оптимизация и масштабирование
Для повышения производительности:
- Используйте сжатие данных в TimescaleDB: SELECT add_compression_policy('app_name_event', INTERVAL '7 days');
- Настройте асинхронную обработку событий с помощью Celery.
- Кэшируйте агрегированные данные с помощью Redis.
Заключение
Мы создали базовую аналитическую систему, которая отслеживает пользовательские действия, сохраняет их в TimescaleDB и визуализирует с помощью Chart.js. Вы можете расширить эту систему, добавив новые метрики, фильтры или интеграции. Собственная аналитика — это мощный инструмент для понимания поведения пользователей и принятия обоснованных решений.