File tree Expand file tree Collapse file tree 1 file changed +15
-1
lines changed
Expand file tree Collapse file tree 1 file changed +15
-1
lines changed Original file line number Diff line number Diff line change @@ -946,7 +946,7 @@ def fix_pid(): # pragma: no cover
946946 set_meter_provider (self ._meter_provider )
947947
948948 @atexit .register
949- def _exit_open_spans (): # type: ignore[reportUnusedFunction] # pragma: no cover
949+ def exit_open_spans (): # pragma: no cover
950950 # Ensure that all open spans are closed when the program exits.
951951 # OTEL registers its own atexit callback in the tracer/meter providers to shut them down.
952952 # Registering this callback here after the OTEL one means that this runs first.
@@ -961,6 +961,20 @@ def _exit_open_spans(): # type: ignore[reportUnusedFunction] # pragma: no cove
961961 # which would log a warning "Calling end() on an ended span."
962962 span .end = lambda * _ , ** __ : None # type: ignore
963963
964+ # atexit isn't called in forked processes, patch os._exit to ensure cleanup.
965+ # https://github.com/pydantic/logfire/issues/779
966+ original_os_exit = os ._exit
967+
968+ def patched_os_exit (code : int ): # pragma: no cover
969+ try :
970+ exit_open_spans ()
971+ self .force_flush ()
972+ except : # noqa # weird errors can happen during shutdown, ignore them *all* with a bare except
973+ pass
974+ return original_os_exit (code )
975+
976+ os ._exit = patched_os_exit
977+
964978 self ._initialized = True
965979
966980 # set up context propagation for ThreadPoolExecutor and ProcessPoolExecutor
You can’t perform that action at this time.
0 commit comments