JustAnalytics for Django

Step-by-step guide to add analytics, error tracking, and APM to your Django app

JustAnalytics for Django

Add distributed tracing, error tracking, structured logging, and infrastructure metrics to your Django application.

Time to data: 3-5 minutes

Prerequisites#


Install the SDK

pip install justanalytics-python[django]

The [django] extra installs Django-specific middleware and integrations.

Initialize and configure Django settings

Add the JustAnalytics middleware and initialization to your Django settings:

# settings.py
import justanalytics

# Initialize the SDK
justanalytics.init(
    site_id=os.environ.get("JA_SITE_ID"),
    api_key=os.environ.get("JA_API_KEY"),
    service_name="django-app",
    environment=os.environ.get("DJANGO_ENV", "development"),
)

MIDDLEWARE = [
    "justanalytics.integrations.django.JustAnalyticsMiddleware",  # Add first
    "django.middleware.security.SecurityMiddleware",
    "django.contrib.sessions.middleware.SessionMiddleware",
    "django.middleware.common.CommonMiddleware",
    "django.middleware.csrf.CsrfViewMiddleware",
    "django.contrib.auth.middleware.AuthenticationMiddleware",
    # ... other middleware
]

Add your credentials to your environment (.env file or environment variables):

export JA_SITE_ID=site_abc123
export JA_API_KEY=ja_sk_your_api_key_here

Automatic request tracing

The Django middleware automatically traces every HTTP request. No code changes needed in your views:

# views.py — these are automatically traced
from django.http import JsonResponse
from django.views import View

def user_list(request):
    users = User.objects.all()
    return JsonResponse({"users": list(users.values())})

class OrderView(View):
    def post(self, request):
        order = Order.objects.create(**request.POST)
        return JsonResponse({"id": order.id}, status=201)

Each request generates a span named like GET /api/users/ or POST /api/orders/.

Add error tracking

Unhandled exceptions are automatically captured by the middleware. For manual error reporting:

import justanalytics

def process_payment(request):
    try:
        charge = stripe.Charge.create(amount=request.POST["amount"])
        return JsonResponse({"charge_id": charge.id})
    except stripe.StripeError as e:
        justanalytics.capture_exception(e, tags={"module": "payments"})
        return JsonResponse({"error": "Payment failed"}, status=400)

Add client-side tracking (optional)

Add the tracking scripts to your base template for frontend analytics:

<!-- templates/base.html -->
<!DOCTYPE html>
<html>
<head>
    <script defer data-site-id="site_abc123"
            src="https://justanalytics.app/tracker.js"></script>
    <script defer data-site-id="site_abc123"
            src="https://justanalytics.app/monitor.js"></script>
</head>
<body>
    {% block content %}{% endblock %}
</body>
</html>

Verify Your Setup

Visit any page or make an API request, then check the Traces tab. You should see server spans for each Django request.

Open Dashboard

Advanced Features#

Custom spans#

import justanalytics

def generate_report(request, report_id):
    with justanalytics.start_span("generate-report") as span:
        span.set_attribute("report.id", report_id)

        with justanalytics.start_span("fetch-data") as child:
            data = Report.objects.get(id=report_id)

        with justanalytics.start_span("render-pdf") as child:
            pdf = render_to_pdf(data)

    return HttpResponse(pdf, content_type="application/pdf")

Decorator-based tracing#

@justanalytics.span(op="db.query")
def get_user_with_orders(user_id):
    user = User.objects.prefetch_related("orders").get(id=user_id)
    return user

User identification#

# In your authentication middleware or view
def login_view(request):
    user = authenticate(request.POST["email"], request.POST["password"])
    if user:
        justanalytics.set_user(id=str(user.id), email=user.email)
        login(request, user)
        return redirect("/dashboard")

Structured logging#

justanalytics.log("info", "User signed up", {"user_id": "u123", "plan": "pro"})
justanalytics.log("error", "Payment failed", {"order_id": "o456", "reason": "declined"})

Python logging bridge#

Forward Python standard library logs to JustAnalytics:

# settings.py
import logging
from justanalytics.integrations.logging import JustAnalyticsHandler

LOGGING = {
    "version": 1,
    "handlers": {
        "justanalytics": {
            "()": JustAnalyticsHandler,
            "level": "WARNING",
        },
        "console": {
            "class": "logging.StreamHandler",
        },
    },
    "root": {
        "handlers": ["console", "justanalytics"],
        "level": "DEBUG",
    },
}

Outgoing HTTP tracing#

Trace requests made with the requests library:

from justanalytics.integrations.requests import RequestsIntegration

integration = RequestsIntegration(service_name="django-app")
integration.enable()

# All requests.get/post calls are now traced with W3C traceparent headers
import requests
response = requests.get("https://api.example.com/data")

Custom metrics#

justanalytics.record_metric("custom.queue_size", 42, {"queue": "emails"})
justanalytics.record_metric("custom.cache_hit_rate", 0.95, {"cache": "redis"})

Graceful shutdown#

# In your WSGI/ASGI shutdown handler or management command
import justanalytics

justanalytics.flush()
justanalytics.close()

Environment variables#

| Variable | Description | Required | |----------|-------------|----------| | JA_SITE_ID | Your site ID from the dashboard | Yes | | JA_API_KEY | API key (starts with ja_sk_) | Yes | | DJANGO_ENV | Deployment environment | No |