|
| 1 | +# wisepay-observability |
| 2 | + |
| 3 | +Shared structured-logging + tracing library for wisepay services. It ships JSON |
| 4 | +log records to OpenSearch (with a console fallback), and propagates W3C trace |
| 5 | +context across services so logs can be correlated by `trace_id`. |
| 6 | + |
| 7 | +Consumed by `ym-api`, `iris`, `currency-exchange-rates-api`, `tg-bot`, |
| 8 | +`currency-exchange-rates-parsers` and `banking`. |
| 9 | + |
| 10 | +## Install |
| 11 | + |
| 12 | +Pinned by tag (this is the supported install path — every release also attaches |
| 13 | +a built wheel + sdist): |
| 14 | + |
| 15 | +``` |
| 16 | +wisepay-observability @ git+https://github.com/wisepayru/observability.git@1.1.1 |
| 17 | +``` |
| 18 | + |
| 19 | +Requires Python >= 3.14. |
| 20 | + |
| 21 | +## Quickstart |
| 22 | + |
| 23 | +### HTTP service (FastAPI / Starlette) |
| 24 | + |
| 25 | +```python |
| 26 | +from fastapi import FastAPI |
| 27 | +from observability import setup_logging, TraceMiddleware |
| 28 | + |
| 29 | +setup_logging() # configure root logging from the environment |
| 30 | +app = FastAPI() |
| 31 | +app.add_middleware(TraceMiddleware) |
| 32 | +``` |
| 33 | + |
| 34 | +`TraceMiddleware` starts (or continues, from an inbound `traceparent`) a trace |
| 35 | +per request, stores `trace_id`/`span_id` in context so every log record carries |
| 36 | +them, logs one record per request with **sanitized** headers (secrets like |
| 37 | +`authorization` / `cookie` / `x-api-key` redacted), and sets a `traceparent` |
| 38 | +response header. |
| 39 | + |
| 40 | +### Outgoing calls — propagate the trace |
| 41 | + |
| 42 | +```python |
| 43 | +import httpx |
| 44 | +from observability import build_outgoing_headers |
| 45 | + |
| 46 | +async with httpx.AsyncClient() as client: |
| 47 | + await client.get(url, headers=build_outgoing_headers()) |
| 48 | +``` |
| 49 | + |
| 50 | +### Scripts / workers / bots |
| 51 | + |
| 52 | +```python |
| 53 | +from observability import setup_logging, run_context |
| 54 | + |
| 55 | +setup_logging() |
| 56 | +with run_context("nightly-rates"): |
| 57 | + fetch_and_store_rates() # every log inside carries the run's trace_id |
| 58 | +``` |
| 59 | + |
| 60 | +`interaction_context` is an alias of `run_context` (used by `tg-bot`). |
| 61 | + |
| 62 | +## Configuration |
| 63 | + |
| 64 | +`setup_logging()` reads everything from the environment: |
| 65 | + |
| 66 | +| Variable | Default | Purpose | |
| 67 | +|---|---|---| |
| 68 | +| `OPENSEARCH_HOST` | _(unset)_ | OpenSearch node URL. **If unset (or no password), logs go to the console** instead of OpenSearch. | |
| 69 | +| `OPENSEARCH_PASSWORD` | _(unset)_ | Basic-auth password; required (with host) to enable the OpenSearch handler. | |
| 70 | +| `OPENSEARCH_USER` | `admin` | Basic-auth username. | |
| 71 | +| `OPENSEARCH_INDEX` | `wisepay-logs` | Target index. Services set this per app, e.g. `wisepay-ym-api`. | |
| 72 | +| `SERVICE_NAME` | `wisepay-service` | Emitted as `service` on every record. | |
| 73 | +| `APP_ENV` | `production` | Emitted as `env`. | |
| 74 | +| `LOG_LEVEL` | `DEBUG` | Root log level. | |
| 75 | +| `LOG_BATCH_SIZE` | `50` | Records per bulk flush. | |
| 76 | +| `LOG_FLUSH_INTERVAL` | `1.0` | Seconds between flushes. | |
| 77 | +| `LOG_MAX_QUEUE_SIZE` | `10000` | In-memory queue cap (overflow falls back to stderr). | |
| 78 | + |
| 79 | +Business logs ship to OpenSearch **or** the console, not both. App code can |
| 80 | +attach arbitrary fields via `extra=` (e.g. `correlation_id`, `order_id`) and |
| 81 | +they pass through to the document untouched. |
| 82 | + |
| 83 | +## Development |
| 84 | + |
| 85 | +```bash |
| 86 | +python3.14 -m venv .venv |
| 87 | +.venv/bin/pip install -e . -r requirements-test.txt |
| 88 | +.venv/bin/ruff check . |
| 89 | +.venv/bin/pytest |
| 90 | +``` |
| 91 | + |
| 92 | +See [`tests/README.md`](tests/README.md) for the test layout and |
| 93 | +[`docs/release.md`](docs/release.md) for the versioning + release flow. |
0 commit comments