Add request response logging
This commit is contained in:
parent
38bc5f47a8
commit
c600f3f514
|
|
@ -78,8 +78,8 @@ THIRD_PARTY_APPS = [
|
|||
]
|
||||
|
||||
LOCAL_APPS = [
|
||||
"vbv_lernwelt.core",
|
||||
"vbv_lernwelt.users",
|
||||
"vbv_lernwelt.core",
|
||||
# Your stuff: custom apps go here
|
||||
]
|
||||
# https://docs.djangoproject.com/en/dev/ref/settings/#installed-apps
|
||||
|
|
@ -138,7 +138,8 @@ MIDDLEWARE = [
|
|||
"django.contrib.messages.middleware.MessageMiddleware",
|
||||
"django.middleware.common.BrokenLinkEmailsMiddleware",
|
||||
"django.middleware.clickjacking.XFrameOptionsMiddleware",
|
||||
"vbv_lernwelt.core.middleware.AuthenticationRequiredMiddleware",
|
||||
"vbv_lernwelt.core.middleware.auth.AuthenticationRequiredMiddleware",
|
||||
"vbv_lernwelt.core.middleware.security.SecurityRequestResponseLoggingMiddleware",
|
||||
]
|
||||
|
||||
# STATIC
|
||||
|
|
|
|||
|
|
@ -9,10 +9,10 @@ from django.views.generic import TemplateView
|
|||
from drf_spectacular.views import SpectacularAPIView, SpectacularSwaggerView
|
||||
from rest_framework.authtoken.views import obtain_auth_token
|
||||
|
||||
from vbv_lernwelt.core.middleware import django_view_authentication_exempt
|
||||
from vbv_lernwelt.core.middleware.auth import django_view_authentication_exempt
|
||||
|
||||
urlpatterns = [
|
||||
path("", TemplateView.as_view(template_name="pages/home.html"), name="home"),
|
||||
path("", django_view_authentication_exempt(TemplateView.as_view(template_name="pages/home.html")), name="home"),
|
||||
path("about/", TemplateView.as_view(template_name="pages/about.html"), name="about"),
|
||||
# Django Admin, use {% url 'admin:index' %}
|
||||
path(settings.ADMIN_URL, admin.site.urls),
|
||||
|
|
|
|||
|
|
@ -3,4 +3,4 @@ from django.apps import AppConfig
|
|||
|
||||
class CoreConfig(AppConfig):
|
||||
default_auto_field = 'django.db.models.BigAutoField'
|
||||
name = 'core'
|
||||
name = 'vbv_lernwelt.core'
|
||||
|
|
|
|||
|
|
@ -1,9 +1,12 @@
|
|||
from functools import wraps
|
||||
|
||||
import structlog
|
||||
from django.conf import settings
|
||||
from django.contrib.auth.views import redirect_to_login
|
||||
from django.utils.deprecation import MiddlewareMixin
|
||||
|
||||
logger = structlog.get_logger(__name__)
|
||||
|
||||
|
||||
class AuthenticationRequiredMiddleware(MiddlewareMixin):
|
||||
def process_view(self, request, callback, callback_args, callback_kwargs):
|
||||
|
|
@ -0,0 +1,72 @@
|
|||
import uuid
|
||||
|
||||
import structlog
|
||||
from structlog.threadlocal import bind_threadlocal, clear_threadlocal
|
||||
|
||||
from vbv_lernwelt.core.models import SecurityRequestResponseLog
|
||||
|
||||
logger = structlog.get_logger(__name__)
|
||||
|
||||
|
||||
class SecurityRequestResponseLoggingMiddleware:
|
||||
def __init__(self, get_response):
|
||||
self.get_response = get_response
|
||||
|
||||
def create_logging_threadlocalbind(self, request):
|
||||
request_username = request.user.username if hasattr(request, 'user') else ''
|
||||
|
||||
bind_threadlocal(
|
||||
request_method=request.method,
|
||||
request_full_path=request.get_full_path(),
|
||||
request_username=request_username,
|
||||
request_client_ip=request.META.get('REMOTE_ADDR'),
|
||||
request_trace_id=uuid.uuid4().hex,
|
||||
)
|
||||
|
||||
def create_database_security_request_response_log(self, request, response):
|
||||
try:
|
||||
entry = SecurityRequestResponseLog()
|
||||
entry.label = getattr(request, 'security_request_logging', '')
|
||||
entry.request_method = request.method
|
||||
entry.request_full_path = request.get_full_path()[:255]
|
||||
entry.request_username = request.user.username if hasattr(request, 'user') else ''
|
||||
entry.request_client_ip = request.META.get('REMOTE_ADDR')
|
||||
entry.request_scn = getattr(request, 'scn', '')
|
||||
entry.response_status_code = response.status_code
|
||||
entry.additional_json_data = getattr(request, 'log_additional_json_data', {})
|
||||
|
||||
entry.save()
|
||||
|
||||
# pylint: disable=broad-except
|
||||
except Exception:
|
||||
logger.warn('could not create db entry', label='security', exc_info=True)
|
||||
|
||||
def log_request_response(self, request):
|
||||
clear_threadlocal()
|
||||
self.create_logging_threadlocalbind(request)
|
||||
|
||||
logger.info(
|
||||
'url access initialized',
|
||||
label='security',
|
||||
)
|
||||
|
||||
response = self.get_response(request)
|
||||
|
||||
security_request_logging = getattr(request, 'security_request_logging', None)
|
||||
if security_request_logging:
|
||||
self.create_database_security_request_response_log(request, response)
|
||||
|
||||
logger.info(
|
||||
'url access finished',
|
||||
label='security',
|
||||
response_status_code=response.status_code,
|
||||
request_ratelimited=getattr(request, 'limited', False),
|
||||
request_finished=True
|
||||
)
|
||||
|
||||
clear_threadlocal()
|
||||
|
||||
return response
|
||||
|
||||
def __call__(self, request):
|
||||
return self.log_request_response(request)
|
||||
|
|
@ -1,3 +1,15 @@
|
|||
from django.db import models
|
||||
from django.db.models import JSONField
|
||||
|
||||
# Create your models here.
|
||||
|
||||
class SecurityRequestResponseLog(models.Model):
|
||||
label = models.CharField(max_length=255, blank=True, default='')
|
||||
|
||||
request_method = models.CharField(max_length=255, blank=True, default='')
|
||||
request_full_path = models.CharField(max_length=255, blank=True, default='')
|
||||
request_username = models.CharField(max_length=255, blank=True, default='')
|
||||
request_client_ip = models.CharField(max_length=255, blank=True, default='')
|
||||
|
||||
response_status_code = models.CharField(max_length=255, blank=True, default='')
|
||||
|
||||
additional_json_data = JSONField(default=dict, blank=True)
|
||||
|
|
|
|||
Loading…
Reference in New Issue