Reputation: 71
I have a custom Logging handler that I want to handle all logging message levels (INFO, WARN, DEBUG, ERROR, etc.) and send that to a data analytics server. For each message, the data will include fields on the record and on the original request object.
The problem is that I have not seen the request object attached to any of the records. I found on the official documentation that only django.request messages have the request object attached to the record, but no mention of what specifically django.request messages are. (https://docs.djangoproject.com/en/1.9/topics/logging/#django-request).
What are django.request messages? How/When are they fired? How can I reroute every logging message to have the request object on it so that my handler can attach that data that will be sent to a proxy server?
----handler----
class LogHandler(logging.Handler):
request = None
def __init__(self, request=None):
logging.Handler.__init__(self)
def parse_record_to_json(self, record):
import json
created = datetime.datetime.fromtimestamp(record.created)
return {
'timestamp': created.strftime('%m/%d/%Y %H:%M:%S'),
'method': record.funcName,
'level': record.levelname,
'line': record.lineno,
'module': record.module,
'message': record.getMessage(),
'path': record.pathname,
}
def emit(self, record):
user_id = None
try:
self.request = record.request
if self.request.user.is_authenticated():
user_id = self.request.user.id
except:
print "this must not be a django.request message"
self.request = None
from .event import SendEvent
json_record = self.parse_record_to_json(record)
level = json_record.pop('level', None)
SendEvent(key="server_log",
name=level,
request=self.request,
obj=json_record,
user=user_id)
-----settings.py-----
LOGGING = {
'version': 1,
'disable_existing_loggers': False,
'formatters': {
'standard': {
'format': '%(levelname)s %(name)s %(asctime)s %(filename)s:%(lineno)s] %(message)s',
},
},
'handlers': {
'console': {
'class': 'logging.StreamHandler',
'formatter': 'standard',
},
'null': {
'level': 'DEBUG',
'class': 'django.utils.log.NullHandler',
},
'splunk':{
'class':'proj.common.handlers.LogHandler',
}
},
# 'root': {
# 'handlers': ['console', 'loghandler',],
# 'level': 'INFO',
# 'formatter':'standard',
# },
'loggers': {
'django':{
'handlers':['console'],
'level':'INFO',
'formatter':'standard',
},
'py.warnings':{
'handlers': ['null',],
'propagate': False,
},
'django.request':{
'handlers':['console','loghandler'],
'propogate':False,
},
}
}
Upvotes: 7
Views: 2857
Reputation: 32307
To answer the “what is a django.request
message”: The django.request
logger is one of the Python loggers provided with Django. So, a django.request
message is a log message sent to the django.request
logger. As you've found, the Django documentation says:
Messages to this logger have the following extra context:
status_code
: The HTTP response code associated with the request.request
: The request object that generated the logging message.
What may not be obvious is that “extra context” is provided with the logging message, and those items become attributes on the LogRecord
instance.
So yes, in the LogHandler.emit
method you defined, the record
parameter is the LogRecord
. The record.request
attribute will be the HTTP request object, if the record was created on the django.request
logger.
Your LogHandler
will only receive messages if you direct them there, for example via the Django setting LOGGING['loggers']['django.request']['handlers']
.
Upvotes: 2