|
@@ -17,6 +17,7 @@ import logging
|
|
|
import logging.config
|
|
|
import os
|
|
|
import sys
|
|
|
+import threading
|
|
|
from string import Template
|
|
|
|
|
|
import yaml
|
|
@@ -25,6 +26,7 @@ from twisted.logger import (
|
|
|
ILogObserver,
|
|
|
LogBeginner,
|
|
|
STDLibLogObserver,
|
|
|
+ eventAsText,
|
|
|
globalLogBeginner,
|
|
|
)
|
|
|
|
|
@@ -216,8 +218,9 @@ def _setup_stdlib_logging(config, log_config, logBeginner: LogBeginner):
|
|
|
# system.
|
|
|
observer = STDLibLogObserver()
|
|
|
|
|
|
- def _log(event):
|
|
|
+ threadlocal = threading.local()
|
|
|
|
|
|
+ def _log(event):
|
|
|
if "log_text" in event:
|
|
|
if event["log_text"].startswith("DNSDatagramProtocol starting on "):
|
|
|
return
|
|
@@ -228,7 +231,25 @@ def _setup_stdlib_logging(config, log_config, logBeginner: LogBeginner):
|
|
|
if event["log_text"].startswith("Timing out client"):
|
|
|
return
|
|
|
|
|
|
- return observer(event)
|
|
|
+ # this is a workaround to make sure we don't get stack overflows when the
|
|
|
+ # logging system raises an error which is written to stderr which is redirected
|
|
|
+ # to the logging system, etc.
|
|
|
+ if getattr(threadlocal, "active", False):
|
|
|
+ # write the text of the event, if any, to the *real* stderr (which may
|
|
|
+ # be redirected to /dev/null, but there's not much we can do)
|
|
|
+ try:
|
|
|
+ event_text = eventAsText(event)
|
|
|
+ print("logging during logging: %s" % event_text, file=sys.__stderr__)
|
|
|
+ except Exception:
|
|
|
+ # gah.
|
|
|
+ pass
|
|
|
+ return
|
|
|
+
|
|
|
+ try:
|
|
|
+ threadlocal.active = True
|
|
|
+ return observer(event)
|
|
|
+ finally:
|
|
|
+ threadlocal.active = False
|
|
|
|
|
|
logBeginner.beginLoggingTo([_log], redirectStandardIO=not config.no_redirect_stdio)
|
|
|
if not config.no_redirect_stdio:
|