Metadata-Version: 2.4
Name: fastx-opentelemetry
Version: 0.1.0
Summary: Code-based OpenTelemetry auto-instrumentation for Python
Author-email: jimo <jimo@foxmail.com>
License: Apache-2.0
Keywords: auto-instrumentation,observability,opentelemetry,tracing
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: Apache Software License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.7
Classifier: Programming Language :: Python :: 3.8
Classifier: Programming Language :: Python :: 3.9
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.7
Requires-Dist: importlib-metadata>=1.0; python_version < '3.8'
Requires-Dist: opentelemetry-api>=1.22
Requires-Dist: opentelemetry-instrumentation>=0.43
Requires-Dist: opentelemetry-sdk>=1.22
Provides-Extra: all
Requires-Dist: opentelemetry-exporter-otlp-proto-grpc>=1.22; extra == 'all'
Requires-Dist: opentelemetry-exporter-otlp-proto-http>=1.22; extra == 'all'
Provides-Extra: otlp-grpc
Requires-Dist: opentelemetry-exporter-otlp-proto-grpc>=1.22; extra == 'otlp-grpc'
Provides-Extra: otlp-http
Requires-Dist: opentelemetry-exporter-otlp-proto-http>=1.22; extra == 'otlp-http'
Description-Content-Type: text/markdown

# fastx-opentelemetry

基于代码的 OpenTelemetry 自动增强 SDK 封装。一行代码完成 OpenTelemetry 初始化，自动发现并加载所有已安装的 instrumentation 库。

## 特性

- **一行初始化** — `fastx_opentelemetry.init(service_name="my-app")` 完成全部配置
- **自动发现增强** — 自动检测并加载所有已安装的 `opentelemetry-instrumentation-*` 包
- **智能建议** — 检测已安装但未增强的库，提示安装对应 instrumentation 包
- **上下游服务串联** — 自动传播 Baggage 中的服务调用链（`parent.service.name` / `parent.service.names` / `current.service.name`）
- **Baggage → Span 属性** — 自动将 Baggage 条目复制为 Span 属性，无需手动操作
- **内置采样器** — 提供 `RulesBasedSampler`（按规则采样）和 `RateLimitingSampler`（限流采样）
- **自动资源检测** — 自动采集 hostname、IP、PID、instance ID 以及云平台属性（`cloud.platform`、`cloud.region` 等）
- **环境变量兼容** — 完全兼容 OpenTelemetry 标准环境变量
- **信号级端点** — 自动为 traces/metrics/logs 拼接 `/v1/traces`、`/v1/metrics`、`/v1/logs` 路径

## 安装

```bash
# 基础安装
pip install fastx-opentelemetry

# 带 OTLP gRPC 导出器
pip install fastx-opentelemetry[otlp-grpc]

# 带 OTLP HTTP 导出器
pip install fastx-opentelemetry[otlp-http]

# 全部安装
pip install fastx-opentelemetry[all]
```

## 快速开始

### 最简用法

```python
import fastx_opentelemetry

fastx_opentelemetry.init()
```

配合环境变量：

```bash
export OTEL_EXPORTER_OTLP_ENDPOINT=http://collector:4318
export OTEL_SERVICE_NAME=my-app
python my_app.py
```

### Flask 应用

```python
import fastx_opentelemetry

# 必须在创建 Flask app 之前初始化
fastx_opentelemetry.init(service_name="my-flask-app")

from flask import Flask
app = Flask(__name__)

@app.route("/hello")
def hello():
    return {"message": "Hello, World!"}
```

### Django 应用

在 `settings.py` 中添加：

```python
import fastx_opentelemetry
fastx_opentelemetry.init(service_name="my-django-app")
```

### FastAPI 应用

```python
import fastx_opentelemetry

fastx_opentelemetry.init(service_name="my-fastapi-app")

from fastapi import FastAPI
app = FastAPI()

@app.get("/hello")
async def hello():
    return {"message": "Hello, World!"}
```

## 高级用法

### 自定义采样器

