core: add X-passbook-id to every request with unique ID
This commit is contained in:
parent
241d59be8d
commit
e2cc2843d8
|
@ -1,11 +1,14 @@
|
||||||
"""passbook admin Middleware to impersonate users"""
|
"""passbook admin Middleware to impersonate users"""
|
||||||
|
from logging import Logger
|
||||||
|
from threading import local
|
||||||
from typing import Callable
|
from typing import Callable
|
||||||
|
from uuid import uuid4
|
||||||
|
|
||||||
from django.http import HttpRequest, HttpResponse
|
from django.http import HttpRequest, HttpResponse
|
||||||
|
|
||||||
SESSION_IMPERSONATE_USER = "passbook_impersonate_user"
|
SESSION_IMPERSONATE_USER = "passbook_impersonate_user"
|
||||||
SESSION_IMPERSONATE_ORIGINAL_USER = "passbook_impersonate_original_user"
|
SESSION_IMPERSONATE_ORIGINAL_USER = "passbook_impersonate_original_user"
|
||||||
|
LOCAL = local()
|
||||||
|
|
||||||
|
|
||||||
class ImpersonateMiddleware:
|
class ImpersonateMiddleware:
|
||||||
|
@ -24,3 +27,30 @@ class ImpersonateMiddleware:
|
||||||
request.user = request.session[SESSION_IMPERSONATE_USER]
|
request.user = request.session[SESSION_IMPERSONATE_USER]
|
||||||
|
|
||||||
return self.get_response(request)
|
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
|
||||||
|
|
|
@ -1,9 +1,23 @@
|
||||||
"""logging helpers"""
|
"""logging helpers"""
|
||||||
|
from logging import Logger
|
||||||
from os import getpid
|
from os import getpid
|
||||||
|
from typing import Callable
|
||||||
|
|
||||||
|
|
||||||
# pylint: disable=unused-argument
|
# 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"""
|
"""Add the current process ID"""
|
||||||
event_dict["pid"] = getpid()
|
event_dict["pid"] = getpid()
|
||||||
return event_dict
|
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
|
||||||
|
|
|
@ -22,8 +22,9 @@ from sentry_sdk.integrations.celery import CeleryIntegration
|
||||||
from sentry_sdk.integrations.django import DjangoIntegration
|
from sentry_sdk.integrations.django import DjangoIntegration
|
||||||
|
|
||||||
from passbook import __version__
|
from passbook import __version__
|
||||||
|
from passbook.core.middleware import structlog_add_request_id
|
||||||
from passbook.lib.config import CONFIG
|
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
|
from passbook.lib.sentry import before_send
|
||||||
|
|
||||||
|
|
||||||
|
@ -175,6 +176,7 @@ MIDDLEWARE = [
|
||||||
"django_prometheus.middleware.PrometheusBeforeMiddleware",
|
"django_prometheus.middleware.PrometheusBeforeMiddleware",
|
||||||
"django.contrib.sessions.middleware.SessionMiddleware",
|
"django.contrib.sessions.middleware.SessionMiddleware",
|
||||||
"django.contrib.auth.middleware.AuthenticationMiddleware",
|
"django.contrib.auth.middleware.AuthenticationMiddleware",
|
||||||
|
"passbook.core.middleware.RequestIDMiddleware",
|
||||||
"django.middleware.security.SecurityMiddleware",
|
"django.middleware.security.SecurityMiddleware",
|
||||||
"django.middleware.common.CommonMiddleware",
|
"django.middleware.common.CommonMiddleware",
|
||||||
"django.middleware.csrf.CsrfViewMiddleware",
|
"django.middleware.csrf.CsrfViewMiddleware",
|
||||||
|
@ -330,6 +332,8 @@ structlog.configure_once(
|
||||||
structlog.stdlib.add_log_level,
|
structlog.stdlib.add_log_level,
|
||||||
structlog.stdlib.add_logger_name,
|
structlog.stdlib.add_logger_name,
|
||||||
add_process_id,
|
add_process_id,
|
||||||
|
add_common_fields(CONFIG.y("error_reporting.environment", "customer")),
|
||||||
|
structlog_add_request_id,
|
||||||
structlog.stdlib.PositionalArgumentsFormatter(),
|
structlog.stdlib.PositionalArgumentsFormatter(),
|
||||||
structlog.processors.TimeStamper(),
|
structlog.processors.TimeStamper(),
|
||||||
structlog.processors.StackInfoRenderer(),
|
structlog.processors.StackInfoRenderer(),
|
||||||
|
|
Reference in New Issue