mirror of
https://codeberg.org/icewind/prometheus-mdns-rs.git
synced 2026-06-03 09:54:21 +02:00
use mdns 1.1
This commit is contained in:
parent
a29b862ae4
commit
5396a883ec
3 changed files with 29 additions and 65 deletions
6
Cargo.lock
generated
6
Cargo.lock
generated
|
|
@ -177,7 +177,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "mdns"
|
name = "mdns"
|
||||||
version = "1.0.0"
|
version = "1.1.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"async-stream 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"async-stream 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
|
@ -304,7 +304,7 @@ dependencies = [
|
||||||
"atomicwrites 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
"atomicwrites 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"futures-util 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"futures-util 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"main_error 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"main_error 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"mdns 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"mdns 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)",
|
"serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"serde_json 1.0.45 (registry+https://github.com/rust-lang/crates.io-index)",
|
"serde_json 1.0.45 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"tokio 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
"tokio 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
|
@ -548,7 +548,7 @@ dependencies = [
|
||||||
"checksum libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)" = "d515b1f41455adea1313a4a2ac8a8a477634fbae63cc6100e3aebb207ce61558"
|
"checksum libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)" = "d515b1f41455adea1313a4a2ac8a8a477634fbae63cc6100e3aebb207ce61558"
|
||||||
"checksum log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)" = "14b6052be84e6b71ab17edffc2eeabf5c2c3ae1fdb464aae35ac50c67a44e1f7"
|
"checksum log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)" = "14b6052be84e6b71ab17edffc2eeabf5c2c3ae1fdb464aae35ac50c67a44e1f7"
|
||||||
"checksum main_error 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3516df0fb44d98fe6d6e859d224adfb7b6686447937e5b96308d6061595eed04"
|
"checksum main_error 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3516df0fb44d98fe6d6e859d224adfb7b6686447937e5b96308d6061595eed04"
|
||||||
"checksum mdns 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d1d1e461d374d1e092612bd6087031f55c03dd10a38e680dce380181ba0aabf0"
|
"checksum mdns 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "caccbabad4e71a1a261c872ac0bb94ce9958098a1ef4c637f2b4de4f6835ce7e"
|
||||||
"checksum mio 0.6.21 (registry+https://github.com/rust-lang/crates.io-index)" = "302dec22bcf6bae6dfb69c647187f4b4d0fb6f535521f7bc022430ce8e12008f"
|
"checksum mio 0.6.21 (registry+https://github.com/rust-lang/crates.io-index)" = "302dec22bcf6bae6dfb69c647187f4b4d0fb6f535521f7bc022430ce8e12008f"
|
||||||
"checksum miow 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8c1f2f3b1cf331de6896aabf6e9d55dca90356cc9960cca7eaaf408a355ae919"
|
"checksum miow 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8c1f2f3b1cf331de6896aabf6e9d55dca90356cc9960cca7eaaf408a355ae919"
|
||||||
"checksum net2 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)" = "42550d9fb7b6684a6d404d9fa7250c2eb2646df731d1c06afc06dcee9e1bcf88"
|
"checksum net2 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)" = "42550d9fb7b6684a6d404d9fa7250c2eb2646df731d1c06afc06dcee9e1bcf88"
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@ repository = "https://github.com/icewind1991/prometheus-mdns-rs"
|
||||||
keywords = ["mdns", "prometheus"]
|
keywords = ["mdns", "prometheus"]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
mdns = "1.0"
|
mdns = "1.1"
|
||||||
tokio = { version = "0.2.4", features = ["macros"] }
|
tokio = { version = "0.2.4", features = ["macros"] }
|
||||||
serde = { version = "1.0", features = ["derive"] }
|
serde = { version = "1.0", features = ["derive"] }
|
||||||
serde_json = "1.0"
|
serde_json = "1.0"
|
||||||
|
|
|
||||||
84
src/main.rs
84
src/main.rs
|
|
@ -1,20 +1,20 @@
|
||||||
use atomicwrites::{AllowOverwrite, AtomicFile};
|
use atomicwrites::{AllowOverwrite, AtomicFile};
|
||||||
use futures_util::{pin_mut, stream::StreamExt};
|
use futures_util::{pin_mut, stream::StreamExt};
|
||||||
use mdns::{Record, RecordKind};
|
use mdns::Response;
|
||||||
use serde::Serialize;
|
use serde::Serialize;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::env;
|
use std::env;
|
||||||
use std::io::Write;
|
use std::io::Write;
|
||||||
|
use std::net::SocketAddr;
|
||||||
|
use std::time::Duration;
|
||||||
use std::time::Instant;
|
use std::time::Instant;
|
||||||
use std::{net::IpAddr, time::Duration};
|
|
||||||
|
|
||||||
/// The hostname of the devices we are searching for.
|
/// The hostname of the devices we are searching for.
|
||||||
const SERVICE_NAME: &str = "_prometheus-http._tcp.local";
|
const SERVICE_NAME: &str = "_prometheus-http._tcp.local";
|
||||||
|
|
||||||
struct Service {
|
struct Service {
|
||||||
labels: HashMap<String, String>,
|
labels: HashMap<String, String>,
|
||||||
addr: IpAddr,
|
addr: SocketAddr,
|
||||||
port: u16,
|
|
||||||
last_seen: Instant,
|
last_seen: Instant,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -27,7 +27,7 @@ struct PrometheusService<'a> {
|
||||||
impl<'a> From<&'a Service> for PrometheusService<'a> {
|
impl<'a> From<&'a Service> for PrometheusService<'a> {
|
||||||
fn from(service: &'a Service) -> Self {
|
fn from(service: &'a Service) -> Self {
|
||||||
PrometheusService {
|
PrometheusService {
|
||||||
targets: vec![format!("{}:{}", service.addr, service.port)],
|
targets: vec![service.addr.to_string()],
|
||||||
labels: &service.labels,
|
labels: &service.labels,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -45,22 +45,31 @@ async fn main() -> Result<(), main_error::MainError> {
|
||||||
let stream = mdns::discover::all(SERVICE_NAME, INTERVAL)?.listen();
|
let stream = mdns::discover::all(SERVICE_NAME, INTERVAL)?.listen();
|
||||||
pin_mut!(stream);
|
pin_mut!(stream);
|
||||||
|
|
||||||
let mut services: HashMap<IpAddr, Service> = HashMap::new();
|
let mut services: HashMap<SocketAddr, Service> = HashMap::new();
|
||||||
|
|
||||||
while let Some(Ok(response)) = stream.next().await {
|
while let Some(Ok(response)) = stream.next().await {
|
||||||
let addr: Option<IpAddr> = response.records().find_map(self::to_ip_addr);
|
let response: Response = response;
|
||||||
let port: Option<u16> = response.records().find_map(self::to_port);
|
let addr = response.socket_address();
|
||||||
let labels: Option<HashMap<String, String>> = response.records().find_map(self::to_labels);
|
let mut labels: HashMap<String, String> = response
|
||||||
let hostname: Option<String> = response.records().find_map(self::to_hostname);
|
.txt_records()
|
||||||
|
.flat_map(|pair| {
|
||||||
|
let mut parts = pair.split('=');
|
||||||
|
if let (Some(key), Some(value)) = (parts.next(), parts.next()) {
|
||||||
|
Some((key.to_string(), value.to_string()))
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.collect();
|
||||||
|
let hostname = response
|
||||||
|
.hostname()
|
||||||
|
.and_then(|host| host.split('.').next().map(|s| s.to_string()));
|
||||||
|
|
||||||
if let (Some(addr), Some(mut labels), Some(port), Some(hostname)) =
|
if let (Some(addr), Some(hostname)) = (addr, hostname) {
|
||||||
(addr, labels, port, hostname)
|
labels.insert("hostname".to_string(), hostname.to_string());
|
||||||
{
|
|
||||||
labels.insert("hostname".to_string(), hostname);
|
|
||||||
let service = Service {
|
let service = Service {
|
||||||
labels,
|
labels,
|
||||||
addr,
|
addr,
|
||||||
port,
|
|
||||||
last_seen: Instant::now(),
|
last_seen: Instant::now(),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -91,48 +100,3 @@ async fn main() -> Result<(), main_error::MainError> {
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn to_hostname(record: &Record) -> Option<String> {
|
|
||||||
match &record.kind {
|
|
||||||
RecordKind::PTR(id) => id.split('.').next().map(|s| s.to_string()),
|
|
||||||
_ => None,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn to_ip_addr(record: &Record) -> Option<IpAddr> {
|
|
||||||
match record.kind {
|
|
||||||
RecordKind::A(addr) => Some(addr.into()),
|
|
||||||
RecordKind::AAAA(addr) => Some(addr.into()),
|
|
||||||
_ => None,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn to_port(record: &Record) -> Option<u16> {
|
|
||||||
match record.kind {
|
|
||||||
RecordKind::SRV { port, .. } if record.name.contains(SERVICE_NAME) => Some(port),
|
|
||||||
_ => None,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn to_labels(record: &Record) -> Option<HashMap<String, String>> {
|
|
||||||
if record.name.contains(SERVICE_NAME) {
|
|
||||||
if let RecordKind::TXT(txt) = &record.kind {
|
|
||||||
Some(
|
|
||||||
txt.iter()
|
|
||||||
.flat_map(|pair| {
|
|
||||||
let mut parts = pair.split('=');
|
|
||||||
if let (Some(key), Some(value)) = (parts.next(), parts.next()) {
|
|
||||||
Some((key.to_string(), value.to_string()))
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.collect(),
|
|
||||||
)
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue