Give a node's fluksio module the logger the SDK exports
Inside a worker `import fluksio` is the reporter, which had emit and the artifact calls but no logger — so `fluksio.logger.info(...)`, written against the SDK's top-level export, died with AttributeError after the training it was reporting on had already succeeded. Its records go to the same capture a print does; the handler resolves sys.stderr per record because a call runs under redirect_stderr. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019Hra4ndWMCLU5F3KjUuVAc
This commit is contained in:
@@ -45,6 +45,7 @@ import hashlib
|
||||
import inspect
|
||||
import io
|
||||
import json
|
||||
import logging
|
||||
import tempfile
|
||||
import time
|
||||
import traceback
|
||||
@@ -150,6 +151,18 @@ class _Reporter(ModuleType):
|
||||
return _Declared()
|
||||
|
||||
|
||||
class _LogHandler(logging.Handler):
|
||||
"""Writes to whatever ``sys.stderr`` is at the time of the record.
|
||||
|
||||
A call runs under ``redirect_stderr`` into the buffer that becomes the
|
||||
node's logs, so a handler holding the stream it was built with would write
|
||||
past every one of them.
|
||||
"""
|
||||
|
||||
def emit(self, record: logging.LogRecord) -> None:
|
||||
sys.stderr.write(self.format(record) + "\n")
|
||||
|
||||
|
||||
class _Declared:
|
||||
"""Stands in for a declaration whose work was done before the run.
|
||||
|
||||
@@ -294,6 +307,17 @@ def _install_reporter() -> None:
|
||||
"""Put ``fluksio`` on the import path of every node this worker runs."""
|
||||
module = _Reporter("fluksio")
|
||||
module.__doc__ = "Report metrics and progress from inside a node."
|
||||
# The SDK exports a logger at top level, so a node written against it says
|
||||
# `fluksio.logger.info(...)` — which used to die with AttributeError, after
|
||||
# whatever it was reporting on had already succeeded. Its records land in
|
||||
# the same capture as a print.
|
||||
logger = logging.getLogger("fluksio")
|
||||
logger.setLevel(logging.INFO)
|
||||
logger.addHandler(_LogHandler())
|
||||
# Nothing above it should see these twice: a node calling `basicConfig` for
|
||||
# its own logging installs a root handler on the same stream.
|
||||
logger.propagate = False
|
||||
module.logger = logger
|
||||
sys.modules["fluksio"] = module
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user