Skip to content

Commit d3a1ef1

Browse files
authored
docs: add logging documentation
The FFI introduces additional complexities when it comes to logging, and as a result, how to enable and configure logging needs its own dedicated section. Fixes: #1302
1 parent b531a5f commit d3a1ef1

File tree

4 files changed

+168
-0
lines changed

4 files changed

+168
-0
lines changed

docs/SUMMARY.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
- [Home](README.md)
44
- [Consumer](consumer.md)
55
- [Provider](provider.md)
6+
- [Logging](logging.md)
67
- [Releases](releases.md)
78
- [Migration Guide](MIGRATION.md)
89
- [Changelog](CHANGELOG.md)

docs/consumer.md

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,24 @@ The mock service can handle multiple interactions within a single test. This is
186186

187187
When the mock service is started with `pact.serve()`, it will handle requests for all defined interactions, ensuring the client code can be tested against a realistic sequence of operations. Furthermore, for the test to pass, all defined interactions must be exercised by the client code. If any interaction is not used, the test will fail.
188188

189+
## Logging
190+
191+
To enable logging for debugging and troubleshooting, configure the FFI (Foreign Function Interface) logging using [`pact_ffi.log_to_stderr`][pact_ffi.log_to_stderr]. This is particularly useful when you need to understand what's happening inside the mock service or diagnose issues with your tests.
192+
193+
The recommended approach is to set up logging in a pytest fixture within your `conftest.py`:
194+
195+
```python
196+
import pytest
197+
import pact_ffi
198+
199+
@pytest.fixture(autouse=True, scope="session")
200+
def pact_logging():
201+
"""Configure Pact FFI logging for the test session."""
202+
pact_ffi.log_to_stderr("INFO")
203+
```
204+
205+
For more information on logging configuration, including advanced options and troubleshooting, see the [Logging Configuration](logging.md) page.
206+
189207
## Mock Service
190208

