core: add X-passbook-id to every request with unique ID

This commit is contained in:
Jens Langhammer 2020-09-21 19:31:01 +02:00
parent 241d59be8d
commit e2cc2843d8
3 changed files with 51 additions and 3 deletions

View file

@ -1,11 +1,14 @@
"""passbook admin Middleware to impersonate users"""
from logging import Logger
from threading import local
from typing import Callable
from uuid import uuid4
from django.http import HttpRequest, HttpResponse
SESSION_IMPERSONATE_USER = "passbook_impersonate_user"
SESSION_IMPERSONATE_ORIGINAL_USER = "passbook_impersonate_original_user"
LOCAL = local()
class ImpersonateMiddleware:
@ -24,3 +27,30 @@ class ImpersonateMiddleware:
request.user = request.session[SESSION_IMPERSONATE_USER]
return self.get_response(request)
class RequestIDMiddleware:
"""Add a unique ID to every request"""
get_response: Callable[[HttpRequest], HttpResponse]
def __init__(self, get_response: Callable[[HttpRequest], HttpResponse]):
self.get_response = get_response
def __call__(self, request: HttpRequest) -> HttpResponse:
if not hasattr(request, "request_id"):
request_id = uuid4().hex
setattr(request, "request_id", request_id)
LOCAL.passbook = {"request_id": request_id}
response = self.get_response(request)
response["X-passbook-id"] = request.request_id
del LOCAL.passbook["request_id"]
return response
# pylint: disable=unused-argument
def structlog_add_request_id(logger: Logger, method_name: str, event_dict):
"""If threadlocal has passbook defined, add request_id to log"""
if hasattr(LOCAL, "passbook"):
event_dict["request_id"] = LOCAL.passbook.get("request_id", "")
return event_dict

View file

@ -1,9 +1,23 @@
"""logging helpers"""
from logging import Logger
from os import getpid
from typing import Callable
# pylint: disable=unused-argument
def add_process_id(logger, method_name, event_dict):
def add_process_id(logger: Logger, method_name: str, event_dict):
"""Add the current process ID"""
event_dict["pid"] = getpid()
return event_dict
def add_common_fields(environment: str) -> Callable:
"""Add a common field to easily search for passbook logs"""
def add_common_field(logger: Logger, method_name: str, event_dict):
"""Add a common field to easily search for passbook logs"""
event_dict["app"] = "passbook"
event_dict["app_environment"] = environment
return event_dict
return add_common_field

View file

@ -22,8 +22,9 @@ from sentry_sdk.integrations.celery import CeleryIntegration
from sentry_sdk.integrations.django import DjangoIntegration
from passbook import __version__
from passbook.core.middleware import structlog_add_request_id
from passbook.lib.config import CONFIG
from passbook.lib.logging import add_process_id
from passbook.lib.logging import add_common_fields, add_process_id
from passbook.lib.sentry import before_send
@ -175,6 +176,7 @@ MIDDLEWARE = [
"django_prometheus.middleware.PrometheusBeforeMiddleware",
"django.contrib.sessions.middleware.SessionMiddleware",
"django.contrib.auth.middleware.AuthenticationMiddleware",
"passbook.core.middleware.RequestIDMiddleware",
"django.middleware.security.SecurityMiddleware",
"django.middleware.common.CommonMiddleware",
"django.middleware.csrf.CsrfViewMiddleware",
@ -330,6 +332,8 @@ structlog.configure_once(
structlog.stdlib.add_log_level,
structlog.stdlib.add_logger_name,
add_process_id,
add_common_fields(CONFIG.y("error_reporting.environment", "customer")),
structlog_add_request_id,
structlog.stdlib.PositionalArgumentsFormatter(),
structlog.processors.TimeStamper(),
structlog.processors.StackInfoRenderer(),