Skip to content

Commit 9b668a4

Browse files
feat(api): pre-wire otel genai instrumentation
Add OpenTelemetry GenAI semantic-convention instrumentation (semconv 2026-Q2, Development status) to the API template: - src/lib/ai/telemetry.py: guarded auto-instrumentation for the official OpenAI/Google GenAI SDKs plus a manual genai_span() helper emitting spec-compliant spans and gen_ai.client.* metrics for custom providers - src/lib/telemetry.py: add Meter and Logger providers (was traces-only), set GenAI semconv stability/content env defaults, move resource to deployment.environment.name - config + .env.example: OTEL_GENAI_CAPTURE_MESSAGE_CONTENT (PII-safe off) - pyproject: optional, mutually-exclusive genai-openai/genai-google extras Co-Authored-By: First Fluke <our.first.fluke@gmail.com>
1 parent db4d281 commit 9b668a4

8 files changed

Lines changed: 858 additions & 22 deletions

File tree

apps/api/.env.example

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,16 @@ JWE_SECRET_KEY=your-super-secret-jwe-encryption-key-change-in-production
1919
# Redis (optional)
2020
REDIS_URL=redis://localhost:6379
2121

22-
# OpenTelemetry (optional - for production tracing)
22+
# OpenTelemetry (optional - for production tracing & metrics)
2323
# OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:4317
2424
# OTEL_SERVICE_NAME=fullstack-starter-api
2525

26+
# OpenTelemetry GenAI (LLM observability - OTel GenAI semconv).
27+
# Prompt/completion content is PII-sensitive: "off" records only metadata
28+
# (model, token usage, latency). Set to span_only/event_only/span_and_event to
29+
# capture message content. Auto-enables OTEL_SEMCONV_STABILITY_OPT_IN.
30+
# OTEL_GENAI_CAPTURE_MESSAGE_CONTENT=off
31+
2632
# AI (optional)
2733
AI_PROVIDER=gemini
2834
GOOGLE_CLOUD_PROJECT=

apps/api/pyproject.toml

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,15 @@ dependencies = [
2727
"bcrypt>=5.0.0",
2828
]
2929

30+
# Optional GenAI SDK auto-instrumentation (OTel GenAI semconv).
31+
# Install the one matching AI_PROVIDER, e.g. `uv sync --extra genai-openai`.
32+
# NOTE: as of 2026-Q2 these two cannot be installed together — openai-v2 pins
33+
# opentelemetry-util-genai>=0.4b0 while google-genai pins <0.4b0. The runtime
34+
# (src/lib/ai/telemetry.py) import-guards both, so absence is a safe no-op.
35+
[project.optional-dependencies]
36+
genai-openai = ["opentelemetry-instrumentation-openai-v2>=2.4b0"]
37+
genai-google = ["opentelemetry-instrumentation-google-genai>=0.7b1"]
38+
3039
[dependency-groups]
3140
dev = [
3241
"ruff>=0.15.16",
@@ -41,6 +50,9 @@ dev = [
4150

4251
[tool.uv]
4352
managed = true
53+
# openai-v2 and google-genai pin incompatible opentelemetry-util-genai ranges
54+
# (2026-Q2); declare them mutually exclusive so each resolves independently.
55+
conflicts = [[{ extra = "genai-openai" }, { extra = "genai-google" }]]
4456

4557
[tool.poe.tasks]
4658
dev = "fastapi dev src/main.py --port 8000"
@@ -88,3 +100,11 @@ ignore_missing_imports = true
88100
[[tool.mypy.overrides]]
89101
module = ["jwcrypto.*"]
90102
ignore_missing_imports = true
103+
104+
# Optional GenAI auto-instrumentation packages (installed via extras only).
105+
[[tool.mypy.overrides]]
106+
module = [
107+
"opentelemetry.instrumentation.openai_v2.*",
108+
"opentelemetry.instrumentation.google_genai.*",
109+
]
110+
ignore_missing_imports = true

apps/api/src/lib/ai/__init__.py

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
"""AI provider abstraction and OTel GenAI instrumentation helpers."""
2+
3+
from src.lib.ai.base import AIProvider
4+
from src.lib.ai.telemetry import (
5+
GenAIAttr,
6+
GenAIOperation,
7+
GenAIProvider,
8+
GenAISpanHandle,
9+
genai_span,
10+
init_genai_metrics,
11+
instrument_genai_sdks,
12+
provider_name,
13+
)
14+
15+
__all__ = [
16+
"AIProvider",
17+
"GenAIAttr",
18+
"GenAIOperation",
19+
"GenAIProvider",
20+
"GenAISpanHandle",
21+
"genai_span",
22+
"init_genai_metrics",
23+
"instrument_genai_sdks",
24+
"provider_name",
25+
]

0 commit comments

Comments
 (0)