From c07e3cbde21807a4e193b3527ef8686a22cf4d96 Mon Sep 17 00:00:00 2001 From: goodboy Date: Fri, 21 Aug 2026 01:11:25 -0400 Subject: [PATCH] Preserve exact `piker` logger namespaces Use `str.removeprefix()` instead of character-set stripping so subloggers such as `piker.paper` retain their requested namespace. Also, - drop stale parent-logger assertions from daemon startup paths - keep logger setup calls without assigning assertion-only locals - cover both logger factories and prefix-sensitive module names Prompt-IO: ai/prompt-io/opencode/20260821T042058Z_b7aca4c0_prompt_io.md (this patch was generated in some part by `opencode` using `gpt-5.6-sol` (`openai`)) --- .../20260821T042058Z_b7aca4c0_prompt_io.md | 39 ++++++++++++++++ ...20260821T042058Z_b7aca4c0_prompt_io.raw.md | 24 ++++++++++ piker/brokers/_daemon.py | 3 +- piker/clearing/_ems.py | 3 +- piker/data/_daemon.py | 3 +- piker/log.py | 33 ++++++-------- piker/service/_daemon.py | 1 - tests/test_logging.py | 44 +++++++++++++++++++ 8 files changed, 123 insertions(+), 27 deletions(-) create mode 100644 ai/prompt-io/opencode/20260821T042058Z_b7aca4c0_prompt_io.md create mode 100644 ai/prompt-io/opencode/20260821T042058Z_b7aca4c0_prompt_io.raw.md create mode 100644 tests/test_logging.py diff --git a/ai/prompt-io/opencode/20260821T042058Z_b7aca4c0_prompt_io.md b/ai/prompt-io/opencode/20260821T042058Z_b7aca4c0_prompt_io.md new file mode 100644 index 00000000..82fb63be --- /dev/null +++ b/ai/prompt-io/opencode/20260821T042058Z_b7aca4c0_prompt_io.md @@ -0,0 +1,39 @@ +--- +model: gpt-5.6-sol +service: opencode +session: tractor-addr-unpacking +timestamp: 2026-08-21T04:20:58Z +git_ref: b7aca4c0 +scope: code +substantive: true +raw_file: 20260821T042058Z_b7aca4c0_prompt_io.raw.md +--- + +## Prompt + +The human approved refining Piker's logger-name handling after the +wider service test exposed a stale parent-logger assertion during the +tractor tagged-address compatibility work. + +## Response summary + +Changed Piker's logger helpers to remove only an exact `piker.` prefix, +preserving complete requested submodule names. Removed daemon startup +assertions that incorrectly required parent logger names and added a +regression covering both logger factories and names that the old +character-set stripping silently corrupted. + +## Files changed + +- `piker/log.py` - exact relative logger-name derivation. +- `piker/service/_daemon.py` - remove stale parent-name assertion. +- `piker/data/_daemon.py` - remove stale parent-name assertion. +- `piker/brokers/_daemon.py` - remove stale parent-name assertion. +- `piker/clearing/_ems.py` - remove redundant logger assertion. +- `tests/test_logging.py` - package logger namespace regressions. + +## Human edits + +The human explicitly approved this follow-up after reviewing the +residual Piker service-suite gap. The agent implemented and verified +the refinement; no direct manual source edits were observed. diff --git a/ai/prompt-io/opencode/20260821T042058Z_b7aca4c0_prompt_io.raw.md b/ai/prompt-io/opencode/20260821T042058Z_b7aca4c0_prompt_io.raw.md new file mode 100644 index 00000000..9b87f3b3 --- /dev/null +++ b/ai/prompt-io/opencode/20260821T042058Z_b7aca4c0_prompt_io.raw.md @@ -0,0 +1,24 @@ +--- +model: gpt-5.6-sol +service: opencode +timestamp: 2026-08-21T04:20:58Z +git_ref: b7aca4c0 +diff_cmd: git diff HEAD~1..HEAD +--- + +# Raw output - preserve Piker logger namespaces + +The human approved a follow-up refinement after the full Piker service +module exposed a stale logger-name assertion while qualifying tractor +PR #505. + +> `git diff HEAD~1..HEAD -- piker/log.py piker/service/_daemon.py piker/data/_daemon.py piker/brokers/_daemon.py piker/clearing/_ems.py tests/test_logging.py` + +Replaced character-set `str.lstrip()` calls with exact package-prefix +removal, removed assertion-only parent-logger expectations from daemon +startup paths, and added regression coverage for both logger factories +and prefix-sensitive submodule names. + +Ruff passed after removing newly unused logger assignments. All four +logger regressions and all six service integration tests passed against +the local tractor PR #505 checkout. diff --git a/piker/brokers/_daemon.py b/piker/brokers/_daemon.py index dafb3b81..8aa45f33 100644 --- a/piker/brokers/_daemon.py +++ b/piker/brokers/_daemon.py @@ -77,12 +77,11 @@ async def _setup_persistent_brokerd( # any further (level) configuration on their own B) actor: tractor.Actor = tractor.current_actor() tll: str = actor.loglevel - log = get_console_log( + get_console_log( level=loglevel or tll, name=f'{_util.subsys}.{brokername}', with_tractor_log=bool(tll), ) - assert log.name == _util.subsys # unblock caller await ctx.started() diff --git a/piker/clearing/_ems.py b/piker/clearing/_ems.py index 1d152926..4280dee0 100644 --- a/piker/clearing/_ems.py +++ b/piker/clearing/_ems.py @@ -810,11 +810,10 @@ async def _setup_persistent_emsd( ) -> None: if loglevel: - _log = get_console_log( + get_console_log( level=loglevel, name=subsys, ) - assert _log.name == 'piker.clearing' global _router diff --git a/piker/data/_daemon.py b/piker/data/_daemon.py index 116d1346..27f27a90 100644 --- a/piker/data/_daemon.py +++ b/piker/data/_daemon.py @@ -86,12 +86,11 @@ async def _setup_persistent_datad( # their own B) actor: tractor.Actor = tractor.current_actor() tll: str = actor.loglevel - log = get_console_log( + get_console_log( level=loglevel or tll, name=f'{_util.subsys}.{brokername}', with_tractor_log=bool(tll), ) - assert log.name == _util.subsys # XXX: ALSO enable console logging for the provider # backend's mod subtree (eg. `piker.brokers.ib.*`) diff --git a/piker/log.py b/piker/log.py index 0145debf..f5989fbf 100644 --- a/piker/log.py +++ b/piker/log.py @@ -36,6 +36,15 @@ from pygments import ( _proj_name: str = 'piker' +def _relative_name( + name: str|None, +) -> str|None: + if name: + return name.removeprefix(f'{_proj_name}.') + + return None + + def get_logger( name: str|None = None, **tractor_log_kwargs, @@ -47,17 +56,9 @@ def get_logger( See `tractor.log.get_logger()` for details. ''' - pkg_name: str = _proj_name - if ( - name - and - pkg_name in name - ): - name: str = name.lstrip(f'{_proj_name}.') - return tractor.log.get_logger( - name=name, - pkg_name=pkg_name, + name=_relative_name(name), + pkg_name=_proj_name, **tractor_log_kwargs, ) @@ -81,14 +82,6 @@ def get_console_log( You do it.. Bp ''' - pkg_name: str = _proj_name - if ( - name - and - pkg_name in name - ): - name: str = name.lstrip(f'{_proj_name}.') - tll: str|None = None if ( with_tractor_log is not False @@ -111,8 +104,8 @@ def get_console_log( return tractor.log.get_console_log( level=level, - name=name, - pkg_name=pkg_name, + name=_relative_name(name), + pkg_name=_proj_name, **tractor_log_kwargs, ) diff --git a/piker/service/_daemon.py b/piker/service/_daemon.py index e6e372df..d89bcaf2 100644 --- a/piker/service/_daemon.py +++ b/piker/service/_daemon.py @@ -72,7 +72,6 @@ async def maybe_spawn_daemon( level=loglevel, name=__name__, ) - assert log.name == 'piker.service' # serialize access to this section to avoid # 2 or more tasks racing to create a daemon diff --git a/tests/test_logging.py b/tests/test_logging.py new file mode 100644 index 00000000..43755446 --- /dev/null +++ b/tests/test_logging.py @@ -0,0 +1,44 @@ +''' +Package logger namespace regression tests. + +''' +import pytest + +from piker.log import ( + get_console_log, + get_logger, +) + + +@pytest.mark.parametrize( + 'factory', + [ + get_logger, + get_console_log, + ], +) +@pytest.mark.parametrize( + 'name', + [ + 'piker.service._daemon', + 'piker.paper', + ], +) +def test_package_logger_name( + factory, + name: str, +): + ''' + `str.lstrip('piker.')` treated the package prefix as a set of + removable characters. A submodule beginning with any of those + characters, such as `piker.paper`, was silently renamed to + `piker.aper`, while service code asserted a stale parent name. + + Exercise both logger factories with service and prefix-sensitive + submodule names, proving they retain the exact requested package + namespace. + + ''' + log = factory(name=name) + + assert log.name == name