3
3
from django .utils .deprecation import MiddlewareMixin
4
4
from django_prometheus .utils import PowersOf , Time , TimeSince
5
5
6
- requests_total = Counter (
7
- "django_http_requests_before_middlewares_total" ,
8
- "Total count of requests before middlewares run." ,
9
- )
10
- responses_total = Counter (
11
- "django_http_responses_before_middlewares_total" ,
12
- "Total count of responses before middlewares run." ,
13
- )
14
- requests_latency_before = Histogram (
15
- "django_http_requests_latency_including_middlewares_seconds" ,
16
- (
17
- "Histogram of requests processing time (including middleware "
18
- "processing time)."
19
- ),
20
- )
21
- requests_unknown_latency_before = Counter (
22
- "django_http_requests_unknown_latency_including_middlewares_total" ,
23
- (
24
- "Count of requests for which the latency was unknown (when computing "
25
- "django_http_requests_latency_including_middlewares_seconds)."
26
- ),
27
- )
28
6
7
+ def _register_metric (cls , name , documentation , labelnames = tuple (), ** kwargs ):
8
+ return cls (name , documentation , labelnames = labelnames , ** kwargs )
29
9
30
- class PrometheusBeforeMiddleware (MiddlewareMixin ):
31
10
11
+ class Metrics :
12
+ _instance = None
13
+
14
+ @classmethod
15
+ def get_instance (cls ):
16
+ if not cls ._instance :
17
+ cls ._instance = cls ()
18
+ return cls ._instance
19
+
20
+ def __init__ (self , * args , ** kwargs ):
21
+ self .register ()
22
+
23
+ def register (self ):
24
+ self .requests_total = _register_metric (
25
+ Counter ,
26
+ "django_http_requests_before_middlewares_total" ,
27
+ "Total count of requests before middlewares run." ,
28
+ )
29
+ self .responses_total = _register_metric (
30
+ Counter ,
31
+ "django_http_responses_before_middlewares_total" ,
32
+ "Total count of responses before middlewares run." ,
33
+ )
34
+ self .requests_latency_before = _register_metric (
35
+ Histogram ,
36
+ "django_http_requests_latency_including_middlewares_seconds" ,
37
+ (
38
+ "Histogram of requests processing time (including middleware "
39
+ "processing time)."
40
+ ),
41
+ )
42
+ self .requests_unknown_latency_before = _register_metric (
43
+ Counter ,
44
+ "django_http_requests_unknown_latency_including_middlewares_total" ,
45
+ (
46
+ "Count of requests for which the latency was unknown (when computing "
47
+ "django_http_requests_latency_including_middlewares_seconds)."
48
+ ),
49
+ )
50
+ self .requests_latency_by_view_method = _register_metric (
51
+ Histogram ,
52
+ "django_http_requests_latency_seconds_by_view_method" ,
53
+ "Histogram of request processing time labelled by view." ,
54
+ ["view" , "method" ],
55
+ buckets = (
56
+ 0.01 ,
57
+ 0.025 ,
58
+ 0.05 ,
59
+ 0.075 ,
60
+ 0.1 ,
61
+ 0.25 ,
62
+ 0.5 ,
63
+ 0.75 ,
64
+ 1.0 ,
65
+ 2.5 ,
66
+ 5.0 ,
67
+ 7.5 ,
68
+ 10.0 ,
69
+ 25.0 ,
70
+ 50.0 ,
71
+ 75.0 ,
72
+ float ("inf" ),
73
+ ),
74
+ )
75
+ self .requests_unknown_latency = _register_metric (
76
+ Counter ,
77
+ "django_http_requests_unknown_latency_total" ,
78
+ "Count of requests for which the latency was unknown." ,
79
+ )
80
+ # Set in process_request
81
+ self .requests_ajax = _register_metric (
82
+ Counter , "django_http_ajax_requests_total" , "Count of AJAX requests."
83
+ )
84
+ self .requests_by_method = _register_metric (
85
+ Counter ,
86
+ "django_http_requests_total_by_method" ,
87
+ "Count of requests by method." ,
88
+ ["method" ],
89
+ )
90
+ self .requests_by_transport = _register_metric (
91
+ Counter ,
92
+ "django_http_requests_total_by_transport" ,
93
+ "Count of requests by transport." ,
94
+ ["transport" ],
95
+ )
96
+ # Set in process_view
97
+ self .requests_by_view_transport_method = _register_metric (
98
+ Counter ,
99
+ "django_http_requests_total_by_view_transport_method" ,
100
+ "Count of requests by view, transport, method." ,
101
+ ["view" , "transport" , "method" ],
102
+ )
103
+ self .requests_body_bytes = _register_metric (
104
+ Histogram ,
105
+ "django_http_requests_body_total_bytes" ,
106
+ "Histogram of requests by body size." ,
107
+ buckets = PowersOf (2 , 30 ),
108
+ )
109
+ # Set in process_template_response
110
+ self .responses_by_templatename = _register_metric (
111
+ Counter ,
112
+ "django_http_responses_total_by_templatename" ,
113
+ "Count of responses by template name." ,
114
+ ["templatename" ],
115
+ )
116
+ # Set in process_response
117
+ self .responses_by_status = _register_metric (
118
+ Counter ,
119
+ "django_http_responses_total_by_status" ,
120
+ "Count of responses by status." ,
121
+ ["status" ],
122
+ )
123
+ self .responses_by_status_view_method = _register_metric (
124
+ Counter ,
125
+ "django_http_responses_total_by_status_view_method" ,
126
+ "Count of responses by status, view, method." ,
127
+ ["status" , "view" , "method" ],
128
+ )
129
+ self .responses_body_bytes = _register_metric (
130
+ Histogram ,
131
+ "django_http_responses_body_total_bytes" ,
132
+ "Histogram of responses by body size." ,
133
+ buckets = PowersOf (2 , 30 ),
134
+ )
135
+ self .responses_by_charset = _register_metric (
136
+ Counter ,
137
+ "django_http_responses_total_by_charset" ,
138
+ "Count of responses by charset." ,
139
+ ["charset" ],
140
+ )
141
+ self .responses_streaming = _register_metric (
142
+ Counter ,
143
+ "django_http_responses_streaming_total" ,
144
+ "Count of streaming responses." ,
145
+ )
146
+ # Set in process_exception
147
+ self .exceptions_by_type = _register_metric (
148
+ Counter ,
149
+ "django_http_exceptions_total_by_type" ,
150
+ "Count of exceptions by object type." ,
151
+ ["type" ],
152
+ )
153
+ self .exceptions_by_view = _register_metric (
154
+ Counter ,
155
+ "django_http_exceptions_total_by_view" ,
156
+ "Count of exceptions by view." ,
157
+ ["view_name" ],
158
+ )
159
+
160
+
161
+ class PrometheusBeforeMiddleware (MiddlewareMixin ):
32
162
"""Monitoring middleware that should run before other middlewares."""
33
163
164
+ def __init__ (self , get_response = None ):
165
+ super (PrometheusBeforeMiddleware , self ).__init__ (get_response )
166
+ self .metrics = Metrics .get_instance ()
167
+
34
168
def process_request (self , request ):
35
- requests_total .inc ()
169
+ self . metrics . requests_total .inc ()
36
170
request .prometheus_before_middleware_event = Time ()
37
171
38
172
def process_response (self , request , response ):
39
- responses_total .inc ()
173
+ self . metrics . responses_total .inc ()
40
174
if hasattr (request , "prometheus_before_middleware_event" ):
41
- requests_latency_before .observe (
175
+ self . metrics . requests_latency_before .observe (
42
176
TimeSince (request .prometheus_before_middleware_event )
43
177
)
44
178
else :
45
- requests_unknown_latency_before .inc ()
179
+ self . metrics . requests_unknown_latency_before .inc ()
46
180
return response
47
181
48
182
49
- requests_latency_by_view_method = Histogram (
50
- "django_http_requests_latency_seconds_by_view_method" ,
51
- "Histogram of request processing time labelled by view." ,
52
- ["view" , "method" ],
53
- buckets = (
54
- 0.01 ,
55
- 0.025 ,
56
- 0.05 ,
57
- 0.075 ,
58
- 0.1 ,
59
- 0.25 ,
60
- 0.5 ,
61
- 0.75 ,
62
- 1.0 ,
63
- 2.5 ,
64
- 5.0 ,
65
- 7.5 ,
66
- 10.0 ,
67
- 25.0 ,
68
- 50.0 ,
69
- 75.0 ,
70
- float ("inf" ),
71
- ),
72
- )
73
- requests_unknown_latency = Counter (
74
- "django_http_requests_unknown_latency_total" ,
75
- "Count of requests for which the latency was unknown." ,
76
- )
77
- # Set in process_request
78
- ajax_requests = Counter ("django_http_ajax_requests_total" , "Count of AJAX requests." )
79
- requests_by_method = Counter (
80
- "django_http_requests_total_by_method" , "Count of requests by method." , ["method" ]
81
- )
82
- requests_by_transport = Counter (
83
- "django_http_requests_total_by_transport" ,
84
- "Count of requests by transport." ,
85
- ["transport" ],
86
- )
87
- # Set in process_view
88
- requests_by_view_transport_method = Counter (
89
- "django_http_requests_total_by_view_transport_method" ,
90
- "Count of requests by view, transport, method." ,
91
- ["view" , "transport" , "method" ],
92
- )
93
- requests_body_bytes = Histogram (
94
- "django_http_requests_body_total_bytes" ,
95
- "Histogram of requests by body size." ,
96
- buckets = PowersOf (2 , 30 ),
97
- )
98
- # Set in process_template_response
99
- responses_by_templatename = Counter (
100
- "django_http_responses_total_by_templatename" ,
101
- "Count of responses by template name." ,
102
- ["templatename" ],
103
- )
104
- # Set in process_response
105
- responses_by_status = Counter (
106
- "django_http_responses_total_by_status" , "Count of responses by status." , ["status" ]
107
- )
108
- responses_by_status_view_method = Counter (
109
- "django_http_responses_total_by_status_view_method" ,
110
- "Count of responses by status, view, method." ,
111
- ["status" , "view" , "method" ],
112
- )
113
- responses_body_bytes = Histogram (
114
- "django_http_responses_body_total_bytes" ,
115
- "Histogram of responses by body size." ,
116
- buckets = PowersOf (2 , 30 ),
117
- )
118
- responses_by_charset = Counter (
119
- "django_http_responses_total_by_charset" ,
120
- "Count of responses by charset." ,
121
- ["charset" ],
122
- )
123
- responses_streaming = Counter (
124
- "django_http_responses_streaming_total" , "Count of streaming responses."
125
- )
126
- # Set in process_exception
127
- exceptions_by_type = Counter (
128
- "django_http_exceptions_total_by_type" ,
129
- "Count of exceptions by object type." ,
130
- ["type" ],
131
- )
132
- exceptions_by_view = Counter (
133
- "django_http_exceptions_total_by_view" ,
134
- "Count of exceptions by view." ,
135
- ["view_name" ],
136
- )
137
-
138
-
139
183
class PrometheusAfterMiddleware (MiddlewareMixin ):
140
184
141
185
"""Monitoring middleware that should run after other middlewares."""
142
186
187
+ def __init__ (self , get_response = None ):
188
+ super (PrometheusAfterMiddleware , self ).__init__ (get_response )
189
+ self .metrics = Metrics .get_instance ()
190
+
143
191
def _transport (self , request ):
144
192
return "https" if request .is_secure () else "http"
145
193
@@ -162,12 +210,12 @@ def _method(self, request):
162
210
def process_request (self , request ):
163
211
transport = self ._transport (request )
164
212
method = self ._method (request )
165
- requests_by_method .labels (method ).inc ()
166
- requests_by_transport .labels (transport ).inc ()
213
+ self . metrics . requests_by_method .labels (method = method ).inc ()
214
+ self . metrics . requests_by_transport .labels (transport = transport ).inc ()
167
215
if request .is_ajax ():
168
- ajax_requests .inc ()
216
+ self . metrics . requests_ajax .inc ()
169
217
content_length = int (request .META .get ("CONTENT_LENGTH" ) or 0 )
170
- requests_body_bytes .observe (content_length )
218
+ self . metrics . requests_body_bytes .observe (content_length )
171
219
request .prometheus_after_middleware_event = Time ()
172
220
173
221
def _get_view_name (self , request ):
@@ -183,41 +231,49 @@ def process_view(self, request, view_func, *view_args, **view_kwargs):
183
231
method = self ._method (request )
184
232
if hasattr (request , "resolver_match" ):
185
233
name = request .resolver_match .view_name or "<unnamed view>"
186
- requests_by_view_transport_method .labels (name , transport , method ).inc ()
234
+ self .metrics .requests_by_view_transport_method .labels (
235
+ view = name , transport = transport , method = method
236
+ ).inc ()
187
237
188
238
def process_template_response (self , request , response ):
189
239
if hasattr (response , "template_name" ):
190
- responses_by_templatename .labels (str (response .template_name )).inc ()
240
+ self .metrics .responses_by_templatename .labels (
241
+ templatename = str (response .template_name )
242
+ ).inc ()
191
243
return response
192
244
193
245
def process_response (self , request , response ):
194
246
method = self ._method (request )
195
247
name = self ._get_view_name (request )
196
-
197
- responses_by_status .labels (str (response .status_code )).inc ()
198
- responses_by_status_view_method .labels (response .status_code , name , method ).inc ()
248
+ status = str (response .status_code )
249
+ self .metrics .responses_by_status .labels (status = status ).inc ()
250
+ self .metrics .responses_by_status_view_method .labels (
251
+ status = status , view = name , method = method
252
+ ).inc ()
199
253
if hasattr (response , "charset" ):
200
- responses_by_charset .labels (str (response .charset )).inc ()
254
+ self .metrics .responses_by_charset .labels (
255
+ charset = str (response .charset )
256
+ ).inc ()
201
257
if hasattr (response , "streaming" ) and response .streaming :
202
- responses_streaming .inc ()
258
+ self . metrics . responses_streaming .inc ()
203
259
if hasattr (response , "content" ):
204
- responses_body_bytes .observe (len (response .content ))
260
+ self . metrics . responses_body_bytes .observe (len (response .content ))
205
261
if hasattr (request , "prometheus_after_middleware_event" ):
206
- requests_latency_by_view_method .labels (
207
- view = name , method = request .method
262
+ self . metrics . requests_latency_by_view_method .labels (
263
+ view = self . _get_view_name ( request ) , method = request .method
208
264
).observe (TimeSince (request .prometheus_after_middleware_event ))
209
265
else :
210
- requests_unknown_latency .inc ()
266
+ self . metrics . requests_unknown_latency .inc ()
211
267
return response
212
268
213
269
def process_exception (self , request , exception ):
214
- name = self ._get_view_name (request )
215
- exceptions_by_type .labels (type (exception ).__name__ ).inc ()
270
+ self .metrics .exceptions_by_type .labels (type = type (exception ).__name__ ).inc ()
216
271
if hasattr (request , "resolver_match" ):
217
- exceptions_by_view .labels (name ).inc ()
272
+ name = request .resolver_match .view_name or "<unnamed view>"
273
+ self .metrics .exceptions_by_view .labels (view_name = name ).inc ()
218
274
if hasattr (request , "prometheus_after_middleware_event" ):
219
- requests_latency_by_view_method .labels (
220
- view = name , method = request .method
275
+ self . metrics . requests_latency_by_view_method .labels (
276
+ view = self . _get_view_name ( request ) , method = request .method
221
277
).observe (TimeSince (request .prometheus_after_middleware_event ))
222
278
else :
223
- requests_unknown_latency .inc ()
279
+ self . metrics . requests_unknown_latency .inc ()
0 commit comments