Django.request is not showing synchronous middleware as docs suggest - django

I've set up a very simple asynchronous view but it's not working. As per the Django instructions I want to check that it's not my middleware causing the issue. The Django docs say that the django.request logger will disclose which middleware is not working in async. Below is the quote from the official docs. I've set up the django.request logger and it logs an 4xx or 5xx errors (as expected) but that's all. Is this a mistake in the Django docs?
https://docs.djangoproject.com/en/4.0/topics/async/
You will only get the benefits of a fully-asynchronous request stack if you have no synchronous middleware loaded into your site. If there is a piece of synchronous middleware, then Django must use a thread per request to safely emulate a synchronous environment for it.
Middleware can be built to support both sync and async contexts. Some of Django’s middleware is built like this, but not all. To see what middleware Django has to adapt, you can turn on debug logging for the django.request logger and look for log messages about “Synchronous middleware … adapted”.
settings.py
LOGGING = {
'version': 1,
'disable_existing_loggers': False,
'handlers': {
'console': {
'level': 'DEBUG',
'class': 'logging.StreamHandler',
},
'file': {
'level': 'DEBUG',
'class': 'logging.FileHandler',
'filename': 'logs/debug.log',
},
},
'root': {
'handlers': ['console'],
'level': 'WARNING',
},
'loggers': {
'django.request': {
#'handlers': ['file','console'],
'handlers': ['file'],
'level': 'DEBUG',
'propagate': True,
},
},
}

Related

How to setup django logging to console

I know there is a very similar question. That one is six years old and the answer in that one doesn't help me. All I want is to know how to configure django so that it can log to the console.
This are my settings:
LOGGING = {
'version': 1,
'disable_existing_loggers': False,
'handlers': {
'console': {
'class': 'logging.StreamHandler',
},
},
'loggers': {
'django': {
'handlers': ['console'],
'level': os.getenv('DJANGO_LOG_LEVEL', 'INFO'),
},
},
}
And in my view I have this:
class Home(TemplateView):
template_name = "inicio/magic_py.html"
def get_context_data(self, **kwargs):
logger = logging.getLogger("django")
logger.debug("home!!!!!!")
print("home?")
The console doesn't show the log.debug, it only shows the print. What am I missing? please help.
I use django 1.10
DEBUG log level is lower than INFO so your logs are being filtered out, you'll need to either lower your log level to DEBUG or you need to log using logger.info() or higher.

Use Logging SocketHandler with Django

I've configured my logging as so:
LOGGING = {
'version': 1,
'disable_existing_loggers': False,
'handlers': {
'console': {
'class': 'logging.StreamHandler',
},
'cute':{
'class': 'logging.handlers.SocketHandler',
'host': '127.0.0.1',
'port': 19996
},
},
'loggers': {
'django': {
'handlers': ['cute'],
'level': os.getenv('DJANGO_LOG_LEVEL', 'INFO'),
},
},
}
But when I try and log out I get an error in the console:
TypeError: an integer is required (got type socket)
This seems to be happening within an attempt to pickle the log message, I think.
What is going on, and how can I get the SocketHandler to work?
There is a bug report about it. The request object cannot be pickled and the log fails.
My loggers were like yours before I got the same error as you did. Since my code contains apps that don't work with request, I partially fixed my problem creating a log for django.request without socket_handler
'django.request': {
'handlers': ['defaultfile', 'console'],
'level': 'WARNING',
'propagate': False,
},
However the bug report also suggest to create a custom SocketHandler removing request:
from logging.handlers import SocketHandler as _SocketHandler
class DjangoSocketHandler(_SocketHandler):
def emit(self, record):
if hasattr(record, 'request'):
record.request = None
return super().emit(record)
I haven't tried this yet, but it could be a way to go.

Why doesn't this Django logging work?

