Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: when handling actions, print uncaught exceptions to stderr #1087

Merged
merged 9 commits into from
Dec 15, 2023
8 changes: 7 additions & 1 deletion ops/log.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,8 @@ def emit(self, record: logging.LogRecord):
self.model_backend.juju_log(record.levelname, self.format(record))


def setup_root_logging(model_backend: _ModelBackend, debug: bool = False):
def setup_root_logging(model_backend: _ModelBackend, debug: bool = False,
exc_stderr: bool = False):
"""Setup python logging to forward messages to juju-log.

By default, logging is set to DEBUG level, and messages will be filtered by Juju.
Expand All @@ -49,6 +50,7 @@ def setup_root_logging(model_backend: _ModelBackend, debug: bool = False):
Args:
model_backend: a ModelBackend to use for juju-log
debug: if True, write logs to stderr as well as to juju-log.
exc_stderr: if True, write uncaught exceptions to stderr as well as to juju-log.
"""
logger = logging.getLogger()
logger.setLevel(logging.DEBUG)
Expand All @@ -65,5 +67,9 @@ def except_hook(etype: typing.Type[BaseException],
logger.error(
"Uncaught exception while in charm code:",
exc_info=(etype, value, tb))
if exc_stderr:
print(f"Uncaught exception while in charm code: {etype.__name__}: {value}",
tonyandrewmeyer marked this conversation as resolved.
Show resolved Hide resolved
file=sys.stderr)
print("Use `juju debug-log` to see the full traceback.", file=sys.stderr)

sys.excepthook = except_hook
6 changes: 5 additions & 1 deletion ops/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -373,7 +373,11 @@ def main(charm_class: Type[ops.charm.CharmBase],

model_backend = ops.model._ModelBackend()
debug = ('JUJU_DEBUG' in os.environ)
setup_root_logging(model_backend, debug=debug)
# For actions, there is a communication channel with the user running the
# action, so we want to send exception details through stderr, rather than
# only to juju-log as normal.
handling_action = ('JUJU_ACTION_NAME' in os.environ)
setup_root_logging(model_backend, debug=debug, exc_stderr=handling_action)
logger.debug("ops %s up and running.", ops.__version__) # type:ignore

dispatcher = _Dispatcher(charm_dir)
Expand Down
Loading