Skip to content

Instantly share code, notes, and snippets.

@ionelmc
Last active December 27, 2015 12:49
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ionelmc/7328674 to your computer and use it in GitHub Desktop.
Save ionelmc/7328674 to your computer and use it in GitHub Desktop.
Dead-simple Django SQL logging
import sys
try:
from sqlparse import format as sqlformat
except ImportError:
sqlformat = lambda s, reindent=None: s
from traceback import format_stack
class WithStacktrace(object):
def __init__(self, skip=[], limit=5):
self.skip = [__name__, 'logging']
self.skip.extend(skip)
self.limit = limit
def filter(self, record):
if not hasattr(record, 'stack_patched'):
frame = sys._getframe(1)
if self.skip:
while [skip for skip in self.skip if frame.f_globals.get('__name__', '').startswith(skip)]:
frame = frame.f_back
if hasattr(record, 'sql'):
record.msg = "\x1b[31mduration: %s%.4f secs\x1b[0m, \x1b[33marguments: %s%s\x1b[0m\n \x1b[1;33m%s\x1b[0m\n -- stack: \n\x1b[32m%s\x1b[0m" % (
"\x1b[31m" if record.duration < 0.1 else "\x1b[1;31m", record.duration,
"\x1b[1;33m" if record.params else '', record.params,
'\n '.join(sqlformat(record.sql, reindent=True).strip().splitlines()),
''.join(format_stack(f=frame, limit=self.limit)).rstrip()
)
else:
record.msg += "\n -- stack: \n\x1b[32m%s\x1b[0m" % (
''.join(format_stack(f=frame, limit=self.limit)).rstrip()
)
record.stack_patched = True
return True
LOGGING['loggers']['django.db.backends'] = {
'level': 'DEBUG',
'filters': ['add_stack'],
}
LOGGING.setdefault('filters', {})['add_stack'] = {
'()': WithStacktrace,
'skip': ("django.", "south.", "__main__"),
'limit': 1,
}
import sys
import sqlparse
from traceback import format_stack
from pygments import highlight, lex
from pygments.lexers import SqlLexer, PythonTracebackLexer
from pygments.formatters import Terminal256Formatter, TerminalFormatter
class WithStacktrace(object):
_term_formatter = TerminalFormatter(bg='dark')
_sql_lexer = SqlLexer()
_tb_lexer = PythonTracebackLexer()
def __init__(self, skip=(), limit=5):
self.skip = [__name__, 'logging']
self.skip.extend(skip)
self.limit = limit
def filter(self, record):
if not hasattr(record, 'stach_patched'):
frame = sys._getframe(1)
if self.skip:
while frame and [m for m in self.skip if frame.f_globals.get('__name__', '').startswith(m)]:
frame = frame.f_back
if hasattr(record, 'duration') and hasattr(record, 'sql') and hasattr(record, 'params'):
if record.duration < 0.1:
record.msg = "\x1b[31mduration: %.4f secs\x1b[0m" % record.duration
else:
record.msg = "\x1b[31mduration: \x1b[1;31m%.4f secs\x1b[0m" % record.duration
if record.params:
record.msg += ", \x1b[33marguments: \x1b[1;33m%s\x1b[0m" % (record.params, )
else:
record.msg += ", \x1b[33marguments: %s\x1b[0m" % (record.params, )
sql = record.sql
try:
sql = '\n '.join(sqlparse.format(sql, reindent=True).strip().splitlines())
sql = highlight(sql, self._sql_lexer, self._term_formatter)
except Exception as ex:
pass
record.msg += "\n \x1b[1;33m%s\x1b[0m" % sql
if frame:
tb = ''.join(format_stack(f=frame, limit=self.limit))
try:
record.msg += "\n -- stack: \n%s" % highlight(tb, self._tb_lexer, self._term_formatter)
except Exception as ex:
record.msg += "\n -- stack: \n\x1b[32m%s\x1b[0m" % tb
record.stach_patched = True
return 1
LOGGING['loggers']['django.db.backends'] = {
'level': 'DEBUG',
'filters': ['add_stack'],
}
LOGGING.setdefault('filters', {})['add_stack'] = {
'()': WithStacktrace,
'skip': ("django.", "south.", "__main__"),
'limit': 1,
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment