Metadata-Version: 2.4
Name: elven-unified-observability-py
Version: 0.1.7
Summary: Unified wrapper for Elven logs interception and OpenTelemetry instrumentation in Python.
Project-URL: Homepage, https://github.com/elven/elven-unified-observability-py
Project-URL: Repository, https://github.com/elven/elven-unified-observability-py
Author: Leonardo Zwirtes
License-Expression: MIT
Keywords: logs,observability,opentelemetry,python,telemetry
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3 :: Only
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: Topic :: Software Development :: Libraries
Classifier: Topic :: System :: Monitoring
Requires-Python: >=3.10
Requires-Dist: elven-logs-interceptor-python<0.2.0,>=0.1.6
Requires-Dist: elven-opentelemetry-instrumentation-py<0.2.0,>=0.1.2
Requires-Dist: python-dotenv<2.0.0,>=1.0.0
Provides-Extra: dev
Requires-Dist: build>=1.2.2; extra == 'dev'
Requires-Dist: pyright>=1.1.408; extra == 'dev'
Requires-Dist: pytest-asyncio>=0.23.0; extra == 'dev'
Requires-Dist: pytest-cov>=5.0.0; extra == 'dev'
Requires-Dist: pytest>=8.3.0; extra == 'dev'
Requires-Dist: ruff>=0.6.0; extra == 'dev'
Requires-Dist: twine>=5.1.1; extra == 'dev'
Provides-Extra: full
Requires-Dist: elven-logs-interceptor-python[all]<0.2.0,>=0.1.6; extra == 'full'
Description-Content-Type: text/markdown

# Unified Observability Py

Pacote unificado para juntar:

- `elven-logs-interceptor-python`
- `elven-opentelemetry-instrumentation-py`

com uma experiência única de bootstrap, config por env e API manual em Python.

## Instalação

Base:

```bash
pip install elven-unified-observability-py
```

Com extras completos do logger:

```bash
pip install "elven-unified-observability-py[full]"
```

Para desenvolvimento:

```bash
pip install -e ".[dev]"
```

## O que a lib entrega

- `init(...)` manual com config Python-first
- `init_from_env()` para bootstrap por ambiente
- `logger`, `tracer` e `metrics` reexportados como proxies seguros
- preload zero-code via `sitecustomize`
- CLI `elven-unified-observability -- <command>`
- shutdown e flush coordenados
- auto-bridge para libs de logging suportadas (`loguru`, `structlog`)
- fallback `LOKI_*` para `LOGS_*`
- aliases legados `ENABLE_LOGGING`, `ENABLE_METRICS`, `ENABLE_TRACING`

## Quick Start Manual

```python
from elven_unified_observability import init, logger, metrics, tracer

handle = init(
    {
        "service": {
            "serviceName": "billing-service",
            "serviceVersion": "1.2.3",
            "environment": "production",
        },
        "logging": {
            "transport": {
                "url": "https://loki.example.com/loki/api/v1/push",
                "tenantId": "tenant-a",
                "authToken": "token",
                "compression": "gzip",
            },
            "interceptConsole": True,
        },
        "telemetry": {
            "metrics": {"exportIntervalMillis": 15000},
            "privacy": {"redactDbStatement": True},
        },
        "enableLogging": True,
        "enableMetrics": True,
        "enableTracing": True,
    }
)

logger.info("service started", {"service": "billing-service"})
metrics.increment("bootstrap.success", 1)
tracer.with_span("startup", lambda span: span.set_attribute("boot.ready", True))

handle.force_flush()
handle.shutdown()
```

O `logger` também aceita padrões comuns do `logging` nativo durante migração:

```python
logger.info("payload criado", {"request_id": "req-1"})
logger.info("payload criado: %s", payload)
logger.info("payload criado: %(id)s", {"id": payload_id})
logger.info("payload criado: {}", payload_id)
logger.info("payload criado: %s", payload_id, extra={"request_id": "req-1"})
logger.exception("falha ao criar payload: %s", payload_id)
```

Aliases suportados: `warning(...)`, `exception(...)` e `critical(...)`.

## Quick Start Zero-Code

1. Crie um `.env` com a identidade do serviço e os endpoints.
2. Rode a app com a CLI:

```bash
elven-unified-observability -- python app.py
```

Também funciona com:

```bash
elven-unified-observability -- uvicorn app:app
elven-unified-observability -- celery -A worker.app worker
elven-unified-observability -- python -m my_service
```

## Como a precedence funciona

1. Config explícita passada para `init(...)`
2. Env da wrapper (`UO_*`)
3. Env dos componentes (`LOGS_*`, `LOKI_*`, `OTEL_*`)
4. Defaults das libs-base

## Variáveis da wrapper

| Variável | Descrição |
| --- | --- |
| `UO_ENABLED` | Liga/desliga tudo por default |
| `UO_ENABLE_LOGGING` | Override unificado para logs |
| `UO_ENABLE_METRICS` | Override unificado para métricas |
| `UO_ENABLE_TRACING` | Override unificado para tracing |
| `UO_STRICT` | Falha o bootstrap se qualquer componente falhar |
| `UO_LOAD_DOTENV` | Controla leitura de `.env` no preload/CLI |
| `UO_DOTENV_PATH` | Caminho alternativo para o `.env` |
| `UO_LOGGING_INTEGRATIONS` | Auto-instala bridges de logging: `auto`, `loguru`, `structlog`, `none` |
| `UO_LOGGING_EXCLUDE_PREFIXES` | Prefixos globais de bibliotecas barulhentas para ignorar nos bridges |
| `UO_ENABLE_LOGURU_BRIDGE` | Override específico para bridge de `loguru` |
| `UO_ENABLE_STRUCTLOG_BRIDGE` | Override específico para bridge de `structlog` |
| `UO_LOGURU_LEVEL` | Nível do sink `loguru` instalado pela wrapper |
| `UO_LOGURU_ENQUEUE` | Ativa `enqueue` no sink `loguru` |
| `UO_LOGURU_BACKTRACE` | Ativa `backtrace` no sink `loguru` |
| `UO_LOGURU_DIAGNOSE` | Ativa `diagnose` no sink `loguru` |
| `UO_LOGURU_EXCLUDE_PREFIXES` | Prefixos extras para ignorar especificamente no bridge de `loguru` |

