Metadata-Version: 2.4
Name: opentelemetry-instrumentation-sanic
Version: 0.2.0
Summary: Zero-code OpenTelemetry instrumentation for the Sanic web framework
Author: Pham Le Gia Dai
License: Apache-2.0
License-File: LICENSE
Keywords: asgi,instrumentation,opentelemetry,sanic,tracing
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: Topic :: System :: Monitoring
Requires-Python: >=3.10
Requires-Dist: opentelemetry-api>=1.26.0
Requires-Dist: opentelemetry-instrumentation>=0.47b0
Requires-Dist: opentelemetry-sdk>=1.26.0
Requires-Dist: opentelemetry-semantic-conventions>=0.47b0
Provides-Extra: dev
Requires-Dist: build>=1.0; extra == 'dev'
Requires-Dist: prek>=0.0.1; extra == 'dev'
Requires-Dist: ruff>=0.6; extra == 'dev'
Requires-Dist: tox>=4.0; extra == 'dev'
Provides-Extra: instruments
Requires-Dist: sanic>=20.12.0; extra == 'instruments'
Provides-Extra: test
Requires-Dist: pytest-asyncio>=0.21; extra == 'test'
Requires-Dist: pytest>=7.0; extra == 'test'
Requires-Dist: sanic[test]; extra == 'test'
Description-Content-Type: text/markdown

# opentelemetry-instrumentation-sanic

Zero-code [OpenTelemetry](https://opentelemetry.io/) instrumentation for the
[Sanic](https://sanic.dev/) web framework (including ASGI deployments).

Every inbound HTTP request handled by Sanic is turned into a server span with
HTTP semantic-convention attributes, W3C context propagation, and correct
error status mapping — plus the standard HTTP server **metrics** — with **no
changes to your application code**.

## Metrics

Alongside spans, the instrumentation emits the standard HTTP server metrics:

| Metric                           | Instrument      | Unit        | Description                          |
| -------------------------------- | --------------- | ----------- | ------------------------------------ |
| `http.server.request.duration`   | histogram       | `s`         | Request latency.                     |
| `http.server.active_requests`    | up-down counter | `{request}` | In-flight requests.                  |
| `http.server.request.body.size`  | histogram       | `By`        | Request payload size (when present). |
| `http.server.response.body.size` | histogram       | `By`        | Response payload size.               |

Duration and body-size measurements carry `http.request.method`, `url.scheme`,
`http.route`, `network.protocol.version`, `http.response.status_code`, and
(for 5xx) `error.type`. The active-requests counter carries only the
low-cardinality `http.request.method` and `url.scheme`.

## Install

```bash
pip install opentelemetry-instrumentation-sanic
```

## Zero-code usage

```bash
opentelemetry-instrument \
    --traces_exporter console \
    --metrics_exporter console \
    python my_sanic_app.py
```

The `opentelemetry-instrument` launcher discovers this package through its
`opentelemetry_instrumentor` entry point and activates it before your app is
created.

## Programmatic usage

Call `instrument()` **before** constructing your `Sanic` app:

```python
from opentelemetry.instrumentation.sanic import SanicInstrumentor

SanicInstrumentor().instrument(excluded_urls="/health,/metrics")

from sanic import Sanic
app = Sanic("my-app")
```

See [`examples/manual_app.py`](examples/manual_app.py) for a runnable example.

## Configuration

`SanicInstrumentor().instrument()` accepts:

| Keyword           | Type                    | Description                                                    |
| ----------------- | ----------------------- | ------------------------------------------------------------- |
| `tracer_provider` | `TracerProvider`        | Provider to use; defaults to the global provider.             |
| `meter_provider`  | `MeterProvider`         | Provider to use; defaults to the global provider.             |
| `excluded_urls`   | `str` / iterable[`str`] | Regex patterns whose matching URLs are neither traced nor measured. |

## Development

```bash
pip install -e ".[test]"
pytest
```

## Design notes

The instrumentor patches `sanic.Sanic.__init__` in place so each app registers
request/response middleware as it is constructed. (Patching in place rather
than swapping in a subclass preserves the class identity that Sanic's `TouchUp`
metaclass keys on.) Middleware signatures are stable across Sanic releases, so
the integration stays decoupled from Sanic internals. Responsibilities are
split across small, single-purpose modules: an anti-corruption layer over
Sanic's request/response objects (`_request`), pure per-signal attribute
assembly (`_span_attributes`, `_metric_attributes`), two symmetric signal
recorders (`_span`, `_metrics`), the thin lifecycle orchestrator that drives
both (`_middleware`), URL filtering (`_url_filter`), the exception hierarchy
(`exceptions`), and activation (`_instrumentor`, re-exported from `__init__`).
