mirror of
https://github.com/frappe/gunicorn.git
synced 2026-01-14 11:09:11 +08:00
redtirect stdout/stderr to logfile
Add the new setting `--caapture-output` to capture output from stdout/stderr to the current log file. fix #1271
This commit is contained in:
parent
20bde96e14
commit
49ebee1386
@ -917,6 +917,7 @@ class WorkerTmpDir(Setting):
|
|||||||
If not set, the default temporary directory will be used.
|
If not set, the default temporary directory will be used.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
class User(Setting):
|
class User(Setting):
|
||||||
name = "user"
|
name = "user"
|
||||||
section = "Server Mechanics"
|
section = "Server Mechanics"
|
||||||
@ -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):
|
class LoggerClass(Setting):
|
||||||
name = "logger_class"
|
name = "logger_class"
|
||||||
section = "Logging"
|
section = "Logging"
|
||||||
|
|||||||
@ -12,6 +12,7 @@ from logging.config import fileConfig
|
|||||||
import os
|
import os
|
||||||
import socket
|
import socket
|
||||||
import sys
|
import sys
|
||||||
|
import threading
|
||||||
import traceback
|
import traceback
|
||||||
|
|
||||||
from gunicorn import util
|
from gunicorn import util
|
||||||
@ -186,6 +187,8 @@ class Logger(object):
|
|||||||
self.access_log.propagate = False
|
self.access_log.propagate = False
|
||||||
self.error_handlers = []
|
self.error_handlers = []
|
||||||
self.access_handlers = []
|
self.access_handlers = []
|
||||||
|
self.logfile = None
|
||||||
|
self.lock = threading.Lock()
|
||||||
self.cfg = cfg
|
self.cfg = cfg
|
||||||
self.setup(cfg)
|
self.setup(cfg)
|
||||||
|
|
||||||
@ -195,8 +198,16 @@ class Logger(object):
|
|||||||
self.access_log.setLevel(logging.INFO)
|
self.access_log.setLevel(logging.INFO)
|
||||||
|
|
||||||
# set gunicorn.error handler
|
# 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,
|
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
|
# set gunicorn.access handler
|
||||||
if cfg.accesslog is not None:
|
if cfg.accesslog is not None:
|
||||||
@ -318,6 +329,18 @@ class Logger(object):
|
|||||||
return time.strftime('[%d/%b/%Y:%H:%M:%S %z]')
|
return time.strftime('[%d/%b/%Y:%H:%M:%S %z]')
|
||||||
|
|
||||||
def reopen_files(self):
|
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 log in loggers():
|
||||||
for handler in log.handlers:
|
for handler in log.handlers:
|
||||||
if isinstance(handler, logging.FileHandler):
|
if isinstance(handler, logging.FileHandler):
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user