Let OTLP log and trace exporters leave no timer pending while idle
Los mantenedores suelen responder en 1 día
Evaluación
Este issue todavía no se ha evaluado.
Descripción
What is the problem this feature would solve?
OtlpExporter.make re-arms its export timer forever, even with nothing buffered (OtlpExporter.ts#L264-L269). So an idle program always has a timer pending: every 1 s for logs and every 5 s for traces. Some runtimes stay in memory while a timer is pending. Cloudflare Durable Objects, for example, can't hibernate and keep billing duration (docs).
OpenTelemetry JS avoids this. Its span and log processors start the timer on the first record and stop once the buffer is empty (BatchSpanProcessorBase.ts#L230-L253, BatchLogRecordProcessorBase.ts#L333-L368).
Prior discussion: effect-smol#2107 and #6641 added Flusher, so a workerd integration can flush per event instead of waiting for an interval. That covers work inside an event. This covers the exporter's own timer, which keeps an idle Durable Object from hibernating even when every event flushes.
Repro ([email protected], same code on main): npm i [email protected] tsx@4, then npx tsx repro.ts.
import { Effect, Layer } from "effect"
import { FetchHttpClient } from "effect/http"
import { OtlpLogger, OtlpSerialization, OtlpTracer } from "effect/observability"
const resource = { serviceName: "idle" }
const exporters = Layer.mergeAll(
OtlpLogger.layer({ url: "http://localhost:4318/v1/logs", resource }),
OtlpTracer.layer({ url: "http://localhost:4318/v1/traces", resource })
).pipe(Layer.provide(OtlpSerialization.layerJson), Layer.provide(FetchHttpClient.layer))
// Nothing is ever logged or traced.
Effect.runFork(Effect.never.pipe(Effect.provide(exporters)))
setTimeout(() => {
const timers = process.getActiveResourcesInfo().filter((name) => name === "Timeout").length
console.log("timers pending after 3 s idle:", timers - 1) // minus this one
process.exit(0)
}, 3000)
- Expected:
timers pending after 3 s idle: 0. - Actual:
timers pending after 3 s idle: 2, one per exporter, for as long as the scope is open.
What is the feature you are proposing to solve the problem?
Match OpenTelemetry JS: a log or trace exporter starts its interval when a record reaches an empty buffer, and stops once the buffer is empty again. Records still go out within one interval, and exports stay one at a time. Metrics keep their fixed interval, as OpenTelemetry's periodic reader does. So the combined Otlp layers still tick unless metrics use metricsExportInterval: Duration.infinity with Flusher.flush. I have a PR ready.
What alternatives have you considered?
exportInterval: Duration.infinityplusFlusher.flush. This works today, but records then wait for a manual flush and are lost if the runtime drops the instance first.- An option. No one benefits from a timer that exports nothing.
Related: alchemy-run/alchemy#2878. We hit this exporting from Cloudflare Durable Objects built with Alchemy.
I investigated this with an AI coding agent, Claude Code. The agent read the Effect sources, wrote the repro and the patch, and ran them and Effect's checks. I reviewed the analysis before filing.
- Lenguaje dominante
- TypeScript
- Estrellas
- 16.7k
- Forks
- 808
- Merge medio
- 10 h 15 min
- PR fusionados (30 d)
- 845
Preparar el entorno
Este proyecto no incluye contenedor de desarrollo, Dockerfile ni guía de contribución, así que la configuración corre por tu cuenta: empieza por su README y consulta nuestra guía para la primera contribución para los pasos generales.
Primeros pasos
- Lee el issue completo y luego la guía de contribución del proyecto.
- Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
- Haz un fork del repositorio y trabaja en una rama.
- Abre un pull request que haga referencia al número del issue.
Más de Effect-TS/effect
-
Otlp.layerFromConfig exports nothing when only OTEL_EXPORTER_OTLP_ENDPOINT is setPosiblemente ocupada @effect-bot la tomó hoy. Abierto
Effect-TS/effect#10231 · 1 asignado ·
Los mantenedores suelen responder en 1 día
-
sql: give BEGIN, COMMIT, ROLLBACK and savepoint statements their own spans under sql.transactionPosiblemente ocupada @effect-bot la tomó hace 1 día. Abierto
Effect-TS/effect#10203 · 1 comentario · 1 asignado ·
Los mantenedores suelen responder en 1 día
-
OpenApi.fromApi (4.1.0) emits duplicate component schemas with a _1 suffix when the encoded side differsQuizá libre de nuevo Un pull request para esta issue se cerró sin fusionarse. Abierto
Dificultad 3/5 1-2 días Aptitud para principiantes 35/100
Los mantenedores suelen responder en 1 día
-
cluster: a runner that lost its shard lock can still write replies and messages for that shardAbierto
Dificultad 5/5 Más de una semana Aptitud para principiantes 35/100
Los mantenedores suelen responder en 1 día
-
Dificultad 4/5 3-5 días Aptitud para principiantes 47/100
Los mantenedores suelen responder en 1 día
Todos los issues de Effect-TS/effect
Issues similares
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 85/100
Slaymish/HealthAgent#7 ·
-
area: engine topic: math type: bug
Dificultad 2/5 1-3 horas Aptitud para principiantes 80/100
Los mantenedores suelen responder en 1 día
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 75/100
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 70/100
Get-Concord-AI/concord-mcp#310 ·
Los mantenedores suelen responder en 1 día
-
Correct install_claude: 'marketplace add' over a different source is refused, not replaced in placeAbiertotype:bug
Dificultad 2/5 1-3 horas Aptitud para principiantes 80/100
nightgauge/nightgauge#2804 ·
Los mantenedores suelen responder en 1 día