OpenTelemetry¶
Spans OpenTelemetry del lado del SDK sobre las operaciones que ya haces
(create, commands.run, run_code, files.*, kill…), exportados al
backend que tú configures. Desde 0.5.0
Coste y activación
- Por defecto: apagado. Sin
tracer_provider=(TypeScript:tracerProvider) el SDK no importaopentelemetry/@opentelemetry/apiy no crea ningún span. - Activa: spans
rayito.*(SpanKind.CLIENT) encreate/connect/kill/pause/resume(instancia y clase),commands.run,run_code/runCodeyfiles.*, sobre elTracerProviderque pases. - Recursos y llamadas AWS: ninguno. Rayito no crea ni llama ningún servicio de AWS por esto.
- Coste aproximado: $0 desde Rayito. El coste, si lo hay, es el de tu exportador (CloudWatch, un collector propio…), que configuras tú.
- IAM: ninguno propio; el que exija tu exportador.
- Cómo apagarla: no pases
tracer_provider=/tracerProvider(o pasaNone/undefined).
Cuándo usarlo¶
- Ya tienes OpenTelemetry en tu servicio y quieres ver cuánto tardan las llamadas a los sandboxes dentro de tus trazas.
- Quieres medir el arranque, las celdas y las transferencias por operación.
- Cuándo no: para métricas del interior del sandbox (CPU, memoria), usa
get_metrics_history().
Instalación¶
El extra otel sólo trae opentelemetry-api. Los ejemplos usan el SDK
de OpenTelemetry (TracerProvider, ConsoleSpanExporter), que va
aparte; si ya tienes un proveedor configurado en tu servicio, el extra
basta.
Ejemplo rápido¶
from opentelemetry.sdk.trace import TracerProvider
from opentelemetry.sdk.trace.export import ConsoleSpanExporter, SimpleSpanProcessor
from rayito import Sandbox
provider = TracerProvider()
provider.add_span_processor(SimpleSpanProcessor(ConsoleSpanExporter()))
with Sandbox.create(tracer_provider=provider) as sbx: # span "rayito.sandbox.create"
sbx.commands.run("echo hola") # span "rayito.commands.run"
sbx.run_code("1 + 1") # span "rayito.code.run"
# al salir: span "rayito.sandbox.kill"
import asyncio
from opentelemetry.sdk.trace import TracerProvider
from opentelemetry.sdk.trace.export import ConsoleSpanExporter, SimpleSpanProcessor
from rayito import AsyncSandbox
async def main() -> None:
provider = TracerProvider()
provider.add_span_processor(SimpleSpanProcessor(ConsoleSpanExporter()))
async with await AsyncSandbox.create(tracer_provider=provider) as sbx:
await sbx.commands.run("echo hola")
await sbx.run_code("1 + 1")
asyncio.run(main())
import { BasicTracerProvider, ConsoleSpanExporter, SimpleSpanProcessor } from "@opentelemetry/sdk-trace-base";
import { Sandbox } from "rayito";
const provider = new BasicTracerProvider({
spanProcessors: [new SimpleSpanProcessor(new ConsoleSpanExporter())],
});
await using sbx = await Sandbox.create({ tracerProvider: provider });
await sbx.commands.run("echo hola"); // span "rayito.commands.run"
await sbx.runCode("1 + 1"); // span "rayito.code.run"
Para enviar los spans a tu backend, cambia ConsoleSpanExporter por el
exportador OTLP de tu SDK de OpenTelemetry. Si ya tienes un proveedor
global, pásalo: tracer_provider=trace.get_tracer_provider().
Nombres de span¶
| Span | Dónde |
|---|---|
rayito.sandbox.create |
create() (envuelve run-microvm, la espera del agente, el índice y la red) |
rayito.sandbox.connect |
connect(), las dos formas |
rayito.sandbox.kill, pause, resume |
instancia y clase / estático |
rayito.code.run |
run_code() / runCode() |
rayito.commands.run |
commands.run() (en segundo plano, el span se cierra cuando arranca el proceso, no cuando termina) |
rayito.files.read, write, write_files, list, exists, get_info, remove, rename, make_dir |
files.* |
rayito.agent.run |
sbx.agent.run() / .stream() (Agente en el sandbox) |
Atributos¶
Lista cerrada de claves (cualquier otra es un error antes de abrir el span):
| Span | Atributos |
|---|---|
rayito.sandbox.create |
rayito.region, rayito.operation y rayito.sandbox.id en cuanto run-microvm responde |
rayito.sandbox.connect, kill, pause, resume |
rayito.sandbox.id, rayito.operation |
rayito.commands.run |
rayito.commands.background; en primer plano, rayito.commands.exit_code |
rayito.code.run |
rayito.code.language cuando se conoce |
rayito.files.* |
rayito.files.operation; read/write añaden rayito.files.bytes; write_files y list añaden rayito.files.count |
rayito.agent.run |
al empezar, gen_ai.operation.name (invoke_agent), gen_ai.provider.name, gen_ai.request.model, gen_ai.agent.name y rayito.agent.runtime; al terminar, gen_ai.conversation.id, gen_ai.usage.input_tokens, gen_ai.usage.output_tokens, rayito.agent.steps, rayito.agent.exit_code, rayito.agent.cache_read_tokens, rayito.agent.cache_write_tokens y, si falla, rayito.agent.failure_reason |
rayito.template.name, rayito.resume_generation y rayito.error.type
están reservadas: hoy ningún span las emite.
Lo que nunca se registra
El texto de un comando, código fuente, rutas de ficheros, valores de
envs, nombres o valores de secretos, valores de metadata, el access
token, el token del proxy ni URLs prefirmadas. En rayito.agent.run,
tampoco el prompt, el texto de la respuesta ni los argumentos de una
herramienta: sólo modelo, proveedor y contadores. Un error dentro de un span
registra sólo el nombre de la clase de la excepción, nunca su mensaje
ni su traza.
Qué no incluye¶
- Con
tracer_provider=, cada llamada del handle lleva ademástraceparent(ytracestate, nuncabaggage) haciarayd, que lo escribe comotrace_id/span_iden sus logs.raydno crea spans: un span de Rayito nunca es padre de nada dentro del MicroVM. Las llamadas de clase (Sandbox.kill(id)y compañía) no lo llevan. Sin la opción, no se añade ninguna cabecera. - Las métricas del interior del sandbox (CPU, memoria, disco) no viajan
por aquí: son la exportación OTLP (
telemetry=), otra opción con su propio coste. - El shim de E2B (
rayito.e2b/rayito/e2b) no está instrumentado.
Errores y solución de problemas¶
| Síntoma | Causa | Qué hacer |
|---|---|---|
ModuleNotFoundError: opentelemetry al pasar tracer_provider= |
falta el extra | pip install "rayito[otel]" |
ModuleNotFoundError: No module named 'opentelemetry.sdk' |
el extra otel sólo instala la API, no el SDK |
pip install opentelemetry-sdk |
Cannot find module '@opentelemetry/sdk-trace-base' (TypeScript) |
falta el SDK de trazas | npm i @opentelemetry/sdk-trace-base |
| no aparece ningún span | el provider no tiene un procesador o no se vacía al salir | añade un SpanProcessor y llama a provider.shutdown() al terminar |
| spans del shim de E2B | el shim no está instrumentado | usa el SDK nativo (sbx.native en el shim) |
Diferencias con E2B¶
Estos spans son del lado del cliente, sobre tus llamadas; E2B no tiene un equivalente en su SDK. Su exportación de telemetría del sandbox (Enterprise) se parece más a la exportación OTLP de Rayito.
Ver también¶
Fuentes y mediciones
- Implementación:
clients/python/src/rayito/_otel.pyyclients/typescript/src/otel.ts. - Probado con
InMemorySpanExporteren los dos SDK: al no llamar a AWS, no necesita una aceptación contra AWS real.