From 5ba7c7f8af05747aa1997f0db5858f8ac208e1e6 Mon Sep 17 00:00:00 2001 From: lihuacai Date: Thu, 15 Jun 2023 09:56:33 +0800 Subject: [PATCH] feat: add request log id --- .gitignore | 2 ++ .vscode/launch.json | 18 ---------- apidemo/settings.py | 84 +++++++++++++++++++++++++++++++++++++++++++- db.sqlite3 | Bin 155648 -> 155648 bytes employee/views.py | 11 +++--- logs/.gitkeep | 0 requirements.txt | 3 ++ 7 files changed, 95 insertions(+), 23 deletions(-) delete mode 100644 .vscode/launch.json create mode 100644 logs/.gitkeep diff --git a/.gitignore b/.gitignore index 0b3366c..117a19c 100644 --- a/.gitignore +++ b/.gitignore @@ -129,3 +129,5 @@ dmypy.json # Pyre type checker .pyre/ + +logs/ \ No newline at end of file diff --git a/.vscode/launch.json b/.vscode/launch.json deleted file mode 100644 index 690ada3..0000000 --- a/.vscode/launch.json +++ /dev/null @@ -1,18 +0,0 @@ -{ - // 使用 IntelliSense 了解相关属性。 - // 悬停以查看现有属性的描述。 - // 欲了解更多信息,请访问: https://go.microsoft.com/fwlink/?linkid=830387 - "version": "0.2.0", - "configurations": [ - { - "name": "Python: Django", - "type": "python", - "request": "launch", - "program": "${workspaceFolder}/manage.py", - "args": [ - "runserver", "--noreload" - ], - "django": true - } - ] -} \ No newline at end of file diff --git a/apidemo/settings.py b/apidemo/settings.py index 0c5fca1..0b25a67 100644 --- a/apidemo/settings.py +++ b/apidemo/settings.py @@ -9,7 +9,7 @@ For the full list of settings and their values, see https://docs.djangoproject.com/en/3.1/ref/settings/ """ - +import os from pathlib import Path # Build paths inside the project like this: BASE_DIR / 'subdir'. @@ -41,6 +41,7 @@ ] MIDDLEWARE = [ + 'log_request_id.middleware.RequestIDMiddleware', 'django.middleware.security.SecurityMiddleware', 'django.contrib.sessions.middleware.SessionMiddleware', 'django.middleware.common.CommonMiddleware', @@ -119,3 +120,84 @@ # https://docs.djangoproject.com/en/3.1/howto/static-files/ STATIC_URL = '/static/' + +# log_id setting +LOG_REQUEST_ID_HEADER = "HTTP_X_REQUEST_ID" +GENERATE_REQUEST_ID_IF_NOT_IN_HEADER = True +REQUEST_ID_RESPONSE_HEADER = "RESPONSE_HEADER_NAME" + +LOGGING = { + "version": 1, + "disable_existing_loggers": True, + "formatters": { + "standard": { + "format": "%(levelname)-2s [%(asctime)s] [%(request_id)s] %(name)s: %(message)s", + "datefmt": "%Y-%m-%d %H:%M:%S", + }, + "color": { + "()": "colorlog.ColoredFormatter", + "format": "%(green)s%(asctime)s [%(request_id)s] %(name)s %(log_color)s%(levelname)s [pid:%(process)d] " + "[%(filename)s->%(funcName)s:%(lineno)s] %(cyan)s%(message)s", + "log_colors": { + "DEBUG": "black", + "INFO": "white", + "WARNING": "yellow", + "ERROR": "red", + "CRITICAL": "bold_red", + }, + } + # 日志格式 + }, + "filters": { + "request_id": {"()": "log_request_id.filters.RequestIDFilter"}, + "require_debug_true": { + "()": "django.utils.log.RequireDebugTrue", # 过滤器,只有当setting的DEBUG = True时生效 + }, + }, + "handlers": { + "mail_admins": { + "level": "ERROR", + "class": "django.utils.log.AdminEmailHandler", + "include_html": True, + }, + "default": { + "level": "DEBUG", + "class": "logging.handlers.RotatingFileHandler", + # 'filename': os.path.join(BASE_DIR, 'logs/../../logs/debug.log'), + "filename": os.path.join(BASE_DIR, "logs/info.log"), + "maxBytes": 1024 * 1024 * 50, + "backupCount": 5, + "formatter": "color", + "filters": ["request_id"], + }, + "error": { + "level": "ERROR", + "class": "logging.handlers.RotatingFileHandler", + # 'filename': os.path.join(BASE_DIR, 'logs/../../logs/debug.log'), + "filename": os.path.join(BASE_DIR, "logs/error.log"), + "maxBytes": 1024 * 1024 * 50, + "backupCount": 5, + "formatter": "color", + "filters": ["request_id"], + }, + "console": { + "level": "DEBUG", + "class": "logging.StreamHandler", + "formatter": "color", + "filters": ["request_id"], + }, + }, + "loggers": { + "django": { + "handlers": ["default", "console", "error"], + "level": "INFO", + "propagate": True, + }, + "employee": { + "handlers": ["default", "console", "error"], + "level": "INFO", + "propagate": True, + }, + + }, +} \ No newline at end of file diff --git a/db.sqlite3 b/db.sqlite3 index 3b3dba8b39b771a57664d6833393912effbf8d0e..946fd9d36610af9c4cddf893fa70d90efa476662 100644 GIT binary patch delta 159 zcmZoTz}awsbAmLZ&O{k!RviYtc-f69g8GbX&1L%SW%`WM%k-K0_*nTLGw{FQf6V`# z{}cb)&4L9N`MFq_IT+bM1nc&<_DtdeKt)*${73kg@jvJ9;LqCF7{PBN!^XxSDXGX& fTvC*omkuF~42+C*4a{^6O=Vc|$xdGu&lCj!{&p-I delta 85 zcmV-b0IL6hzzKlB36L8BDv=yR1u6h8G$65L5ibD*gLW^6b}s>!b}s^s1OpH40JjV< r0@n|bP!6~4KLQsJ3Ih+O01w0urVr<_fpZT858?nNk%1wXre6YDA~qS9 diff --git a/employee/views.py b/employee/views.py index 22159c9..a26bad6 100644 --- a/employee/views.py +++ b/employee/views.py @@ -1,16 +1,18 @@ +import logging from typing import List, Optional -from ninja import Router, Query, Schema + from django.shortcuts import get_object_or_404 +from ninja import Query, Router, Schema from pydantic.fields import Field from pydantic.types import conint - - from common.schema import Message from employee.models import Employee from employee.schemas import EmployeeIn, EmployeeOut -router = Router(tags=['employees']) +router = Router(tags=["employees"]) + +logger = logging.getLogger(__name__) class Filters(Schema): @@ -21,6 +23,7 @@ class Filters(Schema): @router.post("/employees") def create_employee(request, payload: EmployeeIn): + logger.info(f"create employee, input: {payload.dict()}") employee = Employee.objects.create(**payload.dict()) return {"id": employee.id} diff --git a/logs/.gitkeep b/logs/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/requirements.txt b/requirements.txt index c09f913..856a800 100644 --- a/requirements.txt +++ b/requirements.txt @@ -6,3 +6,6 @@ pydantic pytz sqlparse typing-extensions + +django-log-request-id +colorlog==4.0.2 \ No newline at end of file