Metadata-Version: 2.4
Name: vlobservability
Version: 1.0.0
Summary: Structured logging for Value Link Software services with Grafana Loki support.
Author: Value Link Software Platform Engineering
License-Expression: MIT
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Framework :: FastAPI
Requires-Python: >=3.10
Description-Content-Type: text/markdown
License-File: LICENSE
Provides-Extra: dev
Requires-Dist: build>=1.2; extra == "dev"
Dynamic: license-file

# vlobservability (Python)

`vlobservability` provides structured logging for Value Link Software Python
services, with console output and optional Grafana Loki delivery. It follows
the configuration and resilience conventions of the repository's .NET and Go
packages.

## Install

```bash
pip install vlobservability
```

FastAPI is not a mandatory dependency. The included middleware implements the
ASGI interface and can be installed directly on a FastAPI application.

## Quick Start

```python
import logging

from fastapi import FastAPI

from vlobservability import ObservabilityMiddleware, ObservabilityOptions
from vlobservability import configure_logging, shutdown_logging

options = ObservabilityOptions(
    service_name="orders-api",
    service_version="1.0.0",
    environment="Development",
    loki_url="http://localhost:3100",
)

configure_logging(options)

app = FastAPI()
app.add_middleware(ObservabilityMiddleware)


@app.get("/health")
async def health():
    logging.getLogger(__name__).info("Health check completed")
    return {"status": "ok"}


@app.on_event("shutdown")
def flush_observability():
    shutdown_logging()
```

`loki_url` can be a Loki base URL such as `http://loki:3100` or a complete
push endpoint. An empty URL disables Loki delivery while console logging
continues to work.

## What is sent to Loki?

Loki labels are deliberately low-cardinality:

- `app`
- `environment`
- `service_name`
- `hostname`

The log line itself is JSON and contains `Application`, `Environment`,
`ServiceVersion`, `Hostname`, `Level`, `Logger`, `Message`, exception details,
and values passed through Python's `extra` argument.

The middleware adds `RequestId`, `HttpMethod`, and `HttpPath` to logs created
while a request is being handled. It also emits a completion log containing
status code, duration, and response size. If `opentelemetry-api` is installed
and an active span exists, `TraceId` and `SpanId` are included automatically.

```python
logger.info(
    "Order created",
    extra={"OrderId": order_id, "CustomerId": customer_id},
)
```

## Resilience

- Console logging is always configured.
- Loki delivery runs in a background worker and does not block request code.
- Records are batched up to 100 entries or two seconds by default.
- Failed batches are dropped with a warning; the application keeps running.
- `shutdown_logging()` flushes buffered records before the process exits.

Batch size, flush interval, timeout, and queue size can be changed through
`ObservabilityOptions`.

## Development

Run the tests from this directory:

```bash
python -m unittest discover -s tests -v
```

Build a wheel and source distribution with:

```bash
python -m build
```

## License

MIT. See the repository [LICENSE](../LICENSE).
