diff --git a/linkerd/app/outbound/src/http/concrete.rs b/linkerd/app/outbound/src/http/concrete.rs index 0fbfcca0cd..e690530f6e 100644 --- a/linkerd/app/outbound/src/http/concrete.rs +++ b/linkerd/app/outbound/src/http/concrete.rs @@ -42,7 +42,7 @@ pub struct DispatcherFailed(Arc); /// Wraps errors encountered in this module. #[derive(Debug, thiserror::Error)] -#[error("{} {}.{}: {source}", backend.0.kind(), backend.0.name(), backend.0.namespace())] +#[error("{}: {source}", backend.0)] pub struct BalanceError { backend: BackendRef, #[source] diff --git a/linkerd/app/outbound/src/http/logical/policy/route.rs b/linkerd/app/outbound/src/http/logical/policy/route.rs index 24224481a8..3ef64224cc 100644 --- a/linkerd/app/outbound/src/http/logical/policy/route.rs +++ b/linkerd/app/outbound/src/http/logical/policy/route.rs @@ -50,6 +50,15 @@ pub(crate) type Grpc = MatchedRoute< pub(crate) type BackendDistribution = distribute::Distribution>; pub(crate) type NewDistribute = distribute::NewDistribute, (), N>; +/// Wraps errors with route metadata. +#[derive(Debug, thiserror::Error)] +#[error("route {}: {source}", route.0)] +struct RouteError { + route: RouteRef, + #[source] + source: Error, +} + // === impl MatchedRoute === impl MatchedRoute @@ -115,6 +124,15 @@ where // Sets an optional request timeout. .push(http::NewTimeout::layer()) .push(classify::NewClassify::layer()) + .push(svc::NewMapErr::layer_with(|rt: &Self| { + let route = rt.params.route_ref.clone(); + move |source| { + Error::from(RouteError { + route: route.clone(), + source, + }) + } + })) .push(svc::ArcNewService::layer()) .into_inner() }) diff --git a/linkerd/app/outbound/src/http/logical/policy/route/backend.rs b/linkerd/app/outbound/src/http/logical/policy/route/backend.rs index a0d335c000..5d0fb3b804 100644 --- a/linkerd/app/outbound/src/http/logical/policy/route/backend.rs +++ b/linkerd/app/outbound/src/http/logical/policy/route/backend.rs @@ -1,5 +1,5 @@ use super::{super::Concrete, filters}; -use crate::RouteRef; +use crate::{BackendRef, RouteRef}; use linkerd_app_core::{proxy::http, svc, Error, Result}; use linkerd_http_route as http_route; use linkerd_proxy_client_policy as policy; @@ -29,6 +29,15 @@ pub struct ExtractMetrics { metrics: RouteBackendMetrics, } +/// Wraps errors with backend metadata. +#[derive(Debug, thiserror::Error)] +#[error("backend {}: {source}", backend.0)] +struct BackendError { + backend: BackendRef, + #[source] + source: Error, +} + // === impl Backend === impl Clone for Backend { @@ -110,6 +119,15 @@ where .push(count_reqs::NewCountRequests::layer_via(ExtractMetrics { metrics: metrics.clone(), })) + .push(svc::NewMapErr::layer_with(|t: &Self| { + let backend = t.params.concrete.backend_ref.clone(); + move |source| { + Error::from(BackendError { + backend: backend.clone(), + source, + }) + } + })) .push(svc::ArcNewService::layer()) .into_inner() }) diff --git a/linkerd/proxy/client-policy/src/lib.rs b/linkerd/proxy/client-policy/src/lib.rs index f525a041f0..92d942f241 100644 --- a/linkerd/proxy/client-policy/src/lib.rs +++ b/linkerd/proxy/client-policy/src/lib.rs @@ -2,7 +2,7 @@ #![forbid(unsafe_code)] use once_cell::sync::Lazy; -use std::{borrow::Cow, hash::Hash, net::SocketAddr, num::NonZeroU16, sync::Arc, time}; +use std::{borrow::Cow, fmt, hash::Hash, net::SocketAddr, num::NonZeroU16, sync::Arc, time}; pub mod grpc; pub mod http; @@ -264,6 +264,27 @@ impl std::hash::Hash for Meta { } } +impl fmt::Display for Meta { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match self { + Self::Default { name } => write!(f, "default.{name}"), + Self::Resource { + kind, + name, + namespace, + port, + .. + } => { + write!(f, "{kind}.{namespace}.{name}")?; + if let Some(port) = port { + write!(f, ":{port}")? + } + Ok(()) + } + } + } +} + // === impl FailureAccrual === impl Default for FailureAccrual {