Skip to content

Commit 2d7cbd8

Browse files
authored
feat(host_metrics source): add a new collector for tcp stats (#22057)
* feat(host_metrics): add a collector for TCP stats Add a new `tcp` collector to the `host_metrics` source to expose information about the systems's TCP stack. It exposes three metrics: * `tcp_connections_total`: The total number of TCP connections. It includes the `state` of the connection as a tag. * `tcp_tx_queued_bytes_total`: The sum of the number of bytes in the send queue across all connections. * `tcp_rx_queued_bytes_total`: The sum of the number of bytes in the receive queue across all connections. The collector is only enabled for Linux as it uses the netlink subsystem. Signed-off-by: Sanskar Jaiswal <jaiswalsanskar078@gmail.com> * chore(host_metrics): add changelog fragment for tcp collector Signed-off-by: Sanskar Jaiswal <jaiswalsanskar078@gmail.com> * chore(host_metrics): add docs for tcp collector Signed-off-by: Sanskar Jaiswal <jaiswalsanskar078@gmail.com> * chore: update third party licenses Signed-off-by: Sanskar Jaiswal <jaiswalsanskar078@gmail.com> * chore(host_metrics): include error source in snafu display msg Signed-off-by: Sanskar Jaiswal <jaiswalsanskar078@gmail.com> * chore(host_metrics): update cue docs Signed-off-by: Sanskar Jaiswal <jaiswalsanskar078@gmail.com> --------- Signed-off-by: Sanskar Jaiswal <jaiswalsanskar078@gmail.com>
1 parent b92e285 commit 2d7cbd8

10 files changed

Lines changed: 506 additions & 3 deletions

File tree

Cargo.lock

Lines changed: 56 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -384,13 +384,20 @@ heim = { git = "https://github.com/vectordotdev/heim.git", branch = "update-nix"
384384
# make sure to update the external docs when the Lua version changes
385385
mlua = { version = "0.10.2", default-features = false, features = ["lua54", "send", "vendored", "macros"], optional = true }
386386
sysinfo = "0.32.1"
387+
byteorder = "1.5.0"
387388

388389
[target.'cfg(windows)'.dependencies]
389390
windows-service = "0.7.0"
390391

391392
[target.'cfg(unix)'.dependencies]
392393
nix = { version = "0.26.2", default-features = false, features = ["socket", "signal"] }
393394

395+
[target.'cfg(target_os = "linux")'.dependencies]
396+
netlink-packet-utils = "0.5.2"
397+
netlink-packet-sock-diag = "0.4.2"
398+
netlink-packet-core = "0.7.0"
399+
netlink-sys = { version = "0.8.7", features = ["tokio_socket"] }
400+
394401
[build-dependencies]
395402
prost-build = { workspace = true, optional = true }
396403
tonic-build = { workspace = true, optional = true }

LICENSE-3rdparty.csv

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -385,6 +385,10 @@ mongodb,https://github.com/mongodb/mongo-rust-driver,Apache-2.0,"Saghm Rossi <sa
385385
multer,https://github.com/rousan/multer-rs,MIT,Rousan Ali <hello@rousan.io>
386386
native-tls,https://github.com/sfackler/rust-native-tls,MIT OR Apache-2.0,Steven Fackler <sfackler@gmail.com>
387387
ndk-context,https://github.com/rust-windowing/android-ndk-rs,MIT OR Apache-2.0,The Rust Windowing contributors
388+
netlink-packet-core,https://github.com/rust-netlink/netlink-packet-core,MIT,Corentin Henry <corentinhenry@gmail.com>
389+
netlink-packet-sock-diag,https://github.com/rust-netlink/netlink-packet-sock-diag,MIT,"Flier Lu <flier.lu@gmail.com>, Corentin Henry <corentinhenry@gmail.com>"
390+
netlink-packet-utils,https://github.com/rust-netlink/netlink-packet-utils,MIT,Corentin Henry <corentinhenry@gmail.com>
391+
netlink-sys,https://github.com/rust-netlink/netlink-sys,MIT,Corentin Henry <corentinhenry@gmail.com>
388392
nibble_vec,https://github.com/michaelsproul/rust_nibble_vec,MIT,Michael Sproul <micsproul@gmail.com>
389393
nix,https://github.com/nix-rust/nix,MIT,The nix-rust Project Developers
390394
nkeys,https://github.com/wasmcloud/nkeys,Apache-2.0,wasmCloud Team
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
The `host_metrics` source has a new collector, `tcp`. The `tcp`
2+
collector exposes three metrics related to the TCP stack of the
3+
system:
4+
5+
* `tcp_connections_total`: The total number of TCP connections. It
6+
includes the `state` of the connection as a tag.
7+
* `tcp_tx_queued_bytes_total`: The sum of the number of bytes in the
8+
send queue across all connections.
9+
* `tcp_rx_queued_bytes_total`: The sum of the number of bytes in the
10+
receive queue across all connections.
11+
12+
This collector is enabled only on Linux systems.
13+
14+
authors: aryan9600

license-tool.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
# `ring` has a custom license that is mostly "ISC-style" but parts of it also fall under OpenSSL licensing.
1212
"ring-0.16.20" = { license = "ISC AND Custom" }
1313
"ring-0.17.5" = { license = "ISC AND Custom" }
14+
"ring-0.17.8" = { license = "ISC AND Custom" }
1415

1516
# `rustls-webpki` doesn't specify their license in the metadata, but the file contains the ISC terms.
1617
"rustls-webpki-0.100.1" = { license = "ISC" }

src/api/schema/metrics/host.rs

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -259,6 +259,26 @@ impl DiskMetrics {
259259
}
260260
}
261261

262+
pub struct TCPMetrics(Vec<Metric>);
263+
264+
#[Object]
265+
impl TCPMetrics {
266+
/// Total TCP connections
267+
async fn tcp_conns_total(&self) -> f64 {
268+
filter_host_metric(&self.0, "tcp_connections_total")
269+
}
270+
271+
/// Total bytes in the send queue across all connections.
272+
async fn tcp_tx_queued_bytes_total(&self) -> f64 {
273+
filter_host_metric(&self.0, "tcp_tx_queued_bytes_total")
274+
}
275+
276+
/// Total bytes in the receive queue across all connections.
277+
async fn tcp_rx_queued_bytes_total(&self) -> f64 {
278+
filter_host_metric(&self.0, "tcp_rx_queued_bytes_total")
279+
}
280+
}
281+
262282
pub struct HostMetrics(host_metrics::HostMetrics);
263283

264284
impl HostMetrics {
@@ -324,6 +344,14 @@ impl HostMetrics {
324344
self.0.disk_metrics(&mut buffer).await;
325345
DiskMetrics(buffer.metrics)
326346
}
347+
348+
#[cfg(target_os = "linux")]
349+
/// TCP metrics
350+
async fn tcp(&self) -> TCPMetrics {
351+
let mut buffer = self.0.buffer();
352+
self.0.tcp_metrics(&mut buffer).await;
353+
TCPMetrics(buffer.metrics)
354+
}
327355
}
328356

329357
/// Filters a [`Vec<Metric>`] by name, returning the inner `value` or 0.00 if not found

src/sources/host_metrics/mod.rs

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,8 @@ mod filesystem;
3535
mod memory;
3636
mod network;
3737
mod process;
38+
#[cfg(target_os = "linux")]
39+
mod tcp;
3840

3941
/// Collector types.
4042
#[serde_as]
@@ -70,6 +72,9 @@ pub enum Collector {
7072

7173
/// Metrics related to network utilization.
7274
Network,
75+
76+
/// Metrics related to TCP connections.
77+
TCP,
7378
}
7479

7580
/// Filtering configuration.
@@ -178,7 +183,7 @@ pub fn default_namespace() -> Option<String> {
178183
Some(String::from("host"))
179184
}
180185

181-
const fn example_collectors() -> [&'static str; 8] {
186+
const fn example_collectors() -> [&'static str; 9] {
182187
[
183188
"cgroups",
184189
"cpu",
@@ -188,6 +193,7 @@ const fn example_collectors() -> [&'static str; 8] {
188193
"host",
189194
"memory",
190195
"network",
196+
"tcp",
191197
]
192198
}
193199

@@ -206,10 +212,12 @@ fn default_collectors() -> Option<Vec<Collector>> {
206212
#[cfg(target_os = "linux")]
207213
{
208214
collectors.push(Collector::CGroups);
215+
collectors.push(Collector::TCP);
209216
}
210217
#[cfg(not(target_os = "linux"))]
211218
if std::env::var("VECTOR_GENERATE_SCHEMA").is_ok() {
212219
collectors.push(Collector::CGroups);
220+
collectors.push(Collector::TCP);
213221
}
214222

215223
Some(collectors)
@@ -284,6 +292,9 @@ impl SourceConfig for HostMetricsConfig {
284292
if self.cgroups.is_some() || self.has_collector(Collector::CGroups) {
285293
return Err("CGroups collector is only available on Linux systems".into());
286294
}
295+
if self.has_collector(Collector::TCP) {
296+
return Err("TCP collector is only available on Linux systems".into());
297+
}
287298
}
288299

289300
let mut config = self.clone();
@@ -399,6 +410,10 @@ impl HostMetrics {
399410
if self.config.has_collector(Collector::Network) {
400411
self.network_metrics(&mut buffer).await;
401412
}
413+
#[cfg(target_os = "linux")]
414+
if self.config.has_collector(Collector::TCP) {
415+
self.tcp_metrics(&mut buffer).await;
416+
}
402417

403418
let metrics = buffer.metrics;
404419
self.events_received.emit(CountByteSize(

0 commit comments

Comments
 (0)