Nick wrote ..
> Jim Gallacher wrote:
> > Beyond that it still segfaults for me. The other problem is that you
> are 
> > not removing the handler instance from the logging instance so you still
> > have a memory leak. 100k requests would result in 100k handler 
> > instances. Oh, and there might be a bit of a performance issue when 
> > emit() gets fired 100k times. ;) Or should I assume that the user will
> > still be required to include req.register_cleanup(log.removeHandler,
> > hdlr) in their code?
> 
> Not sure if this will help, but in my implementation I registered my hander
> on the root logger as global code in the handler module, not for each
> request.  In that case I used a threading.local to keep track of req, which
> I had to register and free for each request of course.  I couldn't get
> around the minimal bookkeeping required of registering the req object on
> each request, though like Nic's code, I registered a cleanup in a closure
> to
> handle the freeing.
> 
> Alternatively, you can register the server and use apache.log_error with
> a
> server object, which should not leak.  Also, if you don't care about logging
> to a particular server, you can, of course, just call apache.log_error
> without a server argument.

If I understand you correctly, you are probably managing this in the same
way as I think is possibly a much better way than what is currently being
discussed.

That is, a global log handler instance is created once only. No instance per
request handler invocation.

As you point out you need though to do caching of request objects. I have
previously posted on a safe way of doing this which works for internal
redirects. See:

  http://www.modpython.org/pipermail/mod_python/2005-September/019071.html

Other solutions I have seen people describe for request caching didn't
consider internal redirects properly. One also can't use thread local
storage as Python 2.3 doesn't support it.

I have already pointed out how this sort of request caching will probably
be needed in mod_python 3.3 when various of the problems with the
module loading system hopefully will be fixed. Thus, any logger system
could harness what would then be builtin functionality at no cost.

In terms of seamless integration, I am coming to the conclusion that
having mod_python internally create the single global log handler as part
of mod_python.apache being imported would be best. It only gets done
once, so insignificant overhead. Any code therefore doesn't need to
worry about that and just needs to get the logger and log their messages.
Beyond the creation of the one log handler, there is no overhead unless
handlers actually use logging, as the request caching will need to be
done for other reasons anyway associated with module importing.

What would happen is that when the log handler gets called, it would use
the request cache to look up the request object pertinent to the thread
at that time. When it gets that, it logs the message through the req
object. If a message is being logged by a distinct thread and not the
request handler thread, it would be logged via "apache.log_error()".

Apart from the benefit of individual request handlers not having to create
log handler instances and all the cleanup problems with that etc, this
logging mechanism is still usuable from global scope of a module and
messages logged at that point when a module is being imported due
to a request, will still be logged against the request object.

Hopefully everyone follows what I am talking about. I will try and get
together a working example today of what I am talking about, but Nick,
you may want to consider posting your code and how you are using it
as it probably will not be too different.

Graham

Reply via email to