forked from adamlaska/datatracker
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathlog.py
More file actions
145 lines (127 loc) · 4.98 KB
/
log.py
File metadata and controls
145 lines (127 loc) · 4.98 KB
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
# Copyright The IETF Trust 2007-2019, All Rights Reserved
# -*- coding: utf-8 -*-
from __future__ import absolute_import, print_function, unicode_literals
import sys
import logging
import inspect
import os.path
import six
import traceback
if six.PY3:
from typing import Callable # pyflakes:ignore
try:
import syslog
logfunc = syslog.syslog # type: Callable
except ImportError: # import syslog will fail on Windows boxes
logging.basicConfig(filename='tracker.log',level=logging.INFO)
logfunc = logging.info
pass
from django.conf import settings
import debug # pyflakes:ignore
def getclass(frame):
cls = None
argnames, varargs, varkw, defaults = inspect.getargvalues(frame)
if len(argnames) > 0:
selfname = argnames[0]
cls = defaults[selfname].__class__
return cls
def getcaller():
parent, pfile, pline, pfunction, lines, index = inspect.stack()[2]
pmodule = inspect.getmodulename(pfile)
pclass = getclass(parent)
return (pmodule, pclass, pfunction, pfile, pline)
def log(msg, e=None):
"Uses syslog by preference. Logs the given calling point and message."
global logfunc
def _flushfunc():
pass
_logfunc = logfunc
if settings.SERVER_MODE == 'test':
## Comment in when debugging for instance test smtp server failures:
# if e:
# _logfunc = debug.say
# _flushfunc = sys.stdout.flush # pyflakes:ignore (intentional redefinition)
# else:
return
elif settings.DEBUG == True:
_logfunc = debug.say
_flushfunc = sys.stdout.flush # pyflakes:ignore (intentional redefinition)
if isinstance(msg, six.text_type):
msg = msg.encode('unicode_escape')
try:
mod, cls, func, file, line = getcaller()
file = os.path.abspath(file)
file = file.replace(settings.BASE_DIR, "")
if func == "<module>":
where = ""
else:
where = " in " + func + "()"
except IndexError:
file, line, where = "/<UNKNOWN>", 0, ""
_flushfunc()
_logfunc("ietf%s(%d)%s: %s" % (file, line, where, msg))
logger = logging.getLogger('django')
def exc_parts():
info = sys.exc_info()
extype = info[0]
value = info[1]
tb = traceback.format_tb(info[2])
return (extype, value, tb)
def build_traceback(stack):
"""
Build something that looks sufficiently like a traceback to be passed to a
logging.logger as the exc_info argument.
"""
class Traceback():
pass
next = None
for frame_record in stack:
fr_frame, fr_filename, fr_lineno, fr_funcname, fr_context, fr_context_this = frame_record
tb = Traceback()
tb.tb_frame = fr_frame
tb.tb_lasti = fr_frame.f_lasti
tb.tb_lineno = fr_lineno
tb.tb_next = next
next = tb
# Stop traceback at _get_response() -- we don't want to see the
# middleware, debug server, or wsgi internals when the exception
# occurs in our app code, below _get_response():
if fr_funcname == '_get_response' and fr_filename.endswith('django/core/handlers/base.py'):
break
return tb
def assertion(statement, state=True):
"""
This acts like an assertion. It uses the django logger in order to send
the failed assertion and a backtrace as for an internal server error.
"""
stack = inspect.stack()[1:]
frame = stack[0][0]
value = eval(statement, frame.f_globals, frame.f_locals)
if bool(value) != bool(state):
if (settings.DEBUG is True) or (settings.SERVER_MODE == 'test') :
raise AssertionError("Assertion failed: '%s': %s != %s." % (statement, repr(value), state))
else:
# build a simulated traceback object
tb = build_traceback(stack)
# provide extra info if available
extra = {}
for key in [ 'request', 'status_code', ]:
if key in frame.f_locals:
extra[key] = frame.f_locals[key]
logger.error("Assertion failed: '%s': %s != %s", statement, repr(value), state, exc_info=(AssertionError, statement, tb), extra=extra)
def unreachable(date="(unknown)"):
"Raises an assertion or sends traceback to admins if executed."
stack = inspect.stack()[1:]
frame = stack[0][0]
if settings.DEBUG is True or settings.SERVER_MODE == 'test':
raise AssertionError("Arrived at code in %s() which was marked unreachable on %s." % (frame.f_code.co_name, date))
else:
# build a simulated traceback object
tb = build_traceback(stack)
# provide extra info if available
extra = {}
for key in [ 'request', 'status_code', ]:
if key in frame.f_locals:
extra[key] = frame.f_locals[key]
logger.error("Arrived at code in %s() which was marked unreachable on %s." % (frame.f_code.co_name, date),
exc_info=(AssertionError, frame.f_code.co_name, tb), extra=extra)