Skip to content

Commit 9e7fd5a

Browse files
authored
metrics: Add endpoint labels to outbound TCP metrics (#654)
TCP metrics are pretty terse. Now that we're doing discovery for TCP forwards, it seems appropriate to expose endpoint labels on TCP metrics (at least to determine if/when mTLS is being applied).
1 parent 4bac424 commit 9e7fd5a

File tree

7 files changed

+121
-145
lines changed

7 files changed

+121
-145
lines changed

linkerd/app/core/src/transport/labels.rs

Lines changed: 14 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
use super::tls;
2+
pub use crate::metric_labels::{Direction, EndpointLabels};
23
use linkerd2_conditional::Conditional;
34
use linkerd2_metrics::FmtLabels;
45
use std::fmt;
@@ -8,68 +9,28 @@ use std::fmt;
89
/// A `Metrics` type exists for each unique `Key`.
910
///
1011
/// Implements `FmtLabels`.
11-
#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)]
12-
pub struct Key {
13-
direction: Direction,
14-
peer: Peer,
15-
tls_status: TlsStatus,
16-
}
17-
18-
#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)]
19-
struct Direction(&'static str);
20-
21-
#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)]
22-
enum Peer {
23-
/// Represents the side of the proxy that accepts connections.
24-
Src,
25-
/// Represents the side of the proxy that opens connections.
26-
Dst,
12+
#[derive(Clone, Debug, Eq, PartialEq, Hash)]
13+
pub enum Key {
14+
Accept(Direction, TlsStatus),
15+
Connect(EndpointLabels),
2716
}
2817

2918
#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)]
3019
pub struct TlsStatus(tls::Conditional<()>);
3120

32-
// ===== impl Key =====
33-
34-
impl Key {
35-
pub fn accept<T>(direction: &'static str, tls: tls::Conditional<T>) -> Self {
36-
Self {
37-
direction: Direction(direction),
38-
tls_status: TlsStatus(tls.map(|_| ())),
39-
peer: Peer::Src,
40-
}
41-
}
42-
43-
pub fn connect<T>(direction: &'static str, tls: tls::Conditional<T>) -> Self {
44-
Self {
45-
direction: Direction(direction),
46-
tls_status: TlsStatus(tls.map(|_| ())),
47-
peer: Peer::Dst,
48-
}
49-
}
50-
}
21+
// === impl Key ===
5122

5223
impl FmtLabels for Key {
53-
fn fmt_labels(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
54-
((self.direction, self.peer), self.tls_status).fmt_labels(f)
55-
}
56-
}
57-
58-
// ===== impl Peer =====
59-
60-
impl FmtLabels for Direction {
61-
fn fmt_labels(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
62-
write!(f, "direction=\"{}\"", self.0)
63-
}
64-
}
65-
66-
// ===== impl Peer =====
67-
68-
impl FmtLabels for Peer {
6924
fn fmt_labels(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
7025
match self {
71-
Peer::Src => f.pad("peer=\"src\""),
72-
Peer::Dst => f.pad("peer=\"dst\""),
26+
Self::Accept(direction, identity) => {
27+
write!(f, "peer=\"src\",")?;
28+
(direction, identity).fmt_labels(f)
29+
}
30+
Self::Connect(labels) => {
31+
write!(f, "peer=\"dst\",")?;
32+
labels.fmt_labels(f)
33+
}
7334
}
7435
}
7536
}

linkerd/app/inbound/src/lib.rs

Lines changed: 19 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -409,31 +409,35 @@ impl transport::metrics::TransportLabels<HttpEndpoint> for TransportLabels {
409409
type Labels = transport::labels::Key;
410410

411411
fn transport_labels(&self, _: &HttpEndpoint) -> Self::Labels {
412-
transport::labels::Key::connect::<()>(
413-
"inbound",
414-
tls::Conditional::None(tls::ReasonForNoPeerName::Loopback.into()),
415-
)
412+
transport::labels::Key::Connect(transport::labels::EndpointLabels {
413+
direction: transport::labels::Direction::In,
414+
authority: None,
415+
labels: None,
416+
tls_id: tls::Conditional::None(tls::ReasonForNoPeerName::Loopback.into()).into(),
417+
})
416418
}
417419
}
418420

419421
impl transport::metrics::TransportLabels<TcpEndpoint> for TransportLabels {
420422
type Labels = transport::labels::Key;
421423

422424
fn transport_labels(&self, _: &TcpEndpoint) -> Self::Labels {
423-
transport::labels::Key::connect::<()>(
424-
"inbound",
425-
tls::Conditional::None(tls::ReasonForNoPeerName::Loopback.into()),
426-
)
425+
transport::labels::Key::Connect(transport::labels::EndpointLabels {
426+
direction: transport::labels::Direction::In,
427+
authority: None,
428+
labels: None,
429+
tls_id: tls::Conditional::None(tls::ReasonForNoPeerName::Loopback.into()).into(),
430+
})
427431
}
428432
}
429433

430434
impl transport::metrics::TransportLabels<listen::Addrs> for TransportLabels {
431435
type Labels = transport::labels::Key;
432436

433437
fn transport_labels(&self, _: &listen::Addrs) -> Self::Labels {
434-
transport::labels::Key::accept::<()>(
435-
"inbound",
436-
tls::Conditional::None(tls::ReasonForNoPeerName::PortSkipped),
438+
transport::labels::Key::Accept(
439+
transport::labels::Direction::In,
440+
tls::Conditional::<()>::None(tls::ReasonForNoPeerName::PortSkipped).into(),
437441
)
438442
}
439443
}
@@ -442,7 +446,10 @@ impl transport::metrics::TransportLabels<tls::accept::Meta> for TransportLabels
442446
type Labels = transport::labels::Key;
443447

444448
fn transport_labels(&self, target: &tls::accept::Meta) -> Self::Labels {
445-
transport::labels::Key::accept("inbound", target.peer_identity.as_ref())
449+
transport::labels::Key::Accept(
450+
transport::labels::Direction::In,
451+
target.peer_identity.as_ref().into(),
452+
)
446453
}
447454
}
448455

linkerd/app/integration/tests/discovery.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -591,7 +591,7 @@ mod http2 {
591591
// Wait until the proxy has seen the `srv1` disconnect...
592592
assert_eventually_contains!(
593593
metrics.get("/metrics").await,
594-
"tcp_close_total{direction=\"outbound\",peer=\"dst\",tls=\"no_identity\",no_tls_reason=\"not_provided_by_service_discovery\",errno=\"\"} 1"
594+
"tcp_close_total{peer=\"dst\",authority=\"disco.test.svc.cluster.local\",direction=\"outbound\",tls=\"no_identity\",no_tls_reason=\"not_provided_by_service_discovery\",errno=\"\"} 1"
595595
);
596596

597597
// Start a new request to the destination, now that the server is dead.

0 commit comments

Comments
 (0)