Replies: 5 comments 5 replies
-
there currently isn't a way to hook into those layers but you can use a tracing subscriber to capture the tracing events that get fired from those layers |
Beta Was this translation helpful? Give feedback.
-
We have encountered the same issue. Look forward to the better solution. This will help improve the observability. |
Beta Was this translation helpful? Give feedback.
-
@Velfi @rcoh I saw that 1.0 is released. Do we now have a better way to monitor timeout and retry? |
Beta Was this translation helpful? Give feedback.
-
@hzxa21 FYI, for my use case of observing Throttling errors, I was able to use the [derive(Debug)]
struct ErrorLoggingInterceptor<T, E> {
msg: String,
rate_limit_errors: Arc<RelaxedCounter>,
_phantom: PhantomData<(T, E)>,
}
impl<T, E> ErrorLoggingInterceptor<T, E> {
fn apply<B>(
msg: &str,
rate_limit_errors: Arc<RelaxedCounter>,
op: CustomizableOperation<T, E, B>,
) -> CustomizableOperation<T, E, B>
where
T: Debug + Send + Sync + 'static,
E: Error + ProvideErrorMetadata + Debug + Send + Sync + 'static,
{
op.interceptor(Self {
msg: msg.to_owned(),
rate_limit_errors,
_phantom: PhantomData,
})
}
}
impl<T, E> Intercept for ErrorLoggingInterceptor<T, E>
where
T: Debug + Send + Sync + 'static,
E: Error + ProvideErrorMetadata + Debug + Send + Sync + 'static,
{
fn read_after_attempt(
&self,
context: &FinalizerInterceptorContextRef<'_>,
_runtime_components: &RuntimeComponents,
_cfg: &mut ConfigBag,
) -> std::result::Result<(), BoxError> {
if let Some(Err(error)) = context.output_or_error() {
debug!("{}: {error:?}", self.msg);
if let Some(code) = error
.as_operation_error()
.and_then(|e| e.downcast_ref::<E>())
.and_then(|e| e.meta().code())
{
if THROTTLING_ERRORS.contains(&code) {
self.rate_limit_errors.inc();
debug!("{}: throttling: {code}", self.msg);
}
}
}
Ok(())
}
fn name(&self) -> &'static str {
"zettaobject::object_access::s3::ErrorLoggingInterceptor"
}
} and it's used like so: ErrorLoggingInterceptor::apply(
&msg,
self.rate_limit_errors.clone(),
self.client
.get_object()
.bucket(&self.bucket)
.key(&key)
.set_range(range_string.clone())
.customize(),
)
.send() |
Beta Was this translation helpful? Give feedback.
-
@ahrens, I'm pretty sure that's the approach @Velfi was referring to. |
Beta Was this translation helpful? Give feedback.
-
Hello! We're using the S3 client and I was wondering if there's a way to hook into the timeout / retry service layers, or create our own middleware layer to do the same, so that we can bubble up how frequently we see retries happen. We currently set timeouts here, and we'd love to have some insight into when those timeouts are hit
Beta Was this translation helpful? Give feedback.
All reactions