Django Integration
Django Integration
Integrate ByteHide Logs with Django using middleware to automatically track requests, user actions, and errors across your entire application.
Setup
Install the Django integration:
Bash
pip install bytehide-logs[django]pip install bytehide-logs[django]Add the ByteHide logging middleware to your Django settings:
Python
# settings.py
MIDDLEWARE = [
# ... other middleware ...
'bytehide_logs.django.ByteHideLoggingMiddleware',
]
# Configure ByteHide Logs
from bytehide_logs import Log, LogSettings
from datetime import timedelta
settings = LogSettings(
duplicate_suppression_window=timedelta(seconds=5),
mask_sensitive_data=["password", "token", "api_key"]
)
Log.configure(settings)
# Application metadata
Log.add_meta_context("service", "django-app")
Log.add_meta_context("environment", os.environ.get("ENVIRONMENT", "development"))# settings.py
MIDDLEWARE = [
# ... other middleware ...
'bytehide_logs.django.ByteHideLoggingMiddleware',
]
# Configure ByteHide Logs
from bytehide_logs import Log, LogSettings
from datetime import timedelta
settings = LogSettings(
duplicate_suppression_window=timedelta(seconds=5),
mask_sensitive_data=["password", "token", "api_key"]
)
Log.configure(settings)
# Application metadata
Log.add_meta_context("service", "django-app")
Log.add_meta_context("environment", os.environ.get("ENVIRONMENT", "development"))Middleware Setup
The middleware automatically:
- Tracks incoming requests with correlation IDs
- Logs request processing time
- Captures user information
- Handles errors and exceptions
- Cleans up context after request
Python
# settings.py
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
# ... other apps ...
]
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'bytehide_logs.django.ByteHideLoggingMiddleware', # Add here
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
]# settings.py
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
# ... other apps ...
]
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'bytehide_logs.django.ByteHideLoggingMiddleware', # Add here
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
]Request Tracking
The middleware automatically logs all requests:
Python
# Middleware automatically logs:
# - Request method and path
# - Client IP address
# - Correlation ID
# - Response status code
# - Request duration# Middleware automatically logs:
# - Request method and path
# - Client IP address
# - Correlation ID
# - Response status code
# - Request durationTo access the correlation ID in your views:
Python
from django.http import JsonResponse
from bytehide_logs import Log
def my_view(request):
"""View with access to correlation ID."""
# Correlation ID is available from request
correlation_id = getattr(request, 'correlation_id', None)
Log.with_context("view", "my_view") \
.with_correlation_id(correlation_id) \
.info("Processing view")
return JsonResponse({"message": "Success"})from django.http import JsonResponse
from bytehide_logs import Log
def my_view(request):
"""View with access to correlation ID."""
# Correlation ID is available from request
correlation_id = getattr(request, 'correlation_id', None)
Log.with_context("view", "my_view") \
.with_correlation_id(correlation_id) \
.info("Processing view")
return JsonResponse({"message": "Success"})User Identification
Identify authenticated Django users automatically:
Python
# views.py
from django.contrib.auth.decorators import login_required
from django.http import JsonResponse
from bytehide_logs import Log, AuthUser
@login_required
def user_profile(request):
"""View with authenticated user tracking."""
user = request.user
# Identify user in logs
auth_user = AuthUser(
id=str(user.id),
email=user.email
)
Log.identify(auth_user)
Log.with_tags("user", "profile").info("Viewing user profile")
return JsonResponse({
"user_id": user.id,
"email": user.email
})# views.py
from django.contrib.auth.decorators import login_required
from django.http import JsonResponse
from bytehide_logs import Log, AuthUser
@login_required
def user_profile(request):
"""View with authenticated user tracking."""
user = request.user
# Identify user in logs
auth_user = AuthUser(
id=str(user.id),
email=user.email
)
Log.identify(auth_user)
Log.with_tags("user", "profile").info("Viewing user profile")
return JsonResponse({
"user_id": user.id,
"email": user.email
})Model Operations Logging
Log database operations:
Python
# models.py
from django.db import models
from bytehide_logs import Log
class User(models.Model):
"""User model with logging."""
email = models.EmailField(unique=True)
username = models.CharField(max_length=100)
def save(self, *args, **kwargs):
"""Save with logging."""
is_new = not self.pk
if is_new:
Log.with_tags("model", "user", "create") \
.with_context("email", self.email) \
.info("Creating user")
else:
Log.with_tags("model", "user", "update") \
.with_context("user_id", self.id) \
.with_context("email", self.email) \
.info("Updating user")
super().save(*args, **kwargs)
if is_new:
Log.with_tags("model", "user", "create", "success") \
.with_context("user_id", self.id) \
.info("User created")
def delete(self, *args, **kwargs):
"""Delete with logging."""
Log.with_tags("model", "user", "delete") \
.with_context("user_id", self.id) \
.info("Deleting user")
super().delete(*args, **kwargs)
Log.with_tags("model", "user", "delete", "success") \
.info("User deleted")# models.py
from django.db import models
from bytehide_logs import Log
class User(models.Model):
"""User model with logging."""
email = models.EmailField(unique=True)
username = models.CharField(max_length=100)
def save(self, *args, **kwargs):
"""Save with logging."""
is_new = not self.pk
if is_new:
Log.with_tags("model", "user", "create") \
.with_context("email", self.email) \
.info("Creating user")
else:
Log.with_tags("model", "user", "update") \
.with_context("user_id", self.id) \
.with_context("email", self.email) \
.info("Updating user")
super().save(*args, **kwargs)
if is_new:
Log.with_tags("model", "user", "create", "success") \
.with_context("user_id", self.id) \
.info("User created")
def delete(self, *args, **kwargs):
"""Delete with logging."""
Log.with_tags("model", "user", "delete") \
.with_context("user_id", self.id) \
.info("Deleting user")
super().delete(*args, **kwargs)
Log.with_tags("model", "user", "delete", "success") \
.info("User deleted")Signal Handling
Use Django signals with logging:
Python
# signals.py
from django.db.models.signals import post_save, post_delete
from django.dispatch import receiver
from django.contrib.auth.models import User
from bytehide_logs import Log
@receiver(post_save, sender=User)
def user_created(sender, instance, created, **kwargs):
"""Log user creation."""
if created:
Log.with_tags("user", "created") \
.with_context("user_id", instance.id) \
.with_context("email", instance.email) \
.info("User created via signal")
@receiver(post_delete, sender=User)
def user_deleted(sender, instance, **kwargs):
"""Log user deletion."""
Log.with_tags("user", "deleted") \
.with_context("user_id", instance.id) \
.info("User deleted via signal")# signals.py
from django.db.models.signals import post_save, post_delete
from django.dispatch import receiver
from django.contrib.auth.models import User
from bytehide_logs import Log
@receiver(post_save, sender=User)
def user_created(sender, instance, created, **kwargs):
"""Log user creation."""
if created:
Log.with_tags("user", "created") \
.with_context("user_id", instance.id) \
.with_context("email", instance.email) \
.info("User created via signal")
@receiver(post_delete, sender=User)
def user_deleted(sender, instance, **kwargs):
"""Log user deletion."""
Log.with_tags("user", "deleted") \
.with_context("user_id", instance.id) \
.info("User deleted via signal")Exception Handling
Log exceptions in views:
Python
# views.py
from django.http import JsonResponse
from bytehide_logs import Log
from django.views.decorators.http import require_http_methods
@require_http_methods(["POST"])
def process_payment(request):
"""Process payment with error handling."""
try:
data = request.POST
Log.with_tags("payment", "process").info("Processing payment")
# Validate data
if not data.get("amount"):
raise ValueError("Amount is required")
# Process payment
result = charge_card(
card_token=data.get("token"),
amount=int(data.get("amount"))
)
Log.with_tags("payment", "success") \
.with_context("transaction_id", result.id) \
.with_context("amount", data.get("amount")) \
.info("Payment processed successfully")
return JsonResponse({
"transaction_id": result.id,
"status": "success"
})
except ValueError as e:
Log.warning("Payment validation failed", exception=e)
return JsonResponse({"error": str(e)}, status=400)
except Exception as e:
Log.error("Payment processing failed", exception=e)
return JsonResponse({"error": "Payment failed"}, status=500)# views.py
from django.http import JsonResponse
from bytehide_logs import Log
from django.views.decorators.http import require_http_methods
@require_http_methods(["POST"])
def process_payment(request):
"""Process payment with error handling."""
try:
data = request.POST
Log.with_tags("payment", "process").info("Processing payment")
# Validate data
if not data.get("amount"):
raise ValueError("Amount is required")
# Process payment
result = charge_card(
card_token=data.get("token"),
amount=int(data.get("amount"))
)
Log.with_tags("payment", "success") \
.with_context("transaction_id", result.id) \
.with_context("amount", data.get("amount")) \
.info("Payment processed successfully")
return JsonResponse({
"transaction_id": result.id,
"status": "success"
})
except ValueError as e:
Log.warning("Payment validation failed", exception=e)
return JsonResponse({"error": str(e)}, status=400)
except Exception as e:
Log.error("Payment processing failed", exception=e)
return JsonResponse({"error": "Payment failed"}, status=500)Complete Django Example
Python
# views.py
from django.shortcuts import render, redirect
from django.contrib.auth import authenticate, login, logout
from django.contrib.auth.decorators import login_required
from django.http import JsonResponse
from django.views.decorators.http import require_http_methods
from bytehide_logs import Log, AuthUser
import uuid
@require_http_methods(["POST"])
def user_login(request):
"""User login view with logging."""
try:
username = request.POST.get("username")
password = request.POST.get("password")
Log.with_tags("auth", "login") \
.with_context("username", username) \
.info("Login attempt")
# Authenticate user
user = authenticate(request, username=username, password=password)
if user is not None:
# Login successful
login(request, user)
# Identify user in logs
auth_user = AuthUser(
id=str(user.id),
email=user.email
)
Log.identify(auth_user)
Log.with_tags("auth", "login", "success").info("Login successful")
return redirect('dashboard')
else:
# Login failed
Log.with_tags("auth", "login", "failed") \
.with_context("username", username) \
.warning("Login failed - invalid credentials")
return JsonResponse({"error": "Invalid credentials"}, status=401)
except Exception as e:
Log.with_tags("auth", "login", "error") \
.error("Login error", exception=e)
return JsonResponse({"error": "Login error"}, status=500)
@require_http_methods(["POST"])
def user_logout(request):
"""User logout view."""
Log.with_tags("auth", "logout").info("Logout initiated")
logout(request)
Log.with_tags("auth", "logout", "success").info("Logout completed")
Log.logout()
return redirect('login')
@login_required
def user_profile(request):
"""User profile view."""
user = request.user
# Identify user
auth_user = AuthUser(id=str(user.id), email=user.email)
Log.identify(auth_user)
Log.with_tags("user", "profile") \
.with_context("user_id", user.id) \
.info("Accessing user profile")
return render(request, 'profile.html', {
'user': user
})
@login_required
@require_http_methods(["PUT"])
def update_profile(request):
"""Update user profile."""
try:
import json
data = json.loads(request.body)
user = request.user
Log.with_tags("user", "profile", "update") \
.with_context("user_id", user.id) \
.with_context("fields", list(data.keys())) \
.info("Updating user profile")
# Update user fields
if 'email' in data:
user.email = data['email']
if 'first_name' in data:
user.first_name = data['first_name']
if 'last_name' in data:
user.last_name = data['last_name']
user.save()
Log.with_tags("user", "profile", "update", "success") \
.with_context("user_id", user.id) \
.info("User profile updated")
return JsonResponse({"status": "success"})
except Exception as e:
Log.error("Profile update failed", exception=e)
return JsonResponse({"error": "Update failed"}, status=500)
@login_required
@require_http_methods(["POST"])
def process_order(request):
"""Process user order."""
try:
import json
data = json.loads(request.body)
user = request.user
correlation_id = str(uuid.uuid4())
Log.with_tags("order", "process") \
.with_context("user_id", user.id) \
.with_context("order_total", data.get("total")) \
.with_correlation_id(correlation_id) \
.info("Processing order")
# Validate cart
Log.with_tags("order", "validation") \
.with_correlation_id(correlation_id) \
.info("Validating order")
validate_order(data)
# Process payment
Log.with_tags("order", "payment") \
.with_correlation_id(correlation_id) \
.info("Processing payment")
payment = process_payment(data)
# Create order record
Log.with_tags("order", "create") \
.with_context("order_id", payment.id) \
.with_correlation_id(correlation_id) \
.info("Creating order record")
Log.with_tags("order", "complete") \
.with_context("order_id", payment.id) \
.with_correlation_id(correlation_id) \
.info("Order processed successfully")
return JsonResponse({
"order_id": payment.id,
"correlation_id": correlation_id
})
except Exception as e:
Log.error("Order processing failed", exception=e)
return JsonResponse({"error": "Order failed"}, status=500)# views.py
from django.shortcuts import render, redirect
from django.contrib.auth import authenticate, login, logout
from django.contrib.auth.decorators import login_required
from django.http import JsonResponse
from django.views.decorators.http import require_http_methods
from bytehide_logs import Log, AuthUser
import uuid
@require_http_methods(["POST"])
def user_login(request):
"""User login view with logging."""
try:
username = request.POST.get("username")
password = request.POST.get("password")
Log.with_tags("auth", "login") \
.with_context("username", username) \
.info("Login attempt")
# Authenticate user
user = authenticate(request, username=username, password=password)
if user is not None:
# Login successful
login(request, user)
# Identify user in logs
auth_user = AuthUser(
id=str(user.id),
email=user.email
)
Log.identify(auth_user)
Log.with_tags("auth", "login", "success").info("Login successful")
return redirect('dashboard')
else:
# Login failed
Log.with_tags("auth", "login", "failed") \
.with_context("username", username) \
.warning("Login failed - invalid credentials")
return JsonResponse({"error": "Invalid credentials"}, status=401)
except Exception as e:
Log.with_tags("auth", "login", "error") \
.error("Login error", exception=e)
return JsonResponse({"error": "Login error"}, status=500)
@require_http_methods(["POST"])
def user_logout(request):
"""User logout view."""
Log.with_tags("auth", "logout").info("Logout initiated")
logout(request)
Log.with_tags("auth", "logout", "success").info("Logout completed")
Log.logout()
return redirect('login')
@login_required
def user_profile(request):
"""User profile view."""
user = request.user
# Identify user
auth_user = AuthUser(id=str(user.id), email=user.email)
Log.identify(auth_user)
Log.with_tags("user", "profile") \
.with_context("user_id", user.id) \
.info("Accessing user profile")
return render(request, 'profile.html', {
'user': user
})
@login_required
@require_http_methods(["PUT"])
def update_profile(request):
"""Update user profile."""
try:
import json
data = json.loads(request.body)
user = request.user
Log.with_tags("user", "profile", "update") \
.with_context("user_id", user.id) \
.with_context("fields", list(data.keys())) \
.info("Updating user profile")
# Update user fields
if 'email' in data:
user.email = data['email']
if 'first_name' in data:
user.first_name = data['first_name']
if 'last_name' in data:
user.last_name = data['last_name']
user.save()
Log.with_tags("user", "profile", "update", "success") \
.with_context("user_id", user.id) \
.info("User profile updated")
return JsonResponse({"status": "success"})
except Exception as e:
Log.error("Profile update failed", exception=e)
return JsonResponse({"error": "Update failed"}, status=500)
@login_required
@require_http_methods(["POST"])
def process_order(request):
"""Process user order."""
try:
import json
data = json.loads(request.body)
user = request.user
correlation_id = str(uuid.uuid4())
Log.with_tags("order", "process") \
.with_context("user_id", user.id) \
.with_context("order_total", data.get("total")) \
.with_correlation_id(correlation_id) \
.info("Processing order")
# Validate cart
Log.with_tags("order", "validation") \
.with_correlation_id(correlation_id) \
.info("Validating order")
validate_order(data)
# Process payment
Log.with_tags("order", "payment") \
.with_correlation_id(correlation_id) \
.info("Processing payment")
payment = process_payment(data)
# Create order record
Log.with_tags("order", "create") \
.with_context("order_id", payment.id) \
.with_correlation_id(correlation_id) \
.info("Creating order record")
Log.with_tags("order", "complete") \
.with_context("order_id", payment.id) \
.with_correlation_id(correlation_id) \
.info("Order processed successfully")
return JsonResponse({
"order_id": payment.id,
"correlation_id": correlation_id
})
except Exception as e:
Log.error("Order processing failed", exception=e)
return JsonResponse({"error": "Order failed"}, status=500)URL Configuration
Log API endpoints:
Python
# urls.py
from django.contrib import admin
from django.urls import path
from bytehide_logs import Log
# Log URL configuration
Log.info("Configuring Django URLs")
urlpatterns = [
path('admin/', admin.site.urls),
path('auth/login/', views.user_login, name='login'),
path('auth/logout/', views.user_logout, name='logout'),
path('api/profile/', views.user_profile, name='profile'),
path('api/profile/update/', views.update_profile, name='update_profile'),
path('api/order/process/', views.process_order, name='process_order'),
]# urls.py
from django.contrib import admin
from django.urls import path
from bytehide_logs import Log
# Log URL configuration
Log.info("Configuring Django URLs")
urlpatterns = [
path('admin/', admin.site.urls),
path('auth/login/', views.user_login, name='login'),
path('auth/logout/', views.user_logout, name='logout'),
path('api/profile/', views.user_profile, name='profile'),
path('api/profile/update/', views.update_profile, name='update_profile'),
path('api/order/process/', views.process_order, name='process_order'),
]Best Practices
Always identify authenticated users:
Python
user = request.user
if user.is_authenticated:
auth_user = AuthUser(id=str(user.id), email=user.email)
Log.identify(auth_user)user = request.user
if user.is_authenticated:
auth_user = AuthUser(id=str(user.id), email=user.email)
Log.identify(auth_user)Use correlation IDs for multi-step operations:
Python
correlation_id = getattr(request, 'correlation_id', None)
Log.with_correlation_id(correlation_id).info("Processing step")correlation_id = getattr(request, 'correlation_id', None)
Log.with_correlation_id(correlation_id).info("Processing step")Log model operations for audit trails:
Python
def save(self, *args, **kwargs):
Log.with_tags("model", self.__class__.__name__).info("Saving model")
super().save(*args, **kwargs)def save(self, *args, **kwargs):
Log.with_tags("model", self.__class__.__name__).info("Saving model")
super().save(*args, **kwargs)Next Steps
- Learn about user identification
- Explore correlation IDs
- Discover Flask integration