```python
import fastx_opentelemetry
from fastx_opentelemetry import RulesBasedSampler, SamplingRule, RateLimitingSampler
from opentelemetry.sdk.trace.sampling import ALWAYS_ON, ALWAYS_OFF, TraceIdRatioBased

sampler = RulesBasedSampler(
    rules=[
        SamplingRule(match_name="/health.*", sampler=ALWAYS_ON),
        SamplingRule(match_name="/static/.*", sampler=ALWAYS_OFF),
        SamplingRule(match_name="/api/.*", sampler=TraceIdRatioBased(0.1)),
    ],
    default_sampler=RateLimitingSampler(max_spans_per_second=50),
)

fastx_opentelemetry.init(
    service_name="my-app",
    sampler=sampler,
)
```

### 完整配置

```python
import fastx_opentelemetry
from opentelemetry.sdk.trace.export import ConsoleSpanExporter, SimpleSpanProcessor

console_processor = SimpleSpanProcessor(ConsoleSpanExporter())

loaded = fastx_opentelemetry.init(
    service_name="my-app",
    endpoint="http://collector:4317",  # 自动拼接 /v1/traces, /v1/metrics, /v1/logs
    protocol="grpc",
    compression="gzip",
    headers={"Authorization": "Bearer token123"},
    extra_resource_attributes={
        "deployment.environment": "production",
        "service.version": "1.2.3",
    },
    span_processors=[console_processor],
    disabled_instrumentations=["sqlite3"],
)

print(f"Loaded instrumentors: {loaded}")
```

### 禁用特定增强

```python
fastx_opentelemetry.init(
    service_name="my-app",
    disabled_instrumentations=["sqlite3", "urllib"],
)
```

或通过环境变量：

```bash
export OTEL_PYTHON_DISABLED_INSTRUMENTATIONS=sqlite3,urllib
```

禁用所有增强（仅初始化 SDK，不加载任何 instrumentor）：

```python
fastx_opentelemetry.init(
    service_name="my-app",
    disabled_instrumentations=["*"],
)
```

### 上下游服务串联

`FastxBaggagePropagator` 和 `FastxSpanProcessor` 在 `init()` 时自动启用，无需额外配置。它们实现了与 Go 端 `fastx_otel.go` 一致的 Baggage 传播逻辑：

- **`FastxBaggagePropagator`** — 包装 W3C Baggage 传播器，提取时自动转换服务链：
  - 将 `current.service.name` 移入 `parent.service.name`
  - 将 `current.service.name` 追加到 `parent.service.names`（以 `++` 分隔，去重）
  - 将 `current.service.name` 设置为本地服务名
- **`FastxSpanProcessor`** — 在 Span 开始时，自动将所有 Baggage 条目复制为 Span 属性

这意味着在微服务调用链中，每个服务的 Span 都会携带完整的上游服务链信息，便于在后端（如 Jaeger、Grafana）中追踪调用路径。

## 环境变量

| 变量 | 说明 | 默认值 |
|------|------|--------|
| `FASTX_PYTHON_INSTRUMENTATION_ENABLED` | 全局开关，`false` 时跳过全部初始化 | `true` |
| `OTEL_SERVICE_NAME` | 服务名称 | `unknown_service` |
| `OTEL_EXPORTER_OTLP_ENDPOINT` | OTLP Collector 地址（自动拼接信号路径） | — |
| `OTEL_EXPORTER_OTLP_PROTOCOL` | 传输协议 `http/protobuf` 或 `grpc` | `http/protobuf` |
| `OTEL_EXPORTER_OTLP_COMPRESSION` | 压缩方式 `gzip`/`deflate`/`none` | `gzip` |
| `OTEL_EXPORTER_OTLP_TRACES_HEADERS` | 导出器请求头 | — |
| `OTEL_TRACES_SAMPLER` | 采样器名称 | `parentbased_always_on` |
| `OTEL_PYTHON_DISABLED_INSTRUMENTATIONS` | 禁用的增强列表（逗号分隔，`*` 禁用全部） | — |
| `OTEL_PYTHON_LOGGING_AUTO_INSTRUMENTATION_ENABLED` | 是否启用日志自动增强 | `true` |
| `IP_ADDR` | 自动检测为 `host.ip` 资源属性 | 本地非回环 IP |
| `CLOUD_TYPE` | 自动检测为 `cloud.platform` 资源属性 | — |
| `REGION_CODE` | 自动检测为 `cloud.region` 资源属性 | — |
| `AZ_CODE` | 自动检测为 `cloud.availability` 资源属性 | — |
| `env_cd` | 自动检测为 `deployment.environment.name` 资源属性 | — |

