Skip to content

Keep ReplaySafeLoggerProvider working with opentelemetry-api 1.45 - #2030

Merged
tconley1428 merged 3 commits into
temporalio:mainfrom
sangkyoonnam:fix/replay-safe-logger-enabled
Oct 28, 2026
Merged

tconley1428 merged 3 commits into
temporalio:mainfrom
sangkyoonnam:fix/replay-safe-logger-enabled

Conversation

@sangkyoonnam

Copy link
Copy Markdown
Contributor

With opentelemetry-api 1.45, ReplaySafeLoggerProvider.get_logger() raises TypeError: Can't instantiate abstract class _ReplaySafeLogger without an implementation for abstract method 'enabled'. Uncaught inside a workflow, that fails the workflow task on every attempt by default. 1.45.0 added Logger.enabled as an abstract method, and _ReplaySafeLogger doesn't implement it.

The opentelemetry extra allows opentelemetry-api>=1.26,<2, and a fresh uv pip install "temporalio[opentelemetry]==1.34.0" resolved 1.45.1 on October 28. This repo's lock pins 1.42.1, and the October 27 test-latest-deps run also installed 1.42.1, so test_wrapper_abc_drift.py didn't exercise the new method in that run.

This change adds enabled() to _ReplaySafeLogger. While the workflow is replaying history events it returns False, the same check emit() uses, since callers check enabled() to skip building a record. Otherwise it delegates to the wrapped logger when the logger has enabled(), and returns True when it doesn't, as with loggers from an API before 1.45, so a caller that checks hasattr first doesn't hit AttributeError.

Four tests in tests/contrib/opentelemetry/test_logger_provider.py cover delegation outside a workflow, False during replay, delegation in the state a query or update validator sees during replay (simulated like the existing tests), and a wrapped logger without enabled(). Run against main with 1.42.1, the replay test, whose test logger implements enabled(), fails with assert not True, because __getattr__ forwards the call even during replay.

With 1.45.1, a workflow that emits one log record through ReplaySafeLoggerProvider fails every workflow task with the TypeError above on main, and completes with this change, exporting the record.

1.45 also removed opentelemetry.util.types._ExtendedAttributes, which these files import. That breaks type checks and this test module on 1.45, and needs a choice of annotation, so it's in #2029.

Validation, with Python 3.12 and the Rust bridge of the temporalio 1.34.0 wheel:

  • test_logger_provider.py and test_wrapper_abc_drift.py pass with opentelemetry-api 1.42.1 and 1.43.0 (22 tests), and test_wrapper_abc_drift.py passes with 1.45.1.
  • Ruff 0.15.22 (check --select I, format --check), pyright 1.1.403, basedpyright 1.34.0 and mypy pass on the changed files with 1.42.1 and 1.43.0, and pydocstyle passes on the changed source file.

@sangkyoonnam
sangkyoonnam requested a review from a team as a code owner October 28, 2026 12:58
@CLAassistant

CLAassistant commented Oct 28, 2026 •

Copy link
Copy Markdown

CLA assistant check
All committers have signed the CLA.

@tconley1428

Copy link
Copy Markdown
Contributor

Seems reasonable, but we need a CLA signature.

@CLAassistant

Copy link
Copy Markdown

CLA assistant check
Thank you for your submission! We really appreciate it. Like many open source projects, we ask that you sign our Contributor License Agreement before we can accept your contribution.
You have signed the CLA already but the status is still pending? Let us recheck it.

@sangkyoonnam

Copy link
Copy Markdown
Contributor Author

Signed the CLA, and license/cla is green now. Thanks for taking a look.

@tconley1428
tconley1428 merged commit ea7daa8 into temporalio:main Oct 28, 2026
20 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants