App web muy simple que llama a ChatGPT (modelo gpt-4.1-nano) cada vez que presionas un botón,
y además sola cada 1 minuto. Está instrumentada con OpenLLMetry
y envía trazas, métricas y logs a Dynatrace a través de un OpenTelemetry Collector.
Todo corre en GitHub Codespaces.
Solo necesitas 3 valores, que se pasan como variables de entorno:
| Variable | Qué es | Dónde se usa |
|---|---|---|
OPENAI_API_KEY |
API key de OpenAI (sk-...) |
app |
DT_TENANT_URL |
URL de tu tenant Dynatrace | collector |
DT_API_TOKEN |
Platform token de Dynatrace (dt0s16...) |
collector |
- Entra a https://platform.openai.com/api-keys.
- Haz clic en Create new secret key, ponle un nombre (ej.
demo-openllmetry) y clic en Create secret key. - Copia la key (empieza con
sk-). Solo se muestra una vez. - Revisa que la cuenta tenga saldo en https://platform.openai.com/settings/organization/billing.
Sin saldo, OpenAI responde error
429.
👉 Este valor es tu OPENAI_API_KEY.
- Abre Dynatrace en el navegador.
- Copia la dirección hasta
.com, por ejemplohttps://abc12345.apps.dynatrace.com.
Puedes usarla tal cual: start.sh la convierte sola a la URL de la API (https://abc12345.live.dynatrace.com).
Si usas Dynatrace Managed, el formato es https://<tu-dominio>/e/<id-del-entorno>.
👉 Este valor es tu DT_TENANT_URL.
-
Entra a https://myaccount.dynatrace.com/platformTokens (Account Management → My platform tokens).
-
Crea un token nuevo y completa:
- Name:
demo-openllmetry - Expiration: la que quieras
- Environment: tu tenant (el del paso 2)
- Name:
-
En Scopes, agrega estos 3:
Scope Para qué openpipeline:traces:ingestTrazas openpipeline:metrics:ingestMétricas openpipeline:logs:ingestLogs -
Haz clic en Generate y copia el token (empieza con
dt0s16.). Solo se muestra una vez.
El token solo puede hacer lo que tu usuario tiene permitido. Si tu usuario no tiene permiso de ingesta en ese entorno, Dynatrace responderá
403: pide a un admin ese permiso o un token de un service user.¿Tienes un access token clásico (
dt0c01.)? También sirve, con los scopesopenTelemetryTrace.ingest,metrics.ingestylogs.ingest.start.shdetecta solo qué tipo de token es.
👉 Este valor es tu DT_API_TOKEN.
-
En GitHub abre este repo → Settings.
-
En el menú izquierdo: Secrets and variables → Codespaces.
-
Haz clic en New repository secret y crea estos 3 (uno a la vez):
Name Secret OPENAI_API_KEYla key del paso 1 DT_TENANT_URLla URL del paso 2 DT_API_TOKENel token del paso 3
Codespaces los entrega como variables de entorno cada vez que abres el codespace.
- En la página del repo: botón verde Code → pestaña Codespaces → Create codespace on main.
- Espera a que termine de prepararse (la primera vez tarda unos minutos).
Si el codespace ya existía antes de crear los secrets, reinícialo para que los vea.
En la terminal del codespace ejecuta:
./start.shEl script revisa las 3 variables, levanta la app y el collector, y al final te muestra la URL de la web.
- Abre la URL que mostró
start.sh(o en la pestaña PORTS, puerto 8000, clic en el globo). - Presiona Generar tráfico. Cada clic es una llamada a ChatGPT y la respuesta aparece debajo del botón.
Aunque no presiones nada, la app llama a ChatGPT sola cada minuto.
Espera 1 o 2 minutos y luego:
- App Distributed Tracing: busca el servicio
demo-python-openllmetry. Cada trazadato_curioso.workflowtiene un spanopenai.chatcon el modelo, los tokens, el prompt y la respuesta. - O en un Notebook, esta consulta DQL:
fetch spans, from: now()-30m
| filter service.name == "demo-python-openllmetry" and isNotNull(gen_ai.request.model)
| fields timestamp, span.name, gen_ai.request.model, gen_ai.usage.input_tokens, gen_ai.usage.output_tokens, duration
| sort timestamp desc
docker compose down| Problema | Qué hacer |
|---|---|
start.sh dice ERROR: falta la variable ... |
Revisa el paso 4 y reinicia el codespace |
El botón muestra error 401 |
La OPENAI_API_KEY está mal copiada |
El botón muestra error 429 |
La cuenta de OpenAI no tiene saldo |
docker compose logs otel-collector muestra 401 o 403 |
Token de Dynatrace incorrecto, le falta un scope o tu usuario no tiene permiso de ingesta (paso 3) |
docker compose logs otel-collector muestra 404 |
La URL del tenant está mal (paso 2) |

