Skip to content

feat: add plugin observability module - #1694

Draft
JP-Ellis wants to merge 1 commit into
mainfrom
feat/plugin-observability
Draft

JP-Ellis wants to merge 1 commit into
mainfrom
feat/plugin-observability

Conversation

@JP-Ellis

Copy link
Copy Markdown
Member

Goal

Pact FFI 0.5.5 added plugin observability: a per-thread test run ID sent to plugins, a log callback for entries from any running plugin, and a per-instance log buffer. The pact-python-ffi 0.5.8 release wrapped these; this PR surfaces them in the main library as pact.plugins.

What it adds

  • set_test_run_id — tags plugin requests from the current thread so log entries can be attributed to a test.
  • register_log_callback — delivers each entry as a PluginLogEntry dataclass.
  • forward_to_logging — ready-made callback emitting through the standard logging module at the equivalent level, with plugin_instance_id, test_run_id and plugin_target attached to each record.
  • get_logs — the entries buffered for a plugin instance, with timestamp_ms converted to a UTC datetime.

A single CFFI trampoline is registered with the library and dispatches to whichever Python callable is current. Upstream ignores a NULL registration, so this is what makes register_log_callback(None) actually stop delivery.

Prerequisite worth knowing

The FFI only installs its plugin log sink from pactffi_init / pactffi_init_with_log_level, not from log_to_stderr. Without one of those, the callback is silently never invoked. The module docstring and docs/logging.md direct users to pact_ffi.init_with_log_level in its place; ideally upstream would install the sink from pactffi_register_plugin_log_callback itself.

Verification

  • 18 unit tests drive the registered C callback directly and cover level mapping, None normalisation, callback replacement and deregistration, and logging forwarding.
  • End-to-end against a real plugin process: the bundled csv/protobuf plugins write nothing to stderr and predate the Log RPC, so a scratch plugin under PACT_PLUGIN_DIR that writes to stderr was used. Entries arrived through forward_to_logging with the extras populated, and get_logs returned the same entries with plugin_name, source="Stderr" and timestamps.
  • mkdocs build resolves every cross-reference in the new module and the logging page.

Pact FFI 0.5.5 lets a host correlate plugin activity with a test and
receive plugin log entries. `pact.plugins` exposes this in the main
library:

-   `set_test_run_id` tags plugin requests from the current thread.
-   `register_log_callback` delivers each entry as a `PluginLogEntry`.
-   `forward_to_logging` emits entries through the standard `logging`
    module, with the instance ID, test run ID and plugin target attached
    to each record.
-   `get_logs` returns the entries buffered for a plugin instance, with
    the timestamp converted to a UTC `datetime`.

A single CFFI trampoline is registered with the library and dispatches
to whichever Python callable is current. The library ignores a NULL
registration, so this is what makes `register_log_callback(None)` stop
delivery.

The FFI only installs its plugin log sink from `pactffi_init` and
`pactffi_init_with_log_level`, so the module and the logging docs
direct users to `pact_ffi.init_with_log_level` in place of
`log_to_stderr`.

Signed-off-by: JP-Ellis <josh@jpellis.me>
Assisted-by: Claude Code:claude-opus-5
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.

1 participant