I've got to the point in the logging implementation where I want to
add support for logging related settings in settings.py.

The current idea (suggested by Ivan Sagalaev) is to allow for a
standard Django-style setting that look something like this:

LOGGING = {
     'django.db.sql': {
         'handler': 'django.utils.log.StdErrHandler',
         'level': 'DEBUG',
     },
     'django.errors': {
         'handler': 'logging.handlers.SMTPHandler',
         ...
     }
}

So each key is the name of a logger, and the value is a dictionary
that configures various aspects about how log events sent to that
logger be processed (what levels to pay attention to, what handler to
use etc). If a handler isn't mentioned in the LOGGING dictionary (it
will be empty by default) then all log messages sent to that handler
will be silently discarded.

To implement this, I need to write some code that executes only once,
iterates over the django.conf.settings.LOGGING dictionary and uses it
to make the relevant calls to the Python logging framework to set
everything up - the above should map to code something like this
executing:

logger = logging.getLogger('django.db.sql')
logger.setLevel(logging.DEBUG)
logger.addHandler(django.utils.log.StdErrHandler())
logger = logging.getLogger('django.errors')
logger.addHandler(logging.handlers.SMTPHandler(...))

Here's the problem: I need the above to happen once, on startup, some
time AFTER the user's settings have been loaded. I can't figure out
where the appropriate place to do this is.

The best example I've found of code that executes once in Django core
is the code in the Settings class constructor:

http://code.djangoproject.com/browser/django/trunk/django/conf/__init__.py#L62

This is where the time.tzset() call based on the TIME_ZONE setting
happens, for example.

Unfortunately, that code executes the first time anything attempts to
access a property on the django.conf.settings module (which is a
LazySettings module until the first time it is accessed). I could put
the logging stuff in there, but it feels like a bit of a cludge.

The other interesting happens-once execution point I found is the
AppCache class here, which is instantiated once the first time the
django.db.models.loading class is imported:

http://code.djangoproject.com/browser/django/trunk/django/db/models/loading.py#L15

It appears to use the terrifying Borg pattern to avoid being
instantiated more than once.

Neither of these seem like particularly suitable places to put code
that configures logger objects based on the LOGGING setting.

This relates to a wider problem I've had when working with Django
(which I've seen crop up all over the place, but I'm not sure there's
a best practice for handling) - what to do with Django application/
project code that should only be executed once. We had this problem
with class registration for the admin, and ended up hacking around it
with a call to admin.autoload() in the urls.py file - which seems to
have resulted in urls.py becoming a defacto standard place for putting
code that's meant to run once on startup.

For logging, I want advanced users to be able to write their own
Python logging configuration code (see example above) rather than
using the LOGGING setting. Should I tell them to put that in urls.py
as well?

I'm ashamed to admit it, but I tend to shy away from using signals in
my own code purely because I don't know where I should put the code
that registers them.

Is there a straight forward solution to this that I've been missing,
or is it an ongoing problem? If it's a problem, can we fix it? What
makes it so difficult to fix (I'm going to guess there's no easy
solution, or we would have sorted it out ages ago)? Are there any
previous discussions I should be reading to catch up on this?

Alternatively, should I just stick my log configuring code in the
Setting class constructor and leave well alone?

Thanks,

Simon
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"Django developers" group.
To post to this group, send email to django-developers@googlegroups.com
To unsubscribe from this group, send email to 
django-developers+unsubscr...@googlegroups.com
For more options, visit this group at 
http://groups.google.com/group/django-developers?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to