Aliases legados suportados:

- `ENABLE_LOGGING`
- `ENABLE_METRICS`
- `ENABLE_TRACING`

## Identidade unificada

A identidade do serviço é sempre derivada nesta ordem:

1. `OTEL_SERVICE_NAME`
2. `LOGS_APP_NAME` ou `LOKI_APP_NAME`
3. default `unknown-service`

Versão:

1. `OTEL_SERVICE_VERSION`
2. `LOGS_APP_VERSION` ou `LOKI_APP_VERSION`
3. default `1.0.0`

Ambiente:

1. `OTEL_DEPLOYMENT_ENVIRONMENT`
2. `LOGS_ENVIRONMENT` ou `LOKI_ENVIRONMENT`
3. `ENVIRONMENT`
4. `APP_ENV`
5. default `development`

## Logging

Prefixo principal: `LOGS_*`

Fallback suportado: `LOKI_*`

Exemplos mais usados:

```bash
LOGS_URL=https://loki.example.com/loki/api/v1/push
LOGS_TENANT=my-tenant
LOGS_TOKEN=secret
LOGS_COMPRESSION=gzip
LOGS_BUFFER_MAX_SIZE=500
LOGS_FILTER_LEVELS=info,warn,error
LOGS_INTERCEPT_CONSOLE=true
LOGS_ENABLE_METRICS=true
```

`LOGS_ENABLE_METRICS` controla apenas as métricas internas do logger. Se ele não estiver definido, o pacote usa o valor unificado de `UO_ENABLE_METRICS`.

## Logging Bridges

Quando a aplicação usa bibliotecas de logging além do `logging` padrão do Python, a wrapper pode instalar bridges automaticamente no bootstrap.

Hoje os bridges suportados são:

- `loguru`
- `structlog`

No caso de `loguru`, a wrapper também reaplica o bridge automaticamente quando a aplicação chama `logger.configure(...)` ou `logger.remove()`, evitando perder o sink da observabilidade durante o bootstrap da app.

Habilitar autodetecção para todas as bibliotecas suportadas:

```bash
UO_LOGGING_INTEGRATIONS=auto
```

Filtros padrão já silenciam bibliotecas barulhentas como `httpx`, `httpcore`, `urllib3`, `h11`, `h2`, `hpack` e `opentelemetry`.

Habilitar apenas `loguru`:

```bash
UO_LOGGING_INTEGRATIONS=loguru
```

Forçar override granular:

```bash
UO_ENABLE_LOGURU_BRIDGE=true
UO_ENABLE_STRUCTLOG_BRIDGE=false
```

Refinar exclusões globais:

```bash
UO_LOGGING_EXCLUDE_PREFIXES=httpx,httpcore,urllib3,h11,h2,hpack,opentelemetry
```

Adicionar exclusões extras só para `loguru`:

```bash
UO_LOGURU_EXCLUDE_PREFIXES=botocore,boto3
```

Para apps `loguru-first`, a recomendação é manter o bridge ligado e usar `LOGS_INTERCEPT_CONSOLE=false` quando você não quiser capturar `print()` da aplicação.

## Telemetry

A wrapper reaproveita os `OTEL_*` já suportados pela lib-base.

Mais comuns:

```bash
OTEL_SERVICE_NAME=billing-service
OTEL_SERVICE_VERSION=1.2.3
OTEL_DEPLOYMENT_ENVIRONMENT=production
OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:4318
OTEL_EXPORTER_OTLP_PROTOCOL=http/protobuf
OTEL_TRACES_EXPORTER=otlp
OTEL_METRICS_EXPORTER=otlp
OTEL_METRIC_EXPORT_INTERVAL=15000
OTEL_PRIVACY_REDACT_DB_STATEMENT=true
OTEL_INSTR_FASTAPI=true
OTEL_INSTR_REQUESTS=true
```

## Framework examples

### FastAPI

```bash
elven-unified-observability -- uvicorn app:app --host 0.0.0.0 --port 8000
```

### Flask

```bash
elven-unified-observability -- flask --app app run
```

### Celery

```bash
elven-unified-observability -- celery -A worker.app worker -l info
```

## API pública

- `init(config=None)`
- `init_from_env(strict=None)`
- `load_config_from_env(env=None)`
- `get_handle()`
- `is_initialized()`
- `force_flush()`
- `shutdown()`
- `logger`
- `tracer`
- `metrics`

## Build e publish

Validação local:

```bash
ruff check .
pyright
pytest
python -m build
python -m twine check dist/*
```

Publish local:

```bash
./publish.sh --repository testpypi --dry-run
./publish.sh --repository testpypi
./publish.sh --repository pypi
```

Tokens esperados:

- `TEST_PYPI_API_TOKEN`
- `PYPI_API_TOKEN`

## Segurança

- Não versione `.env` real
- Não grave token em arquivo
- Use secrets de CI ou variáveis de ambiente locais
