Yet another SQL logger, this time with color and tresholds. By default it will only print a summary line (total time, query count) unless one of the tresholds (total time, query count, individual query time) was exceeded.
You may use LOG_COLORSQL_VERBOSE = True to get the raw SQL for all requests regardless of any configured tresholds.
In either case the middleware will highlight problematic areas in yellow or red.
If you don't like the colors you can either set your tresholds to really high values, edit the code, or use a different middleware. :-)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 | import sys
from django.db import connection
from time import *
class ColorSQLMiddleware:
"""
Color SQL logging middleware.
Prints a short summary (number of database queries and
total time) for each request. Additionally it will print
the raw SQL if any of the configurable tresholds are
exceeded, in order to draw your attention to pages
that trigger slow or too many queries.
The available tresholds are:
* Query count
* Total Time (for all SQL queries)
* Query Time (for individual SQL queries)
We're trying to keep the output readable by modest use of ANSI color.
Example output
==============
This is what you get for normal page views where
no treshold was exceeded:
----------------------------------------------------------------------
0.006s | 3 queries
----------------------------------------------------------------------
This is what you get for page views where one or more
tresholds have been exceeded. Please note that in reality the
SQL is *not* truncated. I did that by hand to keep this comment
readable:
----------------------------------------------------------------------
SELECT "django_session"."session_key","django_session"."session_data",
FROM "django_session"
WHERE ("django_session"."session_key" = '6495c82cf81b34dc0c4dbb91fc641
SELECT "core_userprofile"."id","core_userprofile"."user_id","core_user
FROM "core_userprofile" INNER JOIN "auth_user" AS "core_userprofile__u
WHERE ("core_userprofile__user"."username" = 'sook')
SELECT "auth_user"."id","auth_user"."username","auth_user"."first_name
f","auth_user"."is_active","auth_user"."is_superuser","auth_user"."las
FROM "auth_user"
WHERE ("auth_user"."id" = 55)
SELECT "auth_user"."id","auth_user"."username","auth_user"."first_name
f","auth_user"."is_active","auth_user"."is_superuser","auth_user"."las
FROM "auth_user"
WHERE ("auth_user"."id" = 55)
SELECT "auth_message"."id","auth_message"."user_id","auth_message"."me
FROM "auth_message"
WHERE ("auth_message"."user_id" = 55)
----------------------------------------------------------------------
0.176s | 5 queries
----------------------------------------------------------------------
Installation
============
Simply put this into your middleware/ directory,
into a file called "colorsql.py".
Then edit your settings.py to enable the middleware:
MIDDLEWARE_CLASSES = (
...
'YOURPATH.colorsql.ColorSQLMiddleware',
...
)
Finally you may tweak the various options in
settings.py, see below.
Options in settings.py (with defaults)
======================================
LOG_COLORSQL_ENABLE = True (boolean)
-------------------
True == Enable the middleware (default)
False == Disable the middleware, nothing will be printed
LOG_COLORSQL_VERBOSE = False (boolean)
--------------------
True == The SQL will always be printed.
False == The SQL will only be printed if one of the tresholds is
exceeded
LOG_COLORSQL_WARN_TOTALTIME = 0.5 (float)
---------------------------
If the total time for all db queries exceeds
this value (in seconds) then the SQL will
be printed and the measured time in the summary-
line will be printed in YELLOW.
LOG_COLORSQL_ALERT_TOTALTIME = 1.0 (float)
----------------------------
If the total time for all db queries exceeds
this value (in seconds) then the SQL will
be printed and the measured time in the summary-
line will be printed in RED.
LOG_COLORSQL_WARN_TOTALCOUNT = 6 (integer)
----------------------------
If the number of db queries exceeds this value
then the SQL will be printed and the query-count
in the summary line will be printed in YELLOW.
LOG_COLORSQL_ALERT_TOTALCOUNT = 10 (integer)
-----------------------------
If the number of db queries exceeds this value
then the SQL will be printed and the query-count
in the summary line will be printed in RED.
LOG_COLORSQL_WARN_TIME = 0.05 (float)
----------------------
If the time for any individual db query exceeds
this value (in seconds) then the SQL will be
printed and the offending query be highlighted
in YELLOW.
LOG_COLORSQL_ALERT_TIME = 0.20 (float)
-----------------------
If the time for any individual db query exceeds
this value (in seconds) then the SQL will be
printed and the offending query be highlighted
in RED.
"""
def process_response ( self, request, response ):
from django.conf import settings
enable = getattr( settings, 'LOG_COLORSQL_ENABLE', True )
if False == enable:
return response
verbose = getattr( settings, 'LOG_COLORSQL_VERBOSE', False )
timewarn = getattr( settings, 'LOG_COLORSQL_WARN_TOTALTIME', 0.5 )
timealert = getattr( settings, 'LOG_COLORSQL_ALERT_TOTALTIME', 1.0 )
countwarn = getattr( settings, 'LOG_COLORSQL_WARN_TOTALCOUNT', 6 )
countalert = getattr( settings, 'LOG_COLORSQL_ALERT_TOTALCOUNT', 10 )
qtimewarn = getattr( settings, 'LOG_COLORSQL_WARN_TIME', 0.05 )
qtimealert = getattr( settings, 'LOG_COLORSQL_ALERT_TIME', 0.20 )
# sanity checks...
if qtimealert < qtimewarn:
qtimewarn = qtimealert
if countalert < countwarn:
countwarn = countalert
if timealert < timewarn:
timewarn = timealert
ttime = 0.0
for q in connection.queries:
time = float(q['time'])
ttime = ttime + time
if qtimewarn < time:
verbose = True
count = len(connection.queries)
if timewarn <= ttime or countwarn <= count:
verbose = True
if verbose:
print "\033[0;30;1m"
print "-" * 70,
print "\033[0m"
i = 0
for q in connection.queries:
time = float(q['time'])
if verbose or timewarn <= ttime or countwarn <= count:
sql = q['sql']
sql = sql.replace( ' FROM ', '\nFROM ' ).replace( ' WHERE ', '\nWHERE ' )
tcolor = "\033[31m"
ptime = "\033[7m %ss \033[0m" % ( time )
if qtimealert > time:
tcolor = "\033[33m"
if qtimewarn > time:
tcolor = "\033[30;1m"
ptime = ""
print "%s%s" % ( tcolor, sql ),
print "%s\033[1m%s\033[0m" % ( tcolor, ptime )
i = i + 1
if i < len(connection.queries):
print
sys.stdout.write( "\033[0;30;1m" )
print "-" * 70,
print "\033[35;1m"
time = ttime
tcolor = "\033[31;1m"
if timealert > time:
tcolor = "\033[33;1m"
if timewarn > time:
tcolor = "\033[30;1m"
ccolor = "\033[31;1m"
if countalert > count:
ccolor = "\033[33;1m"
if countwarn > count:
ccolor = "\033[30;1m"
print "%s %.3fs \033[30;1m| %s%d queries\033[0m" % ( tcolor, time, ccolor, count )
sys.stdout.write( "\033[0;30;1m" )
print "-" * 70,
print "\033[0m"
return response
|
More like this
- Template tag - list punctuation for a list of items by shapiromatron 10 months, 2 weeks ago
- JSONRequestMiddleware adds a .json() method to your HttpRequests by cdcarter 10 months, 3 weeks ago
- Serializer factory with Django Rest Framework by julio 1 year, 5 months ago
- Image compression before saving the new model / work with JPG, PNG by Schleidens 1 year, 6 months ago
- Help text hyperlinks by sa2812 1 year, 7 months ago
Comments
Please login first before commenting.