diff --git a/logfire/_internal/config.py b/logfire/_internal/config.py index 0fb86c8c..09df0194 100644 --- a/logfire/_internal/config.py +++ b/logfire/_internal/config.py @@ -944,8 +944,15 @@ def _exit_open_spans(): # type: ignore[reportUnusedFunction] # pragma: no cove # OTEL registers its own atexit callback in the tracer/meter providers to shut them down. # Registering this callback here after the OTEL one means that this runs first. # Otherwise OTEL would log an error "Already shutdown, dropping span." + # The reason that spans may be lingering open is that they're in suspended generator frames. + # Apart from here, they will be ended when the generator is garbage collected + # as the interpreter shuts down, but that's too late. for span in list(OPEN_SPANS): + # TODO maybe we should be recording something about what happened here? span.end() + # Interpreter shutdown may trigger another call to .end(), + # which would log a warning "Calling end() on an ended span." + span.end = lambda *_, **__: None # type: ignore self._initialized = True