We set up logging like the django docs told us:
https://docs.djangoproject.com/en/2.1/topics/logging/#using-logging
# import the logging library import logging # Get an instance of a logger logger = logging.getLogger(__name__) def my_view(request, arg1, arg): ... if bad_mojo: # Log an error message logger.error('Something went wrong!')
I want to avoid this line in every Python file which wants to log:
logger = logging.getLogger(__name__)
I want it simple:
logging.error('Something went wrong!')
But we want to keep one feature: We want to see the Python file name in the logging output.
Up to now we use this format:
'%(asctime)s %(name)s.%(funcName)s +%(lineno)s: %(levelname)-8s [%(process)d] %(message)s'
Example output:
2016-01-11 12:12:31 myapp.foo +68: ERROR Something went wrong
How to avoid logger = logging.getLogger(__name__)
?
A good convention to use when naming loggers is to use a module-level logger, in each module which uses logging, named as follows: logger = logging.getLogger(__name__) This means that logger names track the package/module hierarchy, and it's intuitively obvious where events are logged just from the logger name.
getLogger(name) is typically executed. The getLogger() function accepts a single argument - the logger's name. It returns a reference to a logger instance with the specified name if provided, or root if not. Multiple calls to getLogger() with the same name will return a reference to the same logger object.
getName() method of a Logger class used to get the name of logger. Many times you have to check the logger name so we can use this method to get the logger name.
You can use logging.basicConfig
to define the default interface available through logging
as follows:
import logging logging.basicConfig(level=logging.DEBUG, format='%(asctime)s %(name)s.%(funcName)s +%(lineno)s: %(levelname)-8s [%(process)d] %(message)s', )
This definition will now be used whenever you do the following anywhere in your application:
import logging logging.error(...)
While __name__
is not available, the equivalent (and other options) are available through the default LogRecord
attributes that can be used for error string formatting - including module
, filename
and pathname
. The following is a two-script demonstration of this in action:
scripta.py
import logging logging.basicConfig(level=logging.DEBUG, format='%(asctime)s %(module)s %(name)s.%(funcName)s +%(lineno)s: %(levelname)-8s [%(process)d] %(message)s', ) from scriptb import my_view my_view()
scriptb.py
import logging def my_view(): # Log an error message logging.error('Something went wrong!')
The logging definition is defined in scripta.py
, with the added module
parameter. In scriptb.py
we simply need to import logging
to get access to this defined default. When running scripta.py
the following output is generated:
2016-01-14 13:22:24,640 scriptb root.my_view +9: ERROR [14144] Something went wrong!
Which shows the module (scriptb
) where the logging of the error occurs.
According to this answer you can continue to use any per-module configuration of logging from Django, by turning off Django handling and setting up the root handler as follows:
# settings.py - django config LOGGING_CONFIG = None # disables Django handling of logging LOGGING = {...} # your standard Django logging configuration import logging.config logging.config.dictConfig(LOGGING)
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