Metadata-Version: 2.1
Name: telemify
Version: 0.5.1
Summary: Seamless instrumentation of tracing, logging, and metrics in FastAPI and Starlette applications, using opentelemetry structlog, and prometheus-client.
Home-page: https://github.com/portmind/telemify
Author: Portmind's ML Engineering Team
Maintainer: Sevak Harutyunyan
Maintainer-email: sevak.harutyunyan@portmind.com
Requires-Python: >=3.10,<4.0
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Requires-Dist: msgpack (>=1.0.8,<2.0.0)
Requires-Dist: opentelemetry-distro (>=0.46b0,<0.47)
Requires-Dist: opentelemetry-exporter-otlp (>=1.25.0,<2.0.0)
Requires-Dist: opentelemetry-instrumentation-botocore (>=0.46b0,<0.47)
Requires-Dist: opentelemetry-instrumentation-celery (>=0.46b0,<0.47)
Requires-Dist: opentelemetry-instrumentation-httpx (>=0.46b0,<0.47)
Requires-Dist: opentelemetry-instrumentation-jinja2 (>=0.46b0,<0.47)
Requires-Dist: opentelemetry-instrumentation-sqlalchemy (>=0.46b0,<0.47)
Requires-Dist: opentelemetry-instrumentation-starlette (>=0.46b0,<0.47)
Requires-Dist: opentelemetry-instrumentation-threading (>=0.46b0,<0.47)
Requires-Dist: prometheus-client (>=0.20.0,<0.21.0)
Requires-Dist: starlette (>=0.37.2,<0.38.0)
Requires-Dist: structlog (>=24.2.0,<25.0.0)
Requires-Dist: urllib3 (>=2.2.2,<3.0.0)
Project-URL: Repository, https://github.com/portmind/telemify
Description-Content-Type: text/markdown

# telemify

Seamless instrumentation of tracing, logging, and metrics in FastAPI and Starlette applications, using opentelemetry, structlog, and prometheus-client.

![Python](https://img.shields.io/badge/Python-3.10%20%7C%203.11-brightgreen)
[![Ruff](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/charliermarsh/ruff/main/assets/badge/v2.json)](https://github.com/charliermarsh/ruff)
[![pre-commit](https://img.shields.io/badge/pre--commit-enabled-brightgreen?logo=pre-commit&logoColor=white)](https://github.com/pre-commit/pre-commit)
[![Conventional Commits](https://img.shields.io/badge/Conventional%20Commits-1.0.0-%23FE5196?logo=conventionalcommits&logoColor=white)](https://conventionalcommits.org)


## Installation
```shell
$ pip install telemify
```

## Usage
```python
import uvicorn
from fastapi import FastAPI
from sqlalchemy.ext.asyncio import create_async_engine
from starlette.config import Config
from telemify.logging.configure import configure as configure_logger
from telemify.logging.filters import (
    ExceptionASGIApplicationFilter,
    MetricsEndpointFilter,
)
from telemify.logging.middleware import LoggerMiddleware
from telemify.logging.processors import add_open_telemetry_spans, drop_color_message_key
from telemify.metrics.configure import configure as configure_metrics
from telemify.metrics.middleware import PrometheusMiddleware
from telemify.tracing.configure import configure as configure_tracing

config = Config()
LOG_LEVEL: str = config("LOG_LEVEL", cast=str, default="info")

engine = create_async_engine("sqlite+aiosqlite:///test.db")


def configure_telemetry(app: FastAPI):
    configure_logger(
        json_logs=False,
        additional_processors=[drop_color_message_key, add_open_telemetry_spans],
        loggers_to_disable=["uvicorn.access"],
        loggers_to_propagate=["uvicorn", "uvicorn.error", "sqlalchemy.engine.Engine"],
        filters={
            "uvicorn.error": [
                ExceptionASGIApplicationFilter(),
            ],
            "telemify.logging.middleware": [MetricsEndpointFilter()],
        },
    )
    configure_metrics(app)
    configure_tracing(
        app,
        instrument_httpx=True,
        instrument_sqlalchemy=True,
        instrument_celery=True,
        instrument_botocore=True,
        instrument_jinja2=True,
        db_engine=engine,
    )


app = FastAPI()

app.add_middleware(LoggerMiddleware)
app.add_middleware(PrometheusMiddleware)
configure_telemetry(app)

if __name__ == "__main__":
    uvicorn.run(
        app,
        log_level=LOG_LEVEL,
    )
```

## Environment variables
```shell
# Application name to be used to mark signals
export APP_NAME=unknown

export LOG_LEVEL=info
export STATUS_4XX_LOG_LEVEL=warning

# Url to send the tracing data. It can be any tool that supports the OpenTelemetry protocol.
# ex. Grafana Tempo, Jaeger, etc.
export OTLP_GRPC_ENDPOINT=http://tempo-distributor.monitoring:4317

# Comma separated string to exclude certain urls from tracking.
# ex. "client/.*/info,healthcheck":
# This will exclude requests such as `https://site/client/123/info` and `https://site/xyz/healthcheck`.
export OTEL_PYTHON_EXCLUDED_URLS="client/.*/info,healthcheck"
```


## Tests

To run the tests, use the following command:

```shell
$ poetry run pytest
```


## Reference
1. [FastAPI with Observability](https://github.com/blueswen/fastapi-observability)
2. [django-structlog](https://github.com/jrobichaud/django-structlog)

