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,
},
}
}
Django uses request and response objects to pass state through the system. When a page is requested, Django creates an HttpRequest object that contains metadata about the request. Then Django loads the appropriate view, passing the HttpRequest as the first argument to the view function.
The Django One-Click application employs Gunicorn and Upstart. Application level logging can be found in /var/log/upstart/gunicorn. log By default, Gunicorn logs to stderr and Upstart will collect output to stderr/stdout in /var/log/upstart/$JOB_NAME.
If you don't want to configure logging at all (or you want to manually configure logging using your own approach), you can set LOGGING_CONFIG to None . This will disable the configuration process for Django's default logging.
A logger is the entry point into the logging system. Each logger is a named bucket to which messages can be written for processing. A logger is configured to have a log level. This log level describes the severity of the messages that the logger will handle.
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']
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With