Jim Gallacher <[EMAIL PROTECTED]> writes:

> My gut was right. Your current version segfaults (using mpm-prefork). It 
> might work if you register a cleanup to remove the reference to your 
> logging handler (untested):
>
> req.register_cleanup(log.removeHandler, hdlr)
>
> The problem here is that we are depending on the user to add that line 
> to their code to avoid the segfault. I don't like the idea of including 
> code in mod_python which may result in a segfault, even if the user is 
> warned of the dangers in the docs.

Here's a new version of my logging module which fixes these problems.


  # A log handler for mod-python

  import logging
  from mod_python import apache


  class ApacheLogHandler(logging.Handler):
      """A handler class which sends all logging to Apache."""

      def __init__(self, request):
          """
          Initialize the handler (does nothing)
          """
          logging.Handler.__init__(self)
          self.request = request

          def cleanup(data = None):
              self.request = None

          request.register_cleanup(cleanup)

          # Set up the thing
          self.level_mapping = { }

          self.level_mapping[logging.CRITICAL] = apache.APLOG_CRIT
          self.level_mapping[logging.ERROR] = apache.APLOG_ERR
          self.level_mapping[logging.WARNING] = apache.APLOG_WARNING
          self.level_mapping[logging.INFO] = apache.APLOG_INFO
          self.level_mapping[logging.debug] = apache.APLOG_DEBUG

      def emit(self, record):
          """Emit a record."""
          msg = self.format(record)
          if self.request != None:
              self.request.log_error(msg, self.level_mapping[record.levelno])

          # We *could* log to apache here:
          #else:
          #    apache.log(msg)


  # End

There is one remaining problem that I am aware of. When you do:

   logger = logging.getLogger("webapp")

you are always gauranteed to get the same logger. That's bad in a
multi-programming environment. 

The traditional approach to this is to create your logger with a
unique name, eg:

   logger = logging.getLogger("webapp" + thread_id)

But clearly we'd be relying on users to do that.

I could come up with a logging factory to mitigate that.



Nic

Reply via email to