Skip to content
This repository
Newer
Older
100644 200 lines (159 sloc) 6.839 kb
06808c25 » sjl
2012-06-21 Strip Google Analytics cookies to prepare for session caching.
1 import re
764b9365 » sjl
2012-05-21 Organize imports.
2 import random
8a3ff924 » aduston
2010-12-28 Fixes browser_id issue for http://bugzilla.pculture.org/show_bug.cgi?…
3 import time
4
764b9365 » sjl
2012-05-21 Organize imports.
5 import debug_toolbar
1ce78372 » sjl
2012-06-15 Remove SqlPrintingMiddleware
6 import django.db.backends.mysql.base
764b9365 » sjl
2012-05-21 Organize imports.
7 from debug_toolbar.middleware import DebugToolbarMiddleware
d1e30a3d » aduston
2010-08-13 Added all P3P stuff. For http://bugzilla.pculture.org/show_bug.cgi?id…
8 from django.conf import settings
764b9365 » sjl
2012-05-21 Organize imports.
9 from django.core.exceptions import ValidationError
10 from django.core.validators import validate_ipv4_address
1ce78372 » sjl
2012-06-15 Remove SqlPrintingMiddleware
11 from django.db.backends.mysql.base import CursorWrapper as _CursorWrapper
5323ed5f » Alerion
2010-10-26 add UserUUIDMiddleware, http://bugzilla.pculture.org/show_bug.cgi?id=…
12 from django.utils.cache import patch_vary_headers
764b9365 » sjl
2012-05-21 Organize imports.
13 from django.utils.hashcompat import sha_constructor
8a3ff924 » aduston
2010-12-28 Fixes browser_id issue for http://bugzilla.pculture.org/show_bug.cgi?…
14 from django.utils.http import cookie_date
764b9365 » sjl
2012-05-21 Organize imports.
15
7ff8f8ce » sjl
2012-05-23 Fire timer meters manually, and record both req starts/ends.
16 from utils.metrics import ManualTimer, Meter, Timer
764b9365 » sjl
2012-05-21 Organize imports.
17
59005cef » aduston
2010-12-10 Resolved rpc.py conflict in merge
18
37e6c37b » sjl
2012-05-21 Add metrics for some common top-level site sections.
19 SECTIONS = {
20 'widget': 'widget',
21 'api': 'api-v1',
d5b3e36a » sjl
2012-05-21 Spell "api2" correctly.
22 'api2': 'api-v2',
37e6c37b » sjl
2012-05-21 Add metrics for some common top-level site sections.
23 'teams': 'teams',
24 }
25
26
604aad1f » Alerion
2011-01-05 add saving user's IP, http://127.0.0.1:8000/en/videos/k5v76tsojVLo/
27 class SaveUserIp(object):
28 def process_request(self, request):
29 if request.user.is_authenticated():
30 ip = request.META.get('REMOTE_ADDR', '')
31 try:
32 validate_ipv4_address(ip)
33 if request.user.last_ip != ip:
34 request.user.last_ip = ip
35 request.user.save()
36 except ValidationError:
37 pass
4a4e895c » aduston
2011-04-29 Added site timing stats to GA. For https://www.pivotaltracker.com/sto…
38
39 class ResponseTimeMiddleware(object):
37e6c37b » sjl
2012-05-21 Add metrics for some common top-level site sections.
40 """Middleware for recording response times.
41
42 Writes the time this request took to process, as a cookie in the response.
43 In order for it to work, it must be the very first middleware in settings.py
9080f233 » sjl
2012-05-08 Metrics!
44
9c85e14c » sjl
2012-06-15 Track HTTP response codes as metrics
45 Also records the response type and time and sends them along to Riemann.
37e6c37b » sjl
2012-05-21 Add metrics for some common top-level site sections.
46
47 If the request was for a section of the site we want to track, sends that
48 information to Riemann as well.
49
4a4e895c » aduston
2011-04-29 Added site timing stats to GA. For https://www.pivotaltracker.com/sto…
50 """
51 def process_request(self, request):
52 request.init_time = time.time()
7ff8f8ce » sjl
2012-05-23 Fire timer meters manually, and record both req starts/ends.
53 Meter('requests.started').inc()
37e6c37b » sjl
2012-05-21 Add metrics for some common top-level site sections.
54
55 # Tracking the section of the site isn't trivial, because sometimes we
56 # have the language prefix, like "/en/foo".
57 paths = request.path.lstrip('/').split('/')[:2]
58 p1 = paths[0] if len(paths) >= 1 else None
59 p2 = paths[1] if len(paths) >= 2 else None
60
61 if p1 in SECTIONS:
62 request._metrics_section = SECTIONS[paths[0]]
63 elif p2 in SECTIONS:
64 request._metrics_section = SECTIONS[paths[1]]
65 else:
66 request._metrics_section = None
67
600efccb » sjl
2012-05-23 Restore req/sec metering for site sections.
68 if request._metrics_section:
69 label = 'site-sections.%s-response-time' % request._metrics_section
70 Meter(label).inc()
71
4a4e895c » aduston
2011-04-29 Added site timing stats to GA. For https://www.pivotaltracker.com/sto…
72 return None
73
74 def process_response(self, request, response):
75 if hasattr(request, "init_time"):
76 delta = time.time() - request.init_time
9080f233 » sjl
2012-05-08 Metrics!
77 ms = delta * 1000
37e6c37b » sjl
2012-05-21 Add metrics for some common top-level site sections.
78
7ff8f8ce » sjl
2012-05-23 Fire timer meters manually, and record both req starts/ends.
79 Meter('requests.completed').inc()
80
9c85e14c » sjl
2012-06-15 Track HTTP response codes as metrics
81 try:
82 response_type = response.status_code / 100 * 100
83 except:
84 response_type = 'unknown'
85 Meter('requests.response-types.%s' % response_type).inc()
86
9080f233 » sjl
2012-05-08 Metrics!
87 response.set_cookie('response_time', str(ms))
37e6c37b » sjl
2012-05-21 Add metrics for some common top-level site sections.
88
9080f233 » sjl
2012-05-08 Metrics!
89 ManualTimer('response-time').record(ms)
90
37e6c37b » sjl
2012-05-21 Add metrics for some common top-level site sections.
91 if request._metrics_section:
92 label = 'site-sections.%s-response-time' % request._metrics_section
93 ManualTimer(label).record(ms)
94
4a4e895c » aduston
2011-04-29 Added site timing stats to GA. For https://www.pivotaltracker.com/sto…
95 return response
9080f233 » sjl
2012-05-08 Metrics!
96
5323ed5f » Alerion
2010-10-26 add UserUUIDMiddleware, http://bugzilla.pculture.org/show_bug.cgi?id=…
97 class P3PHeaderMiddleware(object):
d1e30a3d » aduston
2010-08-13 Added all P3P stuff. For http://bugzilla.pculture.org/show_bug.cgi?id…
98 def process_response(self, request, response):
99 response['P3P'] = settings.P3P_COMPACT
100 return response
5323ed5f » Alerion
2010-10-26 add UserUUIDMiddleware, http://bugzilla.pculture.org/show_bug.cgi?id=…
101
102
103 # Got this from CsrfViewMiddleware
104 # Use the system (hardware-based) random number generator if it exists.
105 if hasattr(random, 'SystemRandom'):
106 randrange = random.SystemRandom().randrange
107 else:
108 randrange = random.randrange
9080f233 » sjl
2012-05-08 Metrics!
109
5323ed5f » Alerion
2010-10-26 add UserUUIDMiddleware, http://bugzilla.pculture.org/show_bug.cgi?id=…
110 _MAX_CSRF_KEY = 18446744073709551616L # 2 << 63
111
112 UUID_COOKIE_NAME = getattr(settings, 'UUID_COOKIE_NAME', 'unisub-user-uuid')
113 UUID_COOKIE_DOMAIN = getattr(settings, 'UUID_COOKIE_DOMAIN', None)
114
115 def _get_new_csrf_key():
116 return sha_constructor("%s%s"
117 % (randrange(0, _MAX_CSRF_KEY), settings.SECRET_KEY)).hexdigest()
118
119 class UserUUIDMiddleware(object):
d41a2edb » Alerion
2010-10-26 fix UserUUIDMiddleware
120 def process_request(self, request):
5323ed5f » Alerion
2010-10-26 add UserUUIDMiddleware, http://bugzilla.pculture.org/show_bug.cgi?id=…
121 try:
d41a2edb » Alerion
2010-10-26 fix UserUUIDMiddleware
122 request.browser_id = request.COOKIES[UUID_COOKIE_NAME]
5323ed5f » Alerion
2010-10-26 add UserUUIDMiddleware, http://bugzilla.pculture.org/show_bug.cgi?id=…
123 except KeyError:
043736b9 » Alerion
2010-12-28 fix UserUUIDMiddleware
124 # No cookie or it is empty, so create one. This will be sent with the next
9080f233 » sjl
2012-05-08 Metrics!
125 # response.
8a3ff924 » aduston
2010-12-28 Fixes browser_id issue for http://bugzilla.pculture.org/show_bug.cgi?…
126 if not hasattr(request, 'browser_id'):
043736b9 » Alerion
2010-12-28 fix UserUUIDMiddleware
127 request.browser_id = _get_new_csrf_key()
5323ed5f » Alerion
2010-10-26 add UserUUIDMiddleware, http://bugzilla.pculture.org/show_bug.cgi?id=…
128
129 def process_response(self, request, response):
3b67e122 » Alerion
2010-11-01 add load_staging command for users loading
130 if hasattr(request, 'browser_id'):
131 browser_id = request.browser_id
8a3ff924 » aduston
2010-12-28 Fixes browser_id issue for http://bugzilla.pculture.org/show_bug.cgi?…
132 if request.COOKIES.get(UUID_COOKIE_NAME) != browser_id:
133 max_age = 60 * 60 * 24 * 365
134 response.set_cookie(
135 UUID_COOKIE_NAME,
9080f233 » sjl
2012-05-08 Metrics!
136 browser_id,
8a3ff924 » aduston
2010-12-28 Fixes browser_id issue for http://bugzilla.pculture.org/show_bug.cgi?…
137 max_age=max_age,
138 expires=cookie_date(time.time() + max_age),
139 domain=UUID_COOKIE_DOMAIN)
5323ed5f » Alerion
2010-10-26 add UserUUIDMiddleware, http://bugzilla.pculture.org/show_bug.cgi?id=…
140 # Content varies with the CSRF cookie, so set the Vary header.
141 patch_vary_headers(response, ('Cookie',))
9080f233 » sjl
2012-05-08 Metrics!
142 return response
59005cef » aduston
2010-12-10 Resolved rpc.py conflict in merge
143
02014abe » Alerion
2011-03-23 update debug_toolbar to be used by superuser without setting INTERNAL…
144
765776c0 » sjl
2012-05-21 Add metrics for database query time and rate.
145 # I'm so sorry about this.
146 class MetricsCursorWrapper(_CursorWrapper):
b5deb70d » sjl
2012-05-21 Add metrics for various types of SQL queries.
147 def _query_type(self, query):
b784cacf » sjl
2012-05-21 Null check the query type metrics check.
148 if not query:
149 return 'UNKNOWN'
150 elif query.startswith('SELECT COUNT(*) '):
b5deb70d » sjl
2012-05-21 Add metrics for various types of SQL queries.
151 return 'COUNT'
152 elif query.startswith('SELECT '):
153 return 'SELECT'
154 elif query.startswith('DELETE '):
155 return 'DELETE'
156 elif query.startswith('INSERT '):
157 return 'INSERT'
158 elif query.startswith('UPDATE '):
159 return 'UPDATE'
160 else:
161 return 'OTHER'
162
765776c0 » sjl
2012-05-21 Add metrics for database query time and rate.
163 def execute(self, query, params=None):
b5deb70d » sjl
2012-05-21 Add metrics for various types of SQL queries.
164 op = self._query_type(query)
165
765776c0 » sjl
2012-05-21 Add metrics for database query time and rate.
166 with Timer('db-query-time'):
b5deb70d » sjl
2012-05-21 Add metrics for various types of SQL queries.
167 with Timer('db-query-time.%s' % op):
168 return super(MetricsCursorWrapper, self).execute(query, params)
765776c0 » sjl
2012-05-21 Add metrics for database query time and rate.
169
170 def executemany(self, query, params_list):
b5deb70d » sjl
2012-05-21 Add metrics for various types of SQL queries.
171 op = self._query_type(query)
765776c0 » sjl
2012-05-21 Add metrics for database query time and rate.
172 start = time.time()
173
174 try:
175 return super(MetricsCursorWrapper, self).executemany(query, params_list)
176 finally:
177 end = time.time()
178 delta = end - start
179 ms = delta * 1000
180
181 # This is an ugly hack to get at least a rough measurement of query
182 # times for executemany() queries.
183 ms_per_query = ms / len(params_list)
184
185 for _ in xrange(len(params_list)):
186 ManualTimer('db-query-time').record(ms_per_query)
b5deb70d » sjl
2012-05-21 Add metrics for various types of SQL queries.
187 ManualTimer('db-query-time.%s' % op).record(ms_per_query)
765776c0 » sjl
2012-05-21 Add metrics for database query time and rate.
188
189 django.db.backends.mysql.base.CursorWrapper = MetricsCursorWrapper
190
06808c25 » sjl
2012-06-21 Strip Google Analytics cookies to prepare for session caching.
191
192 # http://www.randallmorey.com/blog/2010/feb/17/django-cache-sessions-and-google-analytics/
193 class StripGoogleAnalyticsCookieMiddleware(object):
194 strip_re = re.compile(r'(__utm.=.+?(?:; |$))')
195 def process_request(self, request):
196 try:
197 cookie = self.strip_re.sub('', request.META['HTTP_COOKIE'])
198 request.META['HTTP_COOKIE'] = cookie
199 except:
200 pass
Something went wrong with that request. Please try again.