Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions agent-notes/improve-repeated-setup.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# Goal

Replace only this package's handlers on repeated logging setup.

# State

Rebuilt on master after #2, #3, #4, #6 and #7 merged. Keep the root logger and existing helper API. After the staged replacement succeeds, detach and close the handlers this package installed previously.

# Decisions and why

Builds on #4's staging: a failed setup closes its staged handlers and leaves installed handlers, root level and exception hook untouched, so this change needs no rollback code of its own. Fault handling uses #3's crashlogger state: a call that does not enable crash logging disables it before old streams close; a call that enables it has already retargeted it to the new stream. Track only owned handlers, preserve unrelated ones, and restore the previous exception hook when a repeat call or shutdown turns it off. Setup and shutdown run on the main thread.

# Surprises

The earlier version of this PR duplicated #3's fault-handler tracking and #4's rollback; both were removed when rebuilding on merged master. Opening a file may still truncate its contents before a later failure.

# Next step

Read the PR's package checks and merge. No release.
24 changes: 24 additions & 0 deletions logger_setup/logger_setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@
except NameError:
logger = logging.getLogger()

_handlers = []
_previous_excepthook = None


def create_handler(
filename=None,
Expand Down Expand Up @@ -56,6 +59,7 @@ def setup_logging(
remote_address=None,
remote_level=logging.ERROR,
):
global _handlers, _previous_excepthook
formatter = logging.Formatter(message_format)
handlers = []
try:
Expand Down Expand Up @@ -96,13 +100,33 @@ def setup_logging(

for handler in handlers:
logger.addHandler(handler)
# The fault handler must stop using an old stream before that stream closes.
if not (error_log and log_crashes):
crashlogger.disable_crashlogger()
for handler in _handlers:
logger.removeHandler(handler)
handler.close()
_handlers = handlers
logger.setLevel(logging.DEBUG)
if log_unhandled_exceptions:
if sys.excepthook is not custom_excepthook:
_previous_excepthook = sys.excepthook
sys.excepthook = custom_excepthook
elif sys.excepthook is custom_excepthook:
sys.excepthook = _previous_excepthook
_previous_excepthook = None
logger.info("Logging initialized. PID: %d", os.getpid())
return logger


def shutdown():
global _handlers, _previous_excepthook
crashlogger.disable_crashlogger()
for handler in _handlers:
logger.removeHandler(handler)
handler.close()
_handlers = []
if sys.excepthook is custom_excepthook:
sys.excepthook = _previous_excepthook
_previous_excepthook = None
logging.shutdown()
Loading