diff --git a/apps/opentelemetry/src/otel_batch_processor.erl b/apps/opentelemetry/src/otel_batch_processor.erl index dca06d71..945aa133 100644 --- a/apps/opentelemetry/src/otel_batch_processor.erl +++ b/apps/opentelemetry/src/otel_batch_processor.erl @@ -319,6 +319,14 @@ terminate(_Reason, _State, #data{exporter=Exporter, %% `export' is used to perform a blocking export _ = export(Exporter, Resource, CurrentTable), + %% Synchronously shut the exporter down before this gen_statem exits. + %% Linked transport resources (e.g. grpcbox channels) clean up via + %% gproc in their own `terminate'; if we just return here, those + %% terminations race with the shutdown of the `grpcbox' application + %% itself and crash with "the table identifier does not refer to an + %% existing ETS table". See open-telemetry/opentelemetry-erlang#868. + _ = otel_exporter:shutdown(Exporter), + ok. %% diff --git a/apps/opentelemetry/src/otel_simple_processor.erl b/apps/opentelemetry/src/otel_simple_processor.erl index 8d07e593..26d73dc2 100644 --- a/apps/opentelemetry/src/otel_simple_processor.erl +++ b/apps/opentelemetry/src/otel_simple_processor.erl @@ -183,7 +183,12 @@ handle_event_(_, _, _, _) -> keep_state_and_data. %% @private -terminate(_, _, _Data) -> +terminate(_, _, #data{exporter=Exporter}) -> + %% Synchronously shut the exporter down before this gen_statem exits, + %% mirroring `otel_batch_processor:terminate/3'. See #868 — linked + %% grpcbox channels crash on a missing `gproc' ETS table when they + %% terminate after the `grpcbox' application is already gone. + _ = otel_exporter:shutdown(Exporter), ok. %%