mirror of
https://github.com/frappe/gunicorn.git
synced 2026-01-14 11:09:11 +08:00
logging.fileConfig support is back.
This commit is contained in:
parent
85c60c26b5
commit
cc99181cee
@ -1,33 +1,48 @@
|
||||
[loggers]
|
||||
keys=root, gunicorn
|
||||
keys=root, gunicorn_error, gunicorn_access
|
||||
|
||||
[handlers]
|
||||
keys=console, file
|
||||
keys=console, error_file, access_file
|
||||
|
||||
[formatters]
|
||||
keys=generic
|
||||
keys=generic, access
|
||||
|
||||
[logger_root]
|
||||
level=INFO
|
||||
handlers=console
|
||||
|
||||
[logger_gunicorn]
|
||||
level=DEBUG
|
||||
handlers=file
|
||||
[logger_gunicorn_error]
|
||||
level=INFO
|
||||
handlers=error_file
|
||||
propagate=1
|
||||
qualname=gunicorn
|
||||
qualname=gunicorn.error
|
||||
|
||||
[logger_gunicorn_access]
|
||||
level=INFO
|
||||
handlers=access_file
|
||||
propagate=1
|
||||
qualname=gunicorn.access
|
||||
|
||||
[handler_console]
|
||||
class=StreamHandler
|
||||
formatter=generic
|
||||
args=(sys.stdout, )
|
||||
|
||||
[handler_file]
|
||||
[handler_error_file]
|
||||
class=logging.FileHandler
|
||||
formatter=generic
|
||||
args=('/tmp/test.log',)
|
||||
args=('/tmp/gunicorn.error.log',)
|
||||
|
||||
[handler_access_file]
|
||||
class=logging.FileHandler
|
||||
formatter=access
|
||||
args=('/tmp/gunicorn.access.log',)
|
||||
|
||||
[formatter_generic]
|
||||
format="%(asctime)s [%(process)d] [%(levelname)s] %(message)s"
|
||||
datefmt="%Y-%m-%d %H:%M:%S"
|
||||
format=%(asctime)s [%(process)d] [%(levelname)s] %(message)s
|
||||
datefmt=%Y-%m-%d %H:%M:%S
|
||||
class=logging.Formatter
|
||||
|
||||
[formatter_access]
|
||||
format=%(message)s
|
||||
class=logging.Formatter
|
||||
|
||||
@ -686,6 +686,20 @@ class LoggerClass(Setting):
|
||||
with `egg:gunicorn#simple`
|
||||
"""
|
||||
|
||||
|
||||
class LogConfig(Setting):
|
||||
name = "logconfig"
|
||||
section = "Logging"
|
||||
cli = ["--log-config"]
|
||||
meta = "FILE"
|
||||
validator = validate_string
|
||||
default = None
|
||||
desc = """\
|
||||
The log config file to use.
|
||||
Gunicorn uses the standard Python logging module's Configuration
|
||||
file format.
|
||||
"""
|
||||
|
||||
class Procname(Setting):
|
||||
name = "proc_name"
|
||||
section = "Process Naming"
|
||||
|
||||
@ -6,10 +6,16 @@
|
||||
import datetime
|
||||
import logging
|
||||
logging.Logger.manager.emittedNoHandlerWarning = 1
|
||||
import os
|
||||
import sys
|
||||
import traceback
|
||||
import threading
|
||||
|
||||
try:
|
||||
from logging.config import fileConfig
|
||||
except ImportError:
|
||||
from gunicorn.logging_config import fileConfig
|
||||
|
||||
from gunicorn import util
|
||||
|
||||
class LazyWriter(object):
|
||||
@ -68,32 +74,37 @@ class Logger(object):
|
||||
self.access_log = logging.getLogger("gunicorn.access")
|
||||
self.error_handlers = []
|
||||
self.access_handlers = []
|
||||
|
||||
self.cfg = cfg
|
||||
self.setup(cfg)
|
||||
|
||||
def setup(self, cfg):
|
||||
self.cfg = cfg
|
||||
if not cfg.logconfig:
|
||||
loglevel = self.LOG_LEVELS.get(cfg.loglevel.lower(), logging.INFO)
|
||||
self.error_log.setLevel(loglevel)
|
||||
self.access_log.setLevel(logging.INFO)
|
||||
|
||||
loglevel = self.LOG_LEVELS.get(cfg.loglevel.lower(), logging.INFO)
|
||||
|
||||
if cfg.errorlog != "-":
|
||||
# if an error log file is set redirect stdout & stderr to
|
||||
# this log file.
|
||||
stdout_log = LazyWriter(cfg.errorlog, 'a')
|
||||
sys.stdout = stdout_log
|
||||
sys.stderr = stdout_log
|
||||
if cfg.errorlog != "-":
|
||||
# if an error log file is set redirect stdout & stderr to
|
||||
# this log file.
|
||||
stdout_log = LazyWriter(cfg.errorlog, 'a')
|
||||
sys.stdout = stdout_log
|
||||
sys.stderr = stdout_log
|
||||
|
||||
self.error_log.setLevel(loglevel)
|
||||
# set gunicorn.error handler
|
||||
self._set_handler(self.error_log, cfg.errorlog,
|
||||
logging.Formatter(self.error_fmt, self.datefmt))
|
||||
|
||||
# always info in access log
|
||||
self.access_log.setLevel(logging.INFO)
|
||||
|
||||
self._set_handler(self.error_log, cfg.errorlog,
|
||||
logging.Formatter(self.error_fmt, self.datefmt))
|
||||
|
||||
if cfg.accesslog is not None:
|
||||
self._set_handler(self.access_log, cfg.accesslog,
|
||||
fmt=logging.Formatter(self.access_fmt))
|
||||
# set gunicorn.access handler
|
||||
if cfg.accesslog is not None:
|
||||
self._set_handler(self.access_log, cfg.accesslog,
|
||||
fmt=logging.Formatter(self.access_fmt))
|
||||
else:
|
||||
if os.path.exists(cfg.logconfig):
|
||||
util.check_is_writeable(cfg.logconfig)
|
||||
fileConfig(cfg.logconfig)
|
||||
else:
|
||||
raise RuntimeError("Error: log config '%s' not found" % path)
|
||||
|
||||
|
||||
def critical(self, msg, *args, **kwargs):
|
||||
@ -124,10 +135,9 @@ class Logger(object):
|
||||
for format details
|
||||
"""
|
||||
|
||||
if not self.cfg.accesslog:
|
||||
if not self.cfg.accesslog and not self.cfg.logconfig:
|
||||
return
|
||||
|
||||
|
||||
status = resp.status.split(None, 1)[0]
|
||||
atoms = {
|
||||
'h': environ['REMOTE_ADDR'],
|
||||
@ -197,6 +207,7 @@ class Logger(object):
|
||||
if output == "-":
|
||||
h = logging.StreamHandler()
|
||||
else:
|
||||
util.check_is_writeable(output)
|
||||
h = logging.FileHandler(output)
|
||||
|
||||
h.setFormatter(fmt)
|
||||
|
||||
@ -303,3 +303,11 @@ def seed():
|
||||
random.seed(os.urandom(64))
|
||||
except NotImplementedError:
|
||||
random.seed(random.random())
|
||||
|
||||
|
||||
def check_is_writeable(path):
|
||||
try:
|
||||
f = open(path, 'a')
|
||||
except IOError, e:
|
||||
raise RuntimeError("Error: '%s' isn't writable [%r]" % (path, e))
|
||||
f.close()
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user