-
Notifications
You must be signed in to change notification settings - Fork 657
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Implement shutdown procedure for OTLP grpc exporters #3138
Implement shutdown procedure for OTLP grpc exporters #3138
Conversation
- Add `_shutdown` variable for checking if the exporter has been shutdown. - Prevent export if the `_shutdown` flag has been set. Log a warning message is exporter has been shutdown. - Use thread lock to synchronize the last export call before shutdown timeout. The `shutdown` method will wait until the `timeout_millis` if there is an ongoing export. If there is no ongiong export, set the `_shutdown` flag to prevent further exports and return. - Add unit tests for the `OTLPExporterMixIn` and the sub classes for traces and metrics.
...pentelemetry-exporter-otlp-proto-grpc/src/opentelemetry/exporter/otlp/proto/grpc/exporter.py
Show resolved
Hide resolved
@srikanthccv Any opinions on the open question in the PR description? After more investigation I found out that if the code doesn't end the exponential back off in the |
As soon as the shutdown request is received, it should do one last flush before exiting. IIRC there was no reliable way to cancel the ongoing export call and just try once before shutting down everything. I haven't looked at the implementation but if you have some ideas please suggest them. |
Combining the last flush with the shutdown process can make the logic a bit more complicated. If nobody is complaining then let's leave it as it is. Otherwise we would need to change the |
Please fix the lint |
Thank you! |
@@ -290,6 +290,9 @@ def _translate_data( | |||
def export(self, spans: Sequence[ReadableSpan]) -> SpanExportResult: | |||
return self._export(spans) | |||
|
|||
def shutdown(self) -> None: | |||
OTLPExporterMixin.shutdown(self) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@girishc13 Can you please help me understand why you are calling shutdown
on mixin class directly instead of using super()
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't remember the exact details but the shutdown
method is implemented by both the OTLPExporterMixin
and the SpanExporter
interfaces. The exporter.shutdown is handled by different logic and this pr was targeting the backend client that needs to be shutdown. You need to trace the calls for shutdown from the usage of the OTLPSpanExporter
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the issue maybe due to mixin inheritance being applied incorrectly, currently we have
class OTLPSpanExporter(SpanExporter, OTLPExporterMixin[...]):
but usually in python mixin should come before the base class, e.g.
class OTLPSpanExporter(OTLPExporterMixin[...], SpanExporter):
this way, super().shutdown()
call will correctly use shutdown
method from mixin
@girishc13 @lzchen @srikanthccv why in grpc verision, use _export_lock, and why http.OTLPSpanExporter not need the lock flag? |
Hi @Liubey, either there was no HTTP exporter at the time or the author only addressed the issue for the gRPC exporter. |
Description
Partial fix for #1791. Implements the
shutdown
procedure for OTLP gRPC exporters._shutdown
variable for checking if the exporter has been shutdown._shutdown
flag has been set. Log a warning message is exporter has been shutdown.shutdown
method will wait until thetimeout_millis
if there is an ongoing export. If there is no ongiong export, set the_shutdown
flag to prevent further exports and return.OTLPExporterMixIn
and the sub classes for traces and metrics.Type of change
Please delete options that are not relevant.
How Has This Been Tested?
Please describe the tests that you ran to verify your changes. Provide instructions so we can reproduce. Please also list any relevant details for your test configuration
TestOTLPExporterMixin
test_shutdown
: assert that the further exports don't happen after calling theshutdown
method.test_shutdown_wait_last_export
: assert that the shutdown method waits for at leasttimeout_millis
time if an export is in progress before setting the_shutdown
flag to prevent further exports.TestOTLPMetricExporter
andTestOTLPTracesExporter
Does This PR Require a Contrib Repo Change?
Answer the following question based on these examples of changes that would require a Contrib Repo Change:
The OTel specification has changed which prompted this PR to update the method interfaces of
opentelemetry-api/
oropentelemetry-sdk/
The method interfaces of
test/util
have changedScripts in
scripts/
that were copied over to the Contrib repo have changedConfiguration files that were copied over to the Contrib repo have changed (when consistency between repositories is applicable) such as in
pyproject.toml
isort.cfg
.flake8
When a new
.github/CODEOWNER
is addedMajor changes to project information, such as in:
README.md
CONTRIBUTING.md
Yes. - Link to PR:
No.
Checklist:
tox -e lint
on my machine due to some issue with thedistutils
module. I have manually runblack
andisort
commands but there are some changes which might be questionable. I'll try to fix thedistutils
package issues.Open Question
The OTLP gRPC exporters run in a daemon thread with an exponential backoff of max 64 seconds. This is questionable because this often leaves a hanging thread even if the main process has been shutdown. Should the export function stop after the shutdown flag has been set even if the retry is in progress?