Skip to content

Commit a9e26d8

Browse files
committed
add middleware for loggin
1 parent 4d54a16 commit a9e26d8

File tree

4 files changed

+84
-1
lines changed

4 files changed

+84
-1
lines changed

myproject/middleware.py

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
import logging
2+
import time
3+
4+
logger = logging.getLogger("django.request")
5+
6+
7+
class RequestLoggingMiddleware:
8+
def __init__(self, get_response):
9+
self.get_response = get_response
10+
11+
def __call__(self, request):
12+
start_time = time.time()
13+
14+
response = self.get_response(request)
15+
16+
duration = round(time.time() - start_time, 3)
17+
18+
user = request.user if request.user.is_authenticated else "Anonymous"
19+
ip = request.META.get("REMOTE_ADDR")
20+
path = request.path
21+
method = request.method
22+
status = response.status_code
23+
24+
logger.warning(
25+
f"{method} {path} | status={status} | user={user} | ip={ip} | {duration}s"
26+
)
27+
28+
return response

myproject/settings.py

Lines changed: 38 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@
4545
'django.contrib.messages.middleware.MessageMiddleware',
4646
'django.middleware.clickjacking.XFrameOptionsMiddleware',
4747
]
48+
MIDDLEWARE.append("myproject.middleware.RequestLoggingMiddleware")
4849

4950
ROOT_URLCONF = 'myproject.urls'
5051

@@ -184,4 +185,40 @@
184185
})
185186

186187
if "pytest" in sys.argv[0]:
187-
REST_FRAMEWORK["DEFAULT_THROTTLE_CLASSES"] = []
188+
REST_FRAMEWORK["DEFAULT_THROTTLE_CLASSES"] = []
189+
190+
LOGGING = {
191+
"version": 1,
192+
"disable_existing_loggers": False,
193+
194+
"formatters": {
195+
"verbose": {
196+
"format": "[{levelname}] {asctime} {name} | {message}",
197+
"style": "{",
198+
},
199+
"simple": {
200+
"format": "[{levelname}] {message}",
201+
"style": "{",
202+
},
203+
},
204+
205+
"handlers": {
206+
"console": {
207+
"class": "logging.StreamHandler",
208+
"formatter": "verbose",
209+
},
210+
},
211+
212+
"loggers": {
213+
"django": {
214+
"handlers": ["console"],
215+
"level": "INFO",
216+
},
217+
"django.request": {
218+
"handlers": ["console"],
219+
"level": "WARNING",
220+
"propagate": False,
221+
},
222+
},
223+
}
224+

products/views.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,9 @@
33
from .models import Product
44
from .serializers import ProductSerializer
55
from users.permissions import IsAdmin, IsStaff
6+
import logging
7+
8+
logger = logging.getLogger("django.request")
69

710
class ProductViewSet(viewsets.ModelViewSet):
811
serializer_class = ProductSerializer

users/views.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,27 @@
1414
from rest_framework_simplejwt.views import TokenObtainPairView
1515
from .throttles import LoginRateThrottle
1616
import sys
17+
import logging
18+
19+
logger = logging.getLogger("django.request")
20+
1721

1822
class CustomTokenObtainPairView(TokenObtainPairView):
1923
if "pytest" in sys.argv[0]:
2024
throttle_classes = []
2125
else:
2226
throttle_classes = [LoginRateThrottle]
27+
28+
def post(self, request, *args, **kwargs):
29+
ip = request.META.get("REMOTE_ADDR")
30+
response = super().post(request, *args, **kwargs)
31+
32+
if response.status_code == 200:
33+
logger.warning(f"LOGIN OK | user={request.data.get('username')} | ip={ip}")
34+
else:
35+
logger.warning(f"LOGIN FAIL | user={request.data.get('username')} | ip={ip}")
36+
37+
return response
2338

2439
class UserViewSet(viewsets.ModelViewSet):
2540
"""

0 commit comments

Comments
 (0)