## 安装增强库

`fastx-opentelemetry` 会自动检测已安装的库并加载对应的 instrumentation。你需要手动安装需要的 instrumentation 包：

```bash
# Web 框架
pip install opentelemetry-instrumentation-flask
pip install opentelemetry-instrumentation-django
pip install opentelemetry-instrumentation-fastapi

# HTTP 客户端
pip install opentelemetry-instrumentation-requests
pip install opentelemetry-instrumentation-httpx
pip install opentelemetry-instrumentation-urllib

# 数据库
pip install opentelemetry-instrumentation-sqlalchemy
pip install opentelemetry-instrumentation-psycopg2
pip install opentelemetry-instrumentation-redis
pip install opentelemetry-instrumentation-pymongo

# 消息队列
pip install opentelemetry-instrumentation-celery
pip install opentelemetry-instrumentation-kafka-python
```

检查已安装的增强库：

```bash
pip list | grep opentelemetry-instrumentation
```

## API 参考

### `fastx_opentelemetry.init(**kwargs)`

初始化 OpenTelemetry SDK 并加载所有已安装的 instrumentor。

**参数：**

| 参数 | 类型 | 说明 |
|------|------|------|
| `service_name` | `str \| None` | 服务名称，回退到 `OTEL_SERVICE_NAME` |
| `endpoint` | `str \| None` | OTLP Collector 地址（自动拼接信号路径） |
| `protocol` | `str \| None` | `http/protobuf` 或 `grpc` |
| `compression` | `str \| None` | `gzip`、`deflate` 或 `none` |
| `headers` | `dict \| None` | OTLP 导出器请求头 |
| `extra_resource_attributes` | `dict \| None` | 额外的资源属性 |
| `span_processors` | `list \| None` | 自定义 SpanProcessor 列表 |
| `sampler` | `Sampler \| None` | 自定义采样器实例 |
| `disabled_instrumentations` | `list \| None` | 禁用的 instrumentor 名称列表，`"*"` 禁用全部 |

**返回值：** `list[str]` — 成功加载的 instrumentor 名称列表。

### `fastx_opentelemetry.list_available_instrumentors()`

返回所有已安装的 instrumentor 名称列表。

### `fastx_opentelemetry.suggest_missing_instrumentations(loaded)`

检查已安装但未增强的库，返回建议安装的 instrumentation 包名列表。

### 采样器

#### `RulesBasedSampler(rules, default_sampler=None)`

按规则匹配 span 名称或属性，委托给不同的采样器。

#### `SamplingRule(sampler, match_name=None, match_attributes=None)`

单条采样规则。`match_name` 为正则表达式匹配 span 名称，`match_attributes` 为属性键值对匹配。

#### `RateLimitingSampler(max_spans_per_second)`

基于令牌桶算法的限流采样器，限制每秒采样的 span 数量。

### Baggage 传播与 Span 处理

#### `FastxBaggagePropagator`

包装 W3C Baggage 传播器，在 `extract` 时自动转换服务调用链。`init()` 时自动设置为全局传播器。

#### `FastxSpanProcessor`

在 Span `on_start` 时将所有 Baggage 条目复制为 Span 属性。`init()` 时自动添加到 TracerProvider。

## 本地开发

```bash
# 安装依赖
pip install -e ".[all]"

# 运行示例
export OTEL_LOG_LEVEL=debug
export OTEL_EXPORTER_OTLP_ENDPOINT=http://127.0.0.1:4318
export OTEL_SERVICE_NAME=my-app

python examples/app.py
```

## License

Apache-2.0
