File tree Expand file tree Collapse file tree 4 files changed +84
-1
lines changed
Expand file tree Collapse file tree 4 files changed +84
-1
lines changed Original file line number Diff line number Diff line change 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
Original file line number Diff line number Diff line change 4545 'django.contrib.messages.middleware.MessageMiddleware' ,
4646 'django.middleware.clickjacking.XFrameOptionsMiddleware' ,
4747]
48+ MIDDLEWARE .append ("myproject.middleware.RequestLoggingMiddleware" )
4849
4950ROOT_URLCONF = 'myproject.urls'
5051
184185})
185186
186187if "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+
Original file line number Diff line number Diff line change 33from .models import Product
44from .serializers import ProductSerializer
55from users .permissions import IsAdmin , IsStaff
6+ import logging
7+
8+ logger = logging .getLogger ("django.request" )
69
710class ProductViewSet (viewsets .ModelViewSet ):
811 serializer_class = ProductSerializer
Original file line number Diff line number Diff line change 1414from rest_framework_simplejwt .views import TokenObtainPairView
1515from .throttles import LoginRateThrottle
1616import sys
17+ import logging
18+
19+ logger = logging .getLogger ("django.request" )
20+
1721
1822class 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
2439class UserViewSet (viewsets .ModelViewSet ):
2540 """
You can’t perform that action at this time.
0 commit comments