# OpenTelemetry cho Python

> opentelemetry-instrument cho Flask, Django, FastAPI và requests; bật logging handler để log có trace; chạy với Gunicorn hoặc uWSGI.

Python không cần sửa code: `opentelemetry-instrument` khởi động SDK trước app, gắn instrumentation cho các thư viện tìm thấy (Flask, Django, FastAPI, requests, httpx, SQLAlchemy, psycopg, …) và đọc [bộ biến chuẩn](https://belvador.dev/vi/docs/otel/quickstart#2-dat-cac-bien-chuan).

> **Đã kiểm ngày 2026-10-25** với python 3.12.15, opentelemetry-distro 0.66b1, opentelemetry-sdk 1.45.1, flask 3.1.3: traces đạt, logs đạt, log mang trace/span của request.

## Cài đặt

```bash
pip install opentelemetry-distro opentelemetry-exporter-otlp-proto-http opentelemetry-instrumentation-logging
# instrumentation for the libraries you already use (Flask, Django, requests, …)
opentelemetry-bootstrap -a install
```

`opentelemetry-bootstrap -a install` xem các gói đã cài và thêm gói instrumentation tương ứng. Muốn xem trước, chạy `opentelemetry-bootstrap -a requirements` rồi chép các dòng cần vào file requirements, ghim phiên bản như các gói khác.

## Chạy

Đặt `opentelemetry-instrument` trước lệnh khởi động app:

```bash
export OTEL_PYTHON_LOGGING_AUTO_INSTRUMENTATION_ENABLED=true
export OTEL_SEMCONV_STABILITY_OPT_IN=http
opentelemetry-instrument python app.py
```

Máy chủ cũng vậy: `opentelemetry-instrument uvicorn main:app`, `opentelemetry-instrument flask run`, hoặc `opentelemetry-instrument python manage.py runserver --noreload` với Django (Django vẫn cần `DJANGO_SETTINGS_MODULE` như thường lệ).

## Logs

`OTEL_PYTHON_LOGGING_AUTO_INSTRUMENTATION_ENABLED=true` thêm một handler vào root logger, nên mọi bản ghi từ module `logging` chuẩn (và thư viện dựng trên nó, như `structlog` dùng backend stdlib) cũng được gửi thành bản ghi log OpenTelemetry mang trace ID và span ID đang chạy. Các handler sẵn có vẫn hoạt động. Bản ghi dưới mức của root logger không được gửi; đặt mức bạn muốn bằng `logging.basicConfig(level=logging.INFO)` hoặc cấu hình riêng.

## Các biến ở trên làm gì

`OTEL_SEMCONV_STABILITY_OPT_IN=http` cho span HTTP dùng tên thuộc tính ổn định (`url.path`, `http.request.method`, `http.response.status_code`) mà bộ lọc của Belvador dùng.

## Máy chủ fork tiến trình (Gunicorn, uWSGI)

Worker được fork từ tiến trình cha đã khởi động OpenTelemetry sẽ mất luồng nền của exporter, nên không gửi gì. Với Gunicorn, đừng dùng `--preload` cùng `opentelemetry-instrument`, hoặc tự khởi động SDK trong hook `post_fork`; uWSGI cần `lazy-apps = true`. Lần chạy của Belvador dùng một tiến trình Flask, nên cách chạy có fork không nằm trong phần đã kiểm.

## Tắt bớt instrumentation

```bash
export OTEL_PYTHON_DISABLED_INSTRUMENTATIONS=urllib3,sqlite3
```

## Cùng SDK Python của Sentry

Giữ `sentry-sdk` cho lỗi và để tracing tắt (không đặt `traces_sample_rate`), để OpenTelemetry là [bên duy nhất làm chủ tracing](https://belvador.dev/vi/docs/otel/overview#chi-mot-ben-lam-chu-tracing), và thêm `OTLPIntegration` để lỗi mang span đang chạy — cách cài ở [Cùng SDK Sentry](https://belvador.dev/vi/docs/otel/sentry-coexistence#python-sentry-sdk). Belvador chưa chạy app Python có cả hai, nên liên kết đó chưa được ghi là đã kiểm.
