redirect stdout & stderr to logging error file when output is different

from '-' . Useful to collect some errors.
This commit is contained in:
benoitc 2012-02-19 16:06:06 +01:00
parent 9b1aa8a159
commit 85c60c26b5
2 changed files with 49 additions and 2 deletions

View File

@ -1,17 +1,20 @@
# -*- coding: utf-8 -
#
# This file is part of gunicorn released under the MIT license.
# This file is part of gunicorn released under the MIT license.
# See the NOTICE for more information.
#
# Example code from Eventlet sources
from wsgiref.validate import validator
import sys
#@validator
def app(environ, start_response):
"""Simplest possible application object"""
data = 'Hello, World!\n'
status = '200 OK'
print("print to stdout in test app")
sys.stderr.write("stderr, print to stderr in test app")
response_headers = [
('Content-type','text/plain'),
('Content-Length', str(len(data)))

View File

@ -8,9 +8,46 @@ import logging
logging.Logger.manager.emittedNoHandlerWarning = 1
import sys
import traceback
import threading
from gunicorn import util
class LazyWriter(object):
"""
File-like object that opens a file lazily when it is first written
to.
"""
def __init__(self, filename, mode='w'):
self.filename = filename
self.fileobj = None
self.lock = threading.Lock()
self.mode = mode
def open(self):
if self.fileobj is None:
self.lock.acquire()
try:
if self.fileobj is None:
self.fileobj = open(self.filename, self.mode)
finally:
self.lock.release()
return self.fileobj
def write(self, text):
fileobj = self.open()
fileobj.write(text)
fileobj.flush()
def writelines(self, text):
fileobj = self.open()
fileobj.writelines(text)
fileobj.flush()
def flush(self):
self.open().flush()
class Logger(object):
LOG_LEVELS = {
@ -38,6 +75,14 @@ class Logger(object):
self.cfg = cfg
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
self.error_log.setLevel(loglevel)
# always info in access log
@ -46,7 +91,6 @@ class Logger(object):
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))