I'm having trouble getting going with Django logging. I've read both the Python and Django documentation on logging but I still don't see what I'm doing wrong. To start, I'm just trying to log a message to the console where my Django development server is running when I execute this simple view:
# demo/views.py
import logging
logger = logging.getLogger(__name__)
def demo_logging(request, template):
logger.error("Got some error")
return render(request, template)
I'm using Django's default logging setting as specified in django/utils/log.py in my settings file so that I (hopefully) know exactly what's happening (which, clearly I don't):
# settings.py
DEBUG = True
...
LOGGING_CONFIG = None
LOGGING = {
'version': 1,
'disable_existing_loggers': False,
'filters': {
'require_debug_false': {
'()': 'django.utils.log.RequireDebugFalse',
},
'require_debug_true': {
'()': 'django.utils.log.RequireDebugTrue',
},
},
'handlers': {
'console': {
'level': 'INFO',
'filters': ['require_debug_true'],
'class': 'logging.StreamHandler',
},
'null': {
'class': 'logging.NullHandler',
},
'mail_admins': {
'level': 'ERROR',
'filters': ['require_debug_false'],
'class': 'django.utils.log.AdminEmailHandler'
}
},
'loggers': {
'django': {
'handlers': ['console'],
},
'django.request': {
'handlers': ['mail_admins'],
'level': 'ERROR',
'propagate': False,
},
'django.security': {
'handlers': ['mail_admins'],
'level': 'ERROR',
'propagate': False,
},
'py.warnings': {
'handlers': ['console'],
},
}
}
import logging.config
logging.config.dictConfig(LOGGING)
When I execute the view, I don't see anything in the console except the message,
No handlers could be found for logger "demo.views"
I don't understand what I'm doing wrong. I would think calling logger.error would hit the django logger which is linked to the console handler which is defined.
Thanks.
FOLLOW UP
I solved this problem by adding a default, "catch-all" logger that would be triggered when creating a logger using the "__name__" argument:
'loggers': {
'': {
'handlers': ['console'],
},
...
Calling logger = logging.getLogger(__name__) causes the logging module to search for a logger named as your module (demo.views); as you have no logger defined by that name, it fails. To simply log to console, you can use the django logger defined in 'loggers' key of your LOGGING configuration:
import logging
logger = logging.getLogger('django')
def demo_logging(request, template):
logger.error("Got some error")
return render(request, template)

Why are assertions being logged in sentry when DEBUG = True?

I'm in the middle of deploying sentry to handle our django error messages. I've configured django's LOGGING settings to only log when DEBUG = False via the use of 'filters': ['require_debug_false'].
If I manually log an error in a django view as in the following example, it is successfully filtered and therefore not sent to sentry:
import logging
logger = logging.getLogger(__name__)
def view_name(request):
logger.error('An error message')
...
However, if I use an assert statement as in the following example, it is not filtered and does get sent to sentry:
import logging
logger = logging.getLogger(__name__)
def view_name(request):
assert False, 'An error message'
...
It is also worth noting that the assert statement does not get sent to the mail_admins handler, which also uses the same filter.
Can someone please help me prevent assert errors from begin sent to sentry whilst DEBUG = True?
Here are the package versions I am using:
Django==1.6.7
raven==5.1.1
And here are the relevant parts of my settings.py:
DEBUG = True
LOGGING = {
'version': 1,
'disable_existing_loggers': True,
'filters': {
'require_debug_false': {
'()': 'django.utils.log.RequireDebugFalse'
}
},
'formatters': {
'simple': {
'format': '%(levelname)s %(asctime)s %(message)s'
},
},
'handlers': {
'console': {
'level': 'WARNING',
'filters': ['require_debug_false'],
'class': 'logging.StreamHandler',
'formatter': 'simple'
},
'mail_admins': {
'level': 'ERROR',
'filters': ['require_debug_false'],
'class': 'django.utils.log.AdminEmailHandler',
'include_html': True,
},
'sentry': {
'level': 'WARNING',
'filters': ['require_debug_false'],
'class': 'raven.contrib.django.raven_compat.handlers.SentryHandler',
},
},
'loggers': {
'': {
'handlers': ['console', 'mail_admins', 'sentry'],
'level': 'WARNING',
'propagate': False,
},
},
}
In raven-python 3.0.0 DEBUG setting in Django no longer disables Raven.
From documentation:
Raven to install a hook in Django that will automatically report
uncaught exceptions
In your case, assert generate uncaught exceptions AssertionError, which logged in Sentry.
To disable this functionality set dsn = None or remove dsn (source):
RAVEN_CONFIG = {
'dsn': None
}

How to use sentry/raven in django views

I managed to install sentry successfully and I can see the sentry interface webservice at localhost and doing a
raven test http://jsifslkdjfklsdfjklsdjfklMYCODE
works, the tests shows up in the interface.
The problem is I can't find any examples or documentation on what exactly should I put on my views and my settings.
I know I have to add to my INSTALLED_APPS
'sentry',
'raven.contrib.django',
And I also added
SENTRY_DNS = 'http://jsifslkdjfklsdfjklsdjfklMYCODE'
This next two lines appear in the docs but it doesnt say where do they go
from raven.contrib.django.models import client
client.captureException()
I tried in settings.py but still I can't get my views to log anything.
I also added this
LOGGING = {
'version': 1,
'disable_existing_loggers': True,
'root': {
'level': 'WARNING',
'handlers': ['sentry'],
},
'formatters': {
'verbose': {
'format': '%(levelname)s %(asctime)s %(module)s %(process)d %(thread)d %(message)s'
},
},
'handlers': {
'sentry': {
'level': 'ERROR',
'class': 'raven.contrib.django.handlers.SentryHandler',
},
'console': {
'level': 'DEBUG',
'class': 'logging.StreamHandler',
'formatter': 'verbose'
}
},
'loggers': {
'django.db.backends': {
'level': 'ERROR',
'handlers': ['console'],
'propagate': False,
},
'raven': {
'level': 'DEBUG',
'handlers': ['console'],
'propagate': False,
},
'sentry.errors': {
'level': 'DEBUG',
'handlers': ['console'],
'propagate': False,
},
},
}
And in my views I added this:
import logging
logger = logging.getLogger()
def home(request,template_name):
logger.error('There was some crazy error lol', exc_info=True, extra={'request': request, })
return render_to_response(template_name,context, context_instance=RequestContext(request))
I have no other code related to logging apart from what you see here, What am I missing?
Your 'raven' logger is not actually using the sentry handler, but only writing to 'console'. Had the same problem. The documentation for raven/sentry lacks a good writer.
change your raven logger to:
'raven': {
'level': 'DEBUG',
'handlers': ['console', 'sentry'],
'propagate': False,
},
and make sure you use it as logger:
logger = logging.getLogger('raven')
I had to use this monstruosity on my settings.py:
import logging
# from raven.contrib.django.handlers import SentryHandler
from raven.handlers.logging import SentryHandler
logging.getLogger().setLevel(logging.INFO)
logger = logging.getLogger()# ensure we havent already registered the handler
handler = SentryHandler('http://13d06dad246d4fe6a180ef9b15151a13:eb46a6d724df4327a8cc04d9d3cfad37#sentry.bandtastic.pagekite.me/1')
logger.addHandler(handler)
# Add StreamHandler to sentry's default so you can catch missed exceptions
logger = logging.getLogger('sentry.errors')
logger.propagate = False
logger.addHandler(logging.StreamHandler())
from raven.conf import setup_logging
setup_logging(handler)
And in my views i can use a simple
import logging
logger = logging.getLogger(__name__)
def home(request,context={},template_name=None):
logger.info(str(request), exc_info=True)
return render_to_response(template_name,context, context_instance=RequestContext(request))
I tried many settings.