core: add X-passbook-id to every request with unique ID
This commit is contained in:
		| @ -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
	
	Block a user
	 Jens Langhammer
					Jens Langhammer