Document kanta.ctx as the app-context channel for logemit
kanta.ctx already existed as a user-writable namespace for migrations; since LogEvent carries the kanta instance, ev.kanta.ctx is also the way for applications to pass per-connection metadata to their logemit callbacks, including for creation/bootstrap events. No API change needed.
This commit is contained in:
@@ -235,6 +235,9 @@ def resolve_user_key(value: str) -> str | None:
|
|||||||
`kanta` instance, and all relevant state: `action`, `user`, `extra`,
|
`kanta` instance, and all relevant state: `action`, `user`, `extra`,
|
||||||
`error` (for aborted transactions), `diff`, `previous`/`current` state
|
`error` (for aborted transactions), `diff`, `previous`/`current` state
|
||||||
dicts, the built `logfmt` chain, and version info for migration events.
|
dicts, the built `logfmt` chain, and version info for migration events.
|
||||||
|
Application-specific context (e.g. a connection id) can be stored in
|
||||||
|
`kanta.ctx` — a user-writable namespace — and read back in callbacks as
|
||||||
|
`event.kanta.ctx`, which also covers creation/bootstrap events.
|
||||||
- The built-in formatting is assembled from standard blocks that custom
|
- The built-in formatting is assembled from standard blocks that custom
|
||||||
emitters can reuse as-is or replace piecemeal:
|
emitters can reuse as-is or replace piecemeal:
|
||||||
- `event.header` — a lazy property producing the default one-line header
|
- `event.header` — a lazy property producing the default one-line header
|
||||||
|
|||||||
+4
-1
@@ -130,7 +130,10 @@ class Kanta(Generic[T]):
|
|||||||
"""User-writable context namespace.
|
"""User-writable context namespace.
|
||||||
|
|
||||||
Migration functions receive the ``Kanta`` instance and can read or
|
Migration functions receive the ``Kanta`` instance and can read or
|
||||||
mutate ``kanta.ctx`` during migrations.
|
mutate ``kanta.ctx`` during migrations. Applications can also store
|
||||||
|
arbitrary data here (e.g. a connection id); since
|
||||||
|
:class:`kanta.logging.LogEvent` carries the Kanta instance, logemit
|
||||||
|
callbacks can read it as ``event.kanta.ctx``.
|
||||||
"""
|
"""
|
||||||
return self._impl.ctx
|
return self._impl.ctx
|
||||||
|
|
||||||
|
|||||||
@@ -344,3 +344,18 @@ def test_header_is_settable_and_used_by_default_emit(capsys):
|
|||||||
err = capsys.readouterr().err
|
err = capsys.readouterr().err
|
||||||
assert "CUSTOM update" in err
|
assert "CUSTOM update" in err
|
||||||
assert "counter" in err # default diff routing still applies
|
assert "counter" in err # default diff routing still applies
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.asyncio
|
||||||
|
async def test_ctx_reachable_from_event(tmp_path, format_config):
|
||||||
|
path = tmp_path / "test.db"
|
||||||
|
kanta = make_kanta(path, Data, format_config)
|
||||||
|
kanta.ctx.connection_id = 7
|
||||||
|
seen = []
|
||||||
|
kanta.logemit(lambda ev: seen.append(ev.kanta.ctx.connection_id) or True)
|
||||||
|
await kanta.open()
|
||||||
|
with kanta.transaction(action="inc") as data:
|
||||||
|
data.counter = 1
|
||||||
|
await kanta.close()
|
||||||
|
|
||||||
|
assert seen and all(connection_id == 7 for connection_id in seen)
|
||||||
|
|||||||
Reference in New Issue
Block a user