1
0
Fork 0
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:
Robin Appelman 2020-01-31 22:12:39 +01:00
commit 5396a883ec
3 changed files with 29 additions and 65 deletions

6
Cargo.lock generated
View file

@ -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"

View file

@ -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"

View file

@ -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
}
}