Related to a previous question I asked, Airbrake logger in Django still sending notifications even though its level is set to 'CRITICAL'? , I'm working on a Django project with multiple versions of settings.py
: settings/base.py
, settings/staging.py
, etc.
There is also a kind of settings 'mixin', settings/staging_development.py
, which contains the following LOGGING
configuration:
# Auxiliary variable used in LOGGING
_AIRBRAKE_LOGGER = {
'handlers': ['airbrake'],
'level': 'ERROR',
'propagate': True,
}
# Airbrake logging integration (cf. https://github.com/airbrake/pybrake#django-integration)
# In our case, 'app' is replaced by three apps, 'lucy_web', 'api', and 'activation'.
LOGGING = {
'version': 1,
'disable_existing_loggers': False,
'handlers': {
'airbrake': {
'level': 'ERROR',
'class': 'pybrake.LoggingHandler',
},
},
'loggers': {
'lucy_web': _AIRBRAKE_LOGGER,
'api': _AIRBRAKE_LOGGER,
'activation': _AIRBRAKE_LOGGER,
},
}
This is imported in settings/staging.py
in which LOGGING
is further .update()
d as follows:
from lucy.settings.staging_production import *
# LOGGING = {
# 'version': 1,
# 'disable_existing_loggers': False,
# 'handlers': {
# 'console': {
# 'class': 'logging.StreamHandler',
# },
# },
# 'loggers': {
# 'django': {
# 'handlers': ['console'],
# 'level': os.getenv('LOG_LEVEL', 'INFO'),
# },
# },
# }
LOGGING['handlers'].update(console={
'class': 'logging.StreamHandler'
})
LOGGING['loggers'].update(django={
'handlers': ['console'],
'level': os.getenv('LOG_LEVEL', 'INFO'),
})
What I'd like to achieve is to log to Airbrake as well as to the console. Now, if I simply comment in the commented-out code and re-define the LOGGING
configuration, I notice that error messages are successfully getting logged to the console. If I use the code as-is, however, they do not, even though I do get Airbrake notifications.
If I poke around in the shell, everything looks OK: for example, the 'lucy_web'
and 'django'
loggers both have handlers attached and propagate
set to True
:
(venv) Kurts-MacBook-Pro-2:lucy-web kurtpeek$ ENV_ROLE=staging_on_localhost python manage.py shell
Python 3.6.4 (v3.6.4:d48ecebad5, Dec 18 2017, 21:07:28)
Type 'copyright', 'credits' or 'license' for more information
IPython 6.3.1 -- An enhanced Interactive Python. Type '?' for help.
In [1]: from django.conf import settings
In [2]: settings.LOGGING
Out[2]:
{'version': 1,
'disable_existing_loggers': False,
'handlers': {'airbrake': {'level': 'ERROR',
'class': 'pybrake.LoggingHandler'},
'console': {'class': 'logging.StreamHandler'}},
'loggers': {'lucy_web': {'handlers': ['airbrake'],
'level': 'ERROR',
'propagate': True},
'api': {'handlers': ['airbrake'], 'level': 'ERROR', 'propagate': True},
'activation': {'handlers': ['airbrake'],
'level': 'ERROR',
'propagate': True},
'django': {'handlers': ['console'], 'level': 'ERROR'}}}
In [3]: import logging
In [4]: logger = logging.getLogger('lucy_web')
In [6]: logger.propagate
Out[6]: True
In [7]: logger.hasHandlers()
Out[7]: True
In [8]: logger.handlers
Out[8]: [<LoggingHandler (ERROR)>]
In [9]: django_logger = logging.getLogger('django')
In [10]: django_logger.handlers
Out[10]: [<StreamHandler <stderr> (NOTSET)>]
In [11]: django_logger.getEffectiveLevel()
Out[11]: 40
In [12]: logging.ERROR
Out[12]: 40
In [13]: django_logger.propagate
Out[13]: True
In short, I can get one type of logging to work or the other, but not both at the same time, even though log propagation is enabled.
Any idea what the issue might be?
I resolved the problem by adding the 'console'
handler to the apps ( 'lucy_web'
, 'api'
, and 'activation'
) themselves, rather than to the catch-all 'django'
logger. Actually, I think that at the root of the problem, the errors I was throwing were not in 'django'
logger's hierarchy.
So firstly, in settings/base.py
I use deepcopy
:
from copy import deepcopy
# Auxiliary variable used in LOGGING
_AIRBRAKE_LOGGER = {
'handlers': ['airbrake'],
'level': 'ERROR',
'propagate': True,
}
# Airbrake logging integration (cf. https://github.com/airbrake/pybrake#django-integration)
# In our case, 'app' is replaced by three apps, 'lucy_web', 'api', and 'activation'.
LOGGING = {
'version': 1,
'disable_existing_loggers': False,
'handlers': {
'airbrake': {
'level': 'ERROR',
'class': 'pybrake.LoggingHandler',
},
},
'loggers': {
# The deepcopy allows us to append to each app's 'handlers' list without affecting the others
'lucy_web': deepcopy(_AIRBRAKE_LOGGER),
'api': deepcopy(_AIRBRAKE_LOGGER),
'activation': deepcopy(_AIRBRAKE_LOGGER),
},
}
And secondly, in settings/staging.py
I updated LOGGING
like so:
LOGGING['handlers'].update(console={
'class': 'logging.StreamHandler'
})
for app in ('lucy_web', 'api', 'activation'):
LOGGING['loggers'][app]['handlers'].append('console')
Now error gets logged both to Airbrake and to the console.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.