191209
Pact provides a mock service that simulates the provider service based on the defined interactions. The mock service is started when the `pact` object is used as a context manager with `pact.serve()`, as shown in the [consumer test](#consumer-test) example above.

docs/logging.md

Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+
# Logging Configuration
2+
3+
Pact Python uses the Rust FFI (Foreign Function Interface) library for its core functionality. While the Python code uses the standard library `logging` module, the underlying FFI cannot interface with that directly. This page explains how to configure FFI logging for debugging and troubleshooting.
4+
5+
## Basic Configuration
6+
7+
The simplest way to configure FFI logging is to use the [`log_to_stderr`][pact_ffi.log_to_stderr] function from the `pact_ffi` module. This directs all FFI log output to standard error.
8+
9+
```python
10+
import pact_ffi
11+
12+
pact_ffi.log_to_stderr("INFO")
13+
```
14+
15+
### Log Levels
16+
17+
The following log levels are available (from least to most verbose):
18+
19+
- `"OFF"` - Disable all logging
20+
- `"ERROR"` - Only error messages
21+
- `"WARN"` - Warnings and errors
22+
- `"INFO"` - Informational messages, warnings, and errors
23+
- `"DEBUG"` - Debug messages and above
24+
- `"TRACE"` - All messages including trace-level details
25+
26+
## Recommended Setup with Pytest
27+
28+
<!-- markdownlint-disable code-block-style -->
29+
!!! warning "One-time Initialization"
30+
31+
The FFI logging can only be initialized **once** per process. Attempting to configure it multiple times will result in an error. For this reason, it's recommended to set up logging in a session-scoped fixture.
32+
<!-- markdownlint-enable code-block-style -->
33+
34+
The recommended way to configure FFI logging in your test suite is to use a pytest fixture with `autouse=True` and `scope="session"` in your `conftest.py` file:
35+
36+
```python
37+
import pytest
38+
import pact_ffi
39+
40+
@pytest.fixture(autouse=True, scope="session")
41+
def pact_logging():
42+
"""Configure Pact FFI logging for the test session."""
43+
pact_ffi.log_to_stderr("INFO")
44+
```
45+
46+
This ensures that:
47+
48+
1. Logging is configured automatically for all tests
49+
2. It's only initialized once at the start of the test session
50+
3. All test output includes relevant Pact FFI logs
51+
52+
## Advanced Configuration
53+
54+
For more advanced use cases, the `pact_ffi` module provides additional logging functions:
55+
56+
### Logging to a File
57+
58+
<!-- markdownlint-disable code-block-style -->
59+
!!! note "Not Yet Implemented"
60+
61+
The `log_to_file` function is currently not implemented in the Python bindings. If you need this feature, please open an issue on the [Pact Python GitHub repository](https://github.com/pact-foundation/pact-python/issues).
62+
<!-- markdownlint-enable code-block-style -->
63+
64+
To direct logs to a file instead of stderr, you would use:
65+
66+
```python
67+
import pact_ffi
68+
69+
# This will be available in a future release
70+
pact_ffi.log_to_file("/path/to/logfile.log", pact_ffi.LevelFilter.DEBUG)
71+
```
72+
73+
### Logging to a Buffer
74+
75+
For applications that need to capture and process logs programmatically, you can use [`log_to_buffer`][pact_ffi.log_to_buffer]:
76+
77+
```python
78+
import pact_ffi
79+
80+
# Configure logging to an internal buffer
81+
pact_ffi.log_to_buffer("DEBUG")
82+
```
83+
84+
This is particularly useful for:
85+
86+
- Capturing logs in CI/CD environments
87+
- Including logs in test failure reports
88+
- Processing or filtering log messages programmatically
89+
90+
<!-- markdownlint-disable code-block-style -->
91+
!!! note "Retrieving Buffer Contents"
92+
93+
The `fetch_log_buffer` function for retrieving buffered logs is currently not implemented in the Python bindings. If you need this feature, please open an issue on the [Pact Python GitHub repository](https://github.com/pact-foundation/pact-python/issues).
94+
<!-- markdownlint-enable code-block-style -->
95+
96+
### Multiple Sinks
97+
98+
<!-- markdownlint-disable code-block-style -->
99+
!!! note "Advanced Usage"
100+
101+
The functions `logger_init`, `logger_attach_sink`, and `logger_apply` are currently not implemented in the Python bindings. If you need these features, please open an issue on the [Pact Python GitHub repository](https://github.com/pact-foundation/pact-python/issues).
102+
<!-- markdownlint-enable code-block-style -->
103+
104+
For the most advanced scenarios, the FFI supports configuring multiple log sinks simultaneously (e.g., logging to both stderr and a file). This requires using the lower-level `logger_init`, `logger_attach_sink`, and `logger_apply` functions, which are planned for future implementation.
105+
106+
## Troubleshooting
107+
108+
### "Logger already initialized" Error
109+
110+
If you see an error about the logger already being initialized, it means you're trying to configure FFI logging more than once. Ensure that:
111+
112+
1. You're using a session-scoped fixture as shown above
113+
2. You're not calling any of the `log_to_*` functions multiple times in your code
114+
3. If running tests multiple times in the same process (e.g., with pytest-xdist), the fixture scope is set correctly
115+
116+
### No Log Output
117+
118+
If you're not seeing any log output:
119+
120+
1. Check that the log level is appropriate - `"ERROR"` will only show errors, while `"INFO"` or `"DEBUG"` will show more information
121+
2. Verify that the logging is configured before any Pact operations are performed
122+
3. For `log_to_file`, ensure the file path is writable and the directory exists
123+
124+
## Further Information
125+
126+
For complete API documentation, see:
127+
128+
- [`pact_ffi.log_to_stderr`][pact_ffi.log_to_stderr]
129+
- [`pact_ffi.log_to_file`][pact_ffi.log_to_file]
130+
- [`pact_ffi.log_to_buffer`][pact_ffi.log_to_buffer]
131+
- [`pact_ffi.LevelFilter`][pact_ffi.LevelFilter]

docs/provider.md

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,24 @@ def test_provider_with_selectors():
108108

109109
More information on the selector options is available in the [API reference][pact.verifier.BrokerSelectorBuilder].
110110

111+
## Logging
112+
113+
To enable logging for debugging and troubleshooting, configure the FFI (Foreign Function Interface) logging using [`pact_ffi.log_to_stderr`][pact_ffi.log_to_stderr]. This is particularly useful when you need to understand what's happening during provider verification or diagnose issues with provider state handlers.
114+
115+
The recommended approach is to set up logging in a pytest fixture within your `conftest.py`:
116+
117+
```python
118+
import pytest
119+
import pact_ffi
120+
121+
@pytest.fixture(autouse=True, scope="session")
122+
def pact_logging():
123+
"""Configure Pact FFI logging for the test session."""
124+
pact_ffi.log_to_stderr("INFO")
125+
```
126+
127+
For more information on logging configuration, including advanced options and troubleshooting, see the [Logging Configuration](logging.md) page.
128+
111129
### Publishing Results
112130

113131
To publish verification results to the Broker:

0 commit comments

Comments
 (0)