Logger
Print statement generally does not work in production so, to get message we use logger
- Troubleshooting made easier
- Runtime information in production
- https://www.youtube.com/watch?v=ziegOuE7M4A&list=PL2NFhrDSOxgXXUMIGOs8lNe2B-f4pXOX-&index=4
What is Logging?
How Logging Works in Django
- Django comes with
Python's built-in logging module
to leverage system logging.- Loggers
- Handlers
- Filters
- Formatters
Loggers
- Loggers are basically the entry point of the logging system.
- If the log-level is same or exceeds the log-level of the logger, the message is sent to the handler for further processing.
DEBUG: 10 --> Low-level system information
INFO: 20 --> General system information
WARNING: 30 --> Minor problems related information
ERROR/EXCEPTION: 40 --> Major problems related information
CRITICAL: 50 --> Critical problems related information
dblogger.debug("Test Debug")
dblogger.info("Test Info")
dblogger.warning("Test Warning")
dblogger.warn("Test Warn") # Depricated
dblogger.error("Test Error")
dblogger.exception("Test Exception")
dblogger.critical("Test Critical")
Handlers
Handlers basically determine what happens to each message in a logger eg: write to a file or console.
For example: ERROR log level messages can be sent in real-time to the developer
,
while INFO log levels can just be stored in a system file
.
Filters
A filter can sit between a Logger and a Handler
. It can be used to filter the log record.
For example: in CRITICAL messages, you can set a filter which only allows a particular source to be processed.
Formatters
As the name suggests, formatters describe the format of the text which will be rendered.
Logger
Django provides several built-in loggers.
django
django.request
django.server
django.template
django.db.backends
django.security.*
django.db.backends.schema
Handlers
- logging.StreamHandler
- console
- which prints any INFO (or higher) message to sys.stderr
- logging.FileHandler
- This handler is used to write logs into a file
- logging.handlers.WatchedFileHandler
- logging.handlers.RotatingFileHandler
- django.utils.log.AdminEmailHandler
- mail_admins
- which emails any ERROR (or higher) message to the site ADMINS
Examples
Without logger
[02/Jan/2022 18:59:25] "GET /api/posts/ HTTP/1.1" 200 14956
Add log in console and file
'handlers': ['file', 'console']
is used –> to log on File & Console
LOGGING ={
'version': 1,
# The version number of our log
'loggers':{
'django':{
# handler name is added here
'handlers': ['file', 'console'],
'level': 'DEBUG'
}
},
'handlers':{
# file --> user-define name
'file' :{
'level': 'DEBUG',
'class': 'logging.FileHandler',
'filename': './logs/debug.log'
},
# console --> user-define name
'console' :{
'level': 'DEBUG',
'class': 'logging.StreamHandler',
}
},
'formatters':{}
}
# OP
"GET / HTTP/1.1" 200 830
Adding logger formatter
- For level INFO –> INFO and above level will be logged
LOGGING ={
'version': 1,
# The version number of our log
'loggers':{
'django':{
'handlers': ['console'],
'level': 'DEBUG'
}
},
'handlers':{
'console' :{
'level': 'INFO',
'class': 'logging.StreamHandler',
'formatter': 'simple',
}
},
'formatters':{
# simple --> user-define name
'simple':{
'format': '{levelname} {asctime} {module} {message}',
'style': '{'
}
}
}
# OP
INFO 2022-01-02 19:46:52,580 basehttp "GET / HTTP/1.1" 200 830
- Use logger instead of print statement with logger-level
# views.py
logger = logging.getLogger('django')
def home(request):
logger.error('getting some error')
return
ERROR 2022-01-02 19:46:52,538 views getting some error
formatter
- simple, verbose –> are user-define variable
- datefmt –> is formate of asctime
'formatters': {
'simple': {
'format': '[%(asctime)s] %(levelname)s %(message)s',
'datefmt': '%Y-%m-%d %H:%M:%S'
},
'verbose': {
'format': '[%(asctime)s] %(levelname)s [%(name)s.%(funcName)s:%(lineno)d] %(message)s',
'datefmt': '%Y-%m-%d %H:%M:%S'
},
filter
- require_debug_true –> Log only if DEBUG=True
- require_debug_false –> LOg only if DEBUG=False
LOGGING ={
'version': 1,
# The version number of our log
'loggers':{
'django':{
'handlers': ['console'],
'level': 'DEBUG'
}
},
'handlers':{
'console' :{
'level': 'INFO',
'filters': ['require_debug_true'],
'class': 'logging.StreamHandler',
'formatter': 'simple',
}
},
'filters': {
'require_debug_false': {
'()': 'django.utils.log.RequireDebugFalse',
},
'require_debug_true': {
'()': 'django.utils.log.RequireDebugTrue',
},
},
}
Django’s logging extensions
- https://docs.djangoproject.com/en/3.2/topics/logging/#django-s-logging-extensions
- https://github.com/django/django/blob/main/django/utils/log.py
Complete Example
LOGGING = {
'version': 1,
# The version number of our log
'disable_existing_loggers': True,
# django uses some of its own loggers for internal operations.
# In case you want to disable them just replace the False above with True.
'filters': {
'require_debug_false': {
'()': 'django.utils.log.RequireDebugFalse',
},
'require_debug_true': {
'()': 'django.utils.log.RequireDebugTrue',
},
},
'formatters': {
'simple': {
'format': '[%(asctime)s] %(levelname)s %(message)s',
'datefmt': '%Y-%m-%d %H:%M:%S'
},
'verbose': {
'format': '[%(asctime)s] %(levelname)s [%(name)s.%(funcName)s:%(lineno)d] %(message)s',
'datefmt': '%Y-%m-%d %H:%M:%S'
},
},
'handlers': {
# A handler for DEBUG. It is basically writing the DEBUG messages into the console
'console': {
'level': 'DEBUG',
'filters': ['require_debug_true'],
'class': 'logging.StreamHandler',
'formatter': 'verbose'
},
# A handler for DEBUG. It is basically writing the DEBUG messages into '/tmp/django_dev.log' file
'development_logfile': {
'level': 'DEBUG',
'filters': ['require_debug_true'],
'class': 'logging.FileHandler',
'filename': '/tmp/django_dev.log',
'formatter': 'verbose'
},
# A handler for ERROR. It is basically writing the ERROR messages into '/var/log/django/django_production.log' file
'production_logfile': {
'level': 'ERROR',
'filters': ['require_debug_false'],
'class': 'logging.handlers.RotatingFileHandler',
'filename': '/var/log/django/django_production.log',
'maxBytes': 1024*1024*100, # 100MB
'backupCount': 5,
'formatter': 'simple'
},
'dba_logfile': {
'level': 'DEBUG',
'filters': ['require_debug_false','require_debug_true'],
'class': 'logging.handlers.WatchedFileHandler',
'filename': '/var/log/dba/django_dba.log',
'formatter': 'simple'
},
'mail_admins': {
'level': 'ERROR',
'filters': ['require_debug_false'],
'class': 'django.utils.log.AdminEmailHandler'
}
},
'root': {
'level': 'DEBUG',
'handlers': ['console'],
},
# A logger can have multiple handle
'loggers': {
'newmore': {
'handlers': ['development_logfile','production_logfile','mail_admins'],
},
'dba': {
'handlers': ['dba_logfile','mail_admins'],
},
'django': {
'handlers': ['development_logfile','production_logfile','mail_admins'],
},
'py.warnings': {
'handlers': ['development_logfile'],
},
}
}
ADMINS = [('Development', '[email protected]')]