-
Notifications
You must be signed in to change notification settings - Fork 599
chore: modify LogExporter and TraceExporter interfaces to support returning failure #2381
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
Changes from 7 commits
2c24988
5b243a6
77d9a01
dc5d9b1
1b49188
a670a4e
6440a73
3c68efa
c2586ce
a460184
b1fff95
0ad193f
4df322f
26bbdc4
de49068
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -5,11 +5,16 @@ | |
| use opentelemetry::{InstrumentationScope, KeyValue}; | ||
| use std::borrow::Cow; | ||
| use std::fmt::Debug; | ||
| use std::time::SystemTime; | ||
| use std::sync::PoisonError; | ||
| use std::time::{Duration, SystemTime}; | ||
| use thiserror::Error; | ||
|
|
||
| /// Describes the result of an export. | ||
| /// Results of an export operation | ||
| pub type ExportResult = Result<(), TraceError>; | ||
|
|
||
| /// Result of a shutdown operation | ||
| pub type ShutdownResult = Result<(), ShutdownError>; | ||
|
|
||
| /// `SpanExporter` defines the interface that protocol-specific exporters must | ||
| /// implement so that they can be plugged into OpenTelemetry SDK and support | ||
| /// sending of telemetry data. | ||
|
|
@@ -30,7 +35,7 @@ | |
| /// | ||
| /// Any retry logic that is required by the exporter is the responsibility | ||
| /// of the exporter. | ||
| fn export(&mut self, batch: Vec<SpanData>) -> BoxFuture<'static, ExportResult>; | ||
| fn export(&mut self, batch: Vec<SpanData>) -> BoxFuture<'static, Result<(), TraceError>>; | ||
|
|
||
| /// Shuts down the exporter. Called when SDK is shut down. This is an | ||
| /// opportunity for exporter to do any cleanup required. | ||
|
|
@@ -43,7 +48,9 @@ | |
| /// flush the data and the destination is unavailable). SDK authors | ||
| /// can decide if they want to make the shutdown timeout | ||
| /// configurable. | ||
| fn shutdown(&mut self) {} | ||
| fn shutdown(&mut self) -> ShutdownResult { | ||
| Ok(()) | ||
| } | ||
|
|
||
| /// This is a hint to ensure that the export of any Spans the exporter | ||
| /// has received prior to the call to this function SHOULD be completed | ||
|
|
@@ -98,3 +105,31 @@ | |
| /// Instrumentation scope that produced this span | ||
| pub instrumentation_scope: InstrumentationScope, | ||
| } | ||
|
|
||
| /// Errors returned by shutdown operations in the Export API. | ||
| #[derive(Error, Debug)] | ||
| #[non_exhaustive] | ||
| pub enum ShutdownError { | ||
| /// The exporter has already been shut down. | ||
|
||
| #[error("Shutdown already performed")] | ||
| AlreadyShutdown, | ||
|
|
||
| /// Shutdown timed out before completing. | ||
| #[error("Shutdown timed out after {0:?}")] | ||
| Timeout(Duration), | ||
|
|
||
| /// An unexpected error occurred during shutdown. | ||
| #[error(transparent)] | ||
| Other(#[from] Box<dyn std::error::Error + Send + Sync + 'static>), | ||
| } | ||
|
|
||
| /// Custom error wrapper for string messages. | ||
| #[derive(Error, Debug)] | ||
| #[error("{0}")] | ||
| struct CustomError(String); | ||
|
|
||
| impl<T> From<PoisonError<T>> for ShutdownError { | ||
| fn from(err: PoisonError<T>) -> Self { | ||
| ShutdownError::Other(Box::new(CustomError(err.to_string()))) | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -61,3 +61,22 @@ | |
| #[derive(Error, Debug)] | ||
| #[error("{0}")] | ||
| struct Custom(String); | ||
|
|
||
| /// Errors returned during shutdown | ||
| #[derive(Error, Debug)] | ||
| #[non_exhaustive] | ||
| pub enum ShutdownError { | ||
| /// Mutex lock poisoning | ||
| #[error("mutex lock poisioning for {0}")] | ||
| MutexPoisoned(String), | ||
|
||
|
|
||
| /// Other errors propagated from log SDK that weren't covered above. | ||
| #[error(transparent)] | ||
| Other(#[from] Box<dyn std::error::Error + Send + Sync + 'static>), | ||
| } | ||
|
|
||
| impl<T> From<PoisonError<T>> for ShutdownError { | ||
| fn from(err: PoisonError<T>) -> Self { | ||
| ShutdownError::Other(err.to_string().into()) | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -149,14 +149,10 @@ | |
| } | ||
|
|
||
| fn shutdown(&self) -> TraceResult<()> { | ||
|
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think we should (in another issue!) chase this distinction between |
||
| if let Ok(mut exporter) = self.exporter.lock() { | ||
| exporter.shutdown(); | ||
| Ok(()) | ||
| } else { | ||
| Err(TraceError::Other( | ||
| "SimpleSpanProcessor mutex poison at shutdown".into(), | ||
| )) | ||
| } | ||
| self.exporter | ||
| .lock()? | ||
| .shutdown() | ||
| .map_err(|e| TraceError::Other(Box::new(e))) | ||
| } | ||
|
|
||
| fn set_resource(&mut self, resource: &Resource) { | ||
|
|
@@ -432,7 +428,12 @@ | |
| // Stream has terminated or processor is shutdown, return to finish execution. | ||
| BatchMessage::Shutdown(ch) => { | ||
| self.flush(Some(ch)).await; | ||
| self.exporter.shutdown(); | ||
| if let Err(e) = self.exporter.shutdown() { | ||
| otel_warn!( | ||
| name: "SpanProcessor.Shutdown.Failed", | ||
| message = "failed shutting down exporter cleanly", | ||
| error = format!("{:?}", e)); | ||
| } | ||
| return false; | ||
| } | ||
| // propagate the resource | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.