Las flow tables ya coinciden
Las flow tables tma1_token_usage_1m, cost_1m, latency_1m y status_1m de TMA1 derivan de span_attributes.gen_ai.*, que este plugin completa por convención. No hay nada más que configurar.
DSH OTel
Sin collector. Sin sidecar. Sin forkear DSH. Se instala como un plugin común de DeepSeek Harness, y cada turno, llamada al modelo y ejecución de herramienta pasa a ser una fila consultable en GreptimeDB.
INSTALACIÓN
dsh plugin --profile web add @tma1-ai/dsh-plugin-greptimedb
El paquete trae un bundle patch, así que ese comando es toda la instalación. Requiere pnpm 10 o superior. Los valores por defecto ya apuntan a un GreptimeDB local.
Los spans de chat y los de herramienta comparten trace y dsh.step, así que correlacionarlos es un join de SQL común. Los timestamps vienen de los propios eventos de sesión, no del momento en que el plugin los procesó.
Traces, métricas y logs. signals acepta cualquier subconjunto — una señal desactivada no construye exporter alguno.
El valor por defecto content: none exporta solo estructura y contabilidad. Sin prompts, sin mensajes, sin argumentos de herramientas, sin resultados.
Una configuración inválida falla cuando el plugin carga, nombrando el campo culpable — no en silencio durante la primera exportación.
Señales
Traces para la forma, métricas para retención larga y percentiles a prueba de sampleo, logs para los eventos de sesión crudos.
Los spans de turno son raíces. Los de chat y herramienta cuelgan de ellos como hermanos, correlacionados por dsh.step. Todo span de chat tiene un fin real, incluido el caso de caída.
Los conteos de DSH son disjuntos: inputTokens es solo entrada sin caché, y las lecturas y escrituras de caché son campos aparte. gen_ai.usage.input_tokens es el total facturado, así que el plugin los suma.
Overview, Cost, Sessions, Agent loop, Trace explorer, Log explorer y Metrics. Vienen en grafana/ junto a un stack de compose que levanta GreptimeDB y Grafana a la vez, y cada consulta de panel se verifica contra una base real en CI.

Cada tabla enlaza hacia adelante: un trace id abre el waterfall de ese turno, un session id salta entre la vista de traces y la de logs.

Sesión, tipo de evento, turno y step son columnas reales: filtrar una sesión no implica desarmar JSON.
Métricas
La misma actividad que los traces, vista con PromQL — para retención más larga y percentiles que sobreviven al sampleo.
| Instrumento | Tipo | Dimensiones |
|---|---|---|
gen_ai.client.token.usage | Histogram | gen_ai.token.type (solo input/output), model, provider |
gen_ai.client.operation.duration | Histogram | gen_ai.operation.name, model, provider |
gen_ai.invoke_agent.duration | Histogram | gen_ai.operation.name |
gen_ai.execute_tool.duration | Histogram | gen_ai.operation.name, gen_ai.tool.name |
dsh.token.detail | Histogram | dsh.token.detail_kind (cache_read/cache_write/reasoning) |
dsh.tool.invocations | Counter | gen_ai.tool.name, dsh.tool.outcome |
dsh.turns / dsh.steps | Counter | — |
Configuración
Un patch de profile reemplaza todo el config de esa fila en vez de fusionarse con él, así que reescribí cada campo que quieras conservar.
| Clave | Por defecto | Notas |
|---|---|---|
endpoint | requerido | URL base de OTLP. El sufijo /v1/{traces,metrics,logs} lo agrega el plugin. |
database | public | Se envía como X-Greptime-DB-Name. |
username / password | ninguno | Basic auth. Los dos o ninguno. |
signals | las tres | Cualquier subconjunto de traces, metrics, logs. |
content | none | Cuánto payload puede salir del proceso. |
ttl | 180d | Retención de las tablas que crea el plugin. También acepta forever. |
Batching, timeouts, nombre de servicio y overrides de tabla tienen valores razonables; la tabla completa está en el README.
Qué sale de la máquina
contentEl valor por defecto retiene todos los payloads. Subilo a propósito, por profile.
| Modo | Se exporta |
|---|---|
none (por defecto) | Estructura y contabilidad: tipos de evento, números de turno y step, conteos de tokens, nombres de herramientas, duraciones, resultados, name y code del error. |
full | Suma el contenido de los mensajes de usuario y asistente, argumentos de herramientas y resultados. |
full+prompt | Suma request/header: el system prompt completo y el schema de cada herramienta. |
En ningún modo salen el payload privado meta de una herramienta ni el mensaje y stack de una petición fallida. La proyección es una allowlist, así que un tipo de evento que el plugin no conoce exporta su identidad y nada más.
Con TMA1
TMA1 hace de proxy OTLP hacia un GreptimeDB que él mismo administra. Cambiás una línea y DSH aparece en su vista OTel GenAI.
Las flow tables tma1_token_usage_1m, cost_1m, latency_1m y status_1m de TMA1 derivan de span_attributes.gen_ai.*, que este plugin completa por convención. No hay nada más que configurar.
Limitaciones conocidas
La lista completa está en el README.
Renombra y reempaqueta libremente hasta su primer tag, así que el rango de peer queda fijado a la versión contra la que corre CI.
Los nombres de atributo vienen de @opentelemetry/semantic-conventions/incubating y se mueven con él.
ttl no llega a las tablas de métricasEn el metric engine la retención es propiedad de la tabla física, así que hay que definirla ahí (greptimedb#8951).
No hay flush por turno, y los registros en vuelo al apagar pueden perderse.