Skip to content

Commit

Permalink
add greins.app.GreinsLogger
Browse files Browse the repository at this point in the history
This change makes it easier to use the gunicorn log for application
messages. Everything is overridable and configurable as before, but by
default greins will use a new logging class, `greins.GreinsLogger`.

The `GreinsLogger` class is just like the logger from gunicorn, except
it configures a handler on the root logger which forwards to the
handler for the 'gunicorn.error' logger and uses a formatter that
includes the package name of the source of each log message.

Reported by Mark Doliner (#14).
  • Loading branch information
Randall Leeds authored and tilgovi committed Mar 28, 2012
1 parent 93a7ad9 commit 877430e
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 1 deletion.
41 changes: 40 additions & 1 deletion greins/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,52 @@
import textwrap
import traceback

from logging import getLogger, NOTSET
from logging.handlers import MemoryHandler

from gunicorn.app.wsgiapp import WSGIApplication
from gunicorn.config import make_settings
from gunicorn.glogging import Logger
from gunicorn.util import import_app

from greins.reloader import Reloader
from greins.router import Router
from greins.synchronization import synchronized

class GreinsLogger(Logger):
"""
A `gunicorn.glogging.Logger` subclass which sets up a
`logging.handlers.MemoryHandler` that delegates to the gunicorn error
logger but filters out the messages from the gunicorn package.
"""

root_handler = None
error_fmt = r"%(asctime)s [%(process)d] [%(levelname)s] [%(name)s] %(message)s"

@classmethod
def install(cls):
"""
Invoked by the gunicorn config system to perform one-time, class-level
initialization of the logger.
"""
cls.root_handler = MemoryHandler(0)
cls.root_handler.addFilter(cls)
getLogger().addHandler(cls.root_handler)
getLogger().setLevel(NOTSET)

@staticmethod
def filter(record):
return not record.name.startswith('gunicorn')

def setup(self, cfg):
"""
Resets the target of the forwarding, root handler whenever the
logger is reset.
"""
super(GreinsLogger, self).setup(cfg)
self.root_handler.setTarget(self._get_gunicorn_handler(self.error_log))

class GreinsApplication(WSGIApplication):
synchronize_hooks = synchronized('_hooks_lock')

Expand All @@ -24,8 +62,9 @@ def init(self, parser, opts, args):
parser.error("APP_DIR must refer to an existing directory.")

self.cfg.set("default_proc_name", parser.get_prog_name())
self.cfg.set("logger_class", 'greins.app.GreinsLogger')
self.app_dir = os.path.abspath(args[0])
self.logger = logging.getLogger('gunicorn.error')
self.logger = getLogger(__name__)

self._use_reloader = opts.reloader
self._hooks = {}
Expand Down
3 changes: 3 additions & 0 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,5 +44,8 @@
entry_points="""
[console_scripts]
greins=greins.app:run
[gunicorn.loggers]
greins=greins.app:GreinsLogger
"""
)

0 comments on commit 877430e

Please sign in to comment.