Skip to content

Commit

Permalink
redtirect stdout/stderr to logfile
Browse files Browse the repository at this point in the history
Add the new setting `--caapture-output` to capture output from stdout/stderr to the current log file.

fix #1271
  • Loading branch information
benoitc committed May 21, 2016
1 parent 20bde96 commit 49ebee1
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 1 deletion.
15 changes: 15 additions & 0 deletions gunicorn/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -917,6 +917,7 @@ class WorkerTmpDir(Setting):
If not set, the default temporary directory will be used.
"""


class User(Setting):
name = "user"
section = "Server Mechanics"
Expand Down Expand Up @@ -1121,6 +1122,20 @@ class Loglevel(Setting):
"""


class CaptureOutput(Setting):
name = "capture_output"
section = "Logging"
cli = ["--capture-output"]
validator = validate_bool
action = 'store_true'
default = False
desc = """\
Redirect stdout/stderr to Error log.
.. versionadded:: 19.6
"""


class LoggerClass(Setting):
name = "logger_class"
section = "Logging"
Expand Down
25 changes: 24 additions & 1 deletion gunicorn/glogging.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
import os
import socket
import sys
import threading
import traceback

from gunicorn import util
Expand Down Expand Up @@ -186,6 +187,8 @@ def __init__(self, cfg):
self.access_log.propagate = False
self.error_handlers = []
self.access_handlers = []
self.logfile = None
self.lock = threading.Lock()
self.cfg = cfg
self.setup(cfg)

Expand All @@ -195,8 +198,16 @@ def setup(self, cfg):
self.access_log.setLevel(logging.INFO)

# set gunicorn.error handler
if self.cfg.capture_output and cfg.errorlog != "-":
for stream in sys.stdout, sys.stderr:
stream.flush()

self.logfile = open(cfg.errorlog, 'a+')
os.dup2(self.logfile.fileno(), sys.stdout.fileno())
os.dup2(self.logfile.fileno(), sys.stderr.fileno())

self._set_handler(self.error_log, cfg.errorlog,
logging.Formatter(self.error_fmt, self.datefmt))
logging.Formatter(self.error_fmt, self.datefmt))

# set gunicorn.access handler
if cfg.accesslog is not None:
Expand Down Expand Up @@ -318,6 +329,18 @@ def now(self):
return time.strftime('[%d/%b/%Y:%H:%M:%S %z]')

def reopen_files(self):
if self.cfg.capture_output and self.cfg.errorlog != "-":
for stream in sys.stdout, sys.stderr:
stream.flush()

with self.lock:
if self.logfile is not None:
self.logfile.close()
self.logfile = open(self.cfg.errorlog, 'a+')
os.dup2(self.logfile.fileno(), sys.stdout.fileno())
os.dup2(self.logfile.fileno(), sys.stderr.fileno())


for log in loggers():
for handler in log.handlers:
if isinstance(handler, logging.FileHandler):
Expand Down

0 comments on commit 49ebee1

Please sign in to comment.