improve parsing of durations

This commit is contained in:
2026-02-03 19:38:02 -08:00
parent 2e8e731d80
commit d464cf8ee6
6 changed files with 185 additions and 24 deletions

157
Cargo.lock generated
View File

@@ -159,6 +159,12 @@ version = "0.21.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567"
[[package]]
name = "base64"
version = "0.22.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6"
[[package]]
name = "bitflags"
version = "1.3.2"
@@ -241,6 +247,7 @@ dependencies = [
"serde_derive",
"serde_json",
"serde_repr",
"serde_with",
"serialport",
"tokio",
"tokio-serial",
@@ -386,6 +393,41 @@ dependencies = [
"memchr",
]
[[package]]
name = "darling"
version = "0.21.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9cdf337090841a411e2a7f3deb9187445851f91b309c0c0a29e05f74a00a48c0"
dependencies = [
"darling_core",
"darling_macro",
]
[[package]]
name = "darling_core"
version = "0.21.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1247195ecd7e3c85f83c8d2a366e4210d588e802133e1e355180a9870b517ea4"
dependencies = [
"fnv",
"ident_case",
"proc-macro2",
"quote",
"strsim",
"syn 2.0.114",
]
[[package]]
name = "darling_macro"
version = "0.21.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d38308df82d1080de0afee5d069fa14b0326a88c14f15c5ccda35b4a6c414c81"
dependencies = [
"darling_core",
"quote",
"syn 2.0.114",
]
[[package]]
name = "dashmap"
version = "4.0.2"
@@ -403,6 +445,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ececcb659e7ba858fb4f10388c250a7252eb0a27373f1a72b8748afdd248e587"
dependencies = [
"powerfmt",
"serde_core",
]
[[package]]
@@ -428,6 +471,12 @@ version = "0.15.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "77c90badedccf4105eca100756a0b1289e191f6fcbdadd3cee1d2f614f97da8f"
[[package]]
name = "dyn-clone"
version = "1.0.20"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d0881ea181b1df73ff77ffaaf9c7544ecc11e82fba9b5f27b262a3c73a332555"
[[package]]
name = "either"
version = "1.15.0"
@@ -672,13 +721,19 @@ dependencies = [
"futures-sink",
"futures-util",
"http",
"indexmap",
"indexmap 2.13.0",
"slab",
"tokio",
"tokio-util",
"tracing",
]
[[package]]
name = "hashbrown"
version = "0.12.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888"
[[package]]
name = "hashbrown"
version = "0.16.1"
@@ -879,6 +934,12 @@ dependencies = [
"zerovec",
]
[[package]]
name = "ident_case"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39"
[[package]]
name = "idna"
version = "1.1.0"
@@ -900,6 +961,17 @@ dependencies = [
"icu_properties",
]
[[package]]
name = "indexmap"
version = "1.9.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99"
dependencies = [
"autocfg",
"hashbrown 0.12.3",
"serde",
]
[[package]]
name = "indexmap"
version = "2.13.0"
@@ -907,7 +979,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7714e70437a7dc3ac8eb7e6f8df75fd8eb422675fc7678aff7364301092b1017"
dependencies = [
"equivalent",
"hashbrown",
"hashbrown 0.16.1",
"serde",
"serde_core",
]
[[package]]
@@ -1516,6 +1590,26 @@ dependencies = [
"bitflags 1.3.2",
]
[[package]]
name = "ref-cast"
version = "1.0.25"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f354300ae66f76f1c85c5f84693f0ce81d747e2c3f21a45fef496d89c960bf7d"
dependencies = [
"ref-cast-impl",
]
[[package]]
name = "ref-cast-impl"
version = "1.0.25"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b7186006dcb21920990093f30e3dea63b7d6e977bf1256be20c3563a5db070da"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.114",
]
[[package]]
name = "regex"
version = "1.12.2"
@@ -1645,6 +1739,30 @@ dependencies = [
"windows-sys 0.61.2",
]
[[package]]
name = "schemars"
version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4cd191f9397d57d581cddd31014772520aa448f65ef991055d7f61582c65165f"
dependencies = [
"dyn-clone",
"ref-cast",
"serde",
"serde_json",
]
[[package]]
name = "schemars"
version = "1.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a2b42f36aa1cd011945615b92222f6bf73c599a102a300334cd7f8dbeec726cc"
dependencies = [
"dyn-clone",
"ref-cast",
"serde",
"serde_json",
]
[[package]]
name = "scopeguard"
version = "1.2.0"
@@ -1760,6 +1878,37 @@ dependencies = [
"serde",
]
[[package]]
name = "serde_with"
version = "3.16.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4fa237f2807440d238e0364a218270b98f767a00d3dada77b1c53ae88940e2e7"
dependencies = [
"base64 0.22.1",
"chrono",
"hex",
"indexmap 1.9.3",
"indexmap 2.13.0",
"schemars 0.9.0",
"schemars 1.2.1",
"serde_core",
"serde_json",
"serde_with_macros",
"time",
]
[[package]]
name = "serde_with_macros"
version = "3.16.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "52a8e3ca0ca629121f70ab50f95249e5a6f925cc0f6ffe8256c45b728875706c"
dependencies = [
"darling",
"proc-macro2",
"quote",
"syn 2.0.114",
]
[[package]]
name = "serialport"
version = "4.8.1"
@@ -2131,7 +2280,7 @@ version = "0.19.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1b5bb770da30e5cbfde35a2d7b9b8a2c4b8ef89548a7a6aeab5c9a576e3e7421"
dependencies = [
"indexmap",
"indexmap 2.13.0",
"toml_datetime",
"winnow 0.5.40",
]
@@ -2142,7 +2291,7 @@ version = "0.22.27"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "41fe8c660ae4257887cf66394862d21dbca4a6ddd26f04a3560410406a2f819a"
dependencies = [
"indexmap",
"indexmap 2.13.0",
"serde",
"serde_spanned",
"toml_datetime",

View File

@@ -34,6 +34,7 @@ gethostname = "1.1.0"
bitflags = "2.10.0"
influxdb2 = "0.3.9"
chrono = "0.4.43"
serde_with = "3.16.1"
[dependencies.chrony-candm]
git = "https://github.com/aws/chrony-candm"

View File

@@ -12,6 +12,7 @@ use figment::{
use gethostname::gethostname;
use influxdb2::models::DataPoint;
use serde_derive::{Deserialize, Serialize};
use serde_with::{DurationSeconds, serde_as};
use tokio::sync::broadcast::*;
use std::{fmt::Debug, path::Path, sync::Arc};
@@ -40,12 +41,16 @@ impl Default for InfluxConfig {
}
}
#[serde_as]
#[derive(Serialize, Deserialize, Clone)]
pub struct ChronyConfig {
pub enabled: bool,
pub timeout: u64,
pub tracking_interval: u64,
pub sources_interval: u64,
#[serde_as(as = "DurationSeconds<u64>")]
pub timeout: std::time::Duration,
#[serde_as(as = "DurationSeconds<u64>")]
pub tracking_interval: std::time::Duration,
#[serde_as(as = "DurationSeconds<u64>")]
pub sources_interval: std::time::Duration,
pub measurement_prefix: String,
pub tracking_measurement: String,
pub sources_measurement: String,
@@ -56,9 +61,9 @@ impl Default for ChronyConfig {
fn default() -> Self {
ChronyConfig {
enabled: false,
timeout: 5,
tracking_interval: 60,
sources_interval: 300,
timeout: std::time::Duration::from_secs(5),
tracking_interval: std::time::Duration::from_secs(60),
sources_interval: std::time::Duration::from_secs(300),
measurement_prefix: "chrony.".into(),
tracking_measurement: "tracking".into(),
sources_measurement: "sources".into(),
@@ -88,10 +93,12 @@ pub struct HwmonSensorConfig {
pub sensor: String,
}
#[serde_as]
#[derive(Serialize, Deserialize, Clone)]
pub struct HwmonConfig {
pub enabled: bool,
pub interval: u64,
#[serde_as(as = "DurationSeconds<u64>")]
pub interval: std::time::Duration,
pub measurement: String,
pub sensors: Map<String, HwmonSensorConfig>,
}
@@ -100,17 +107,19 @@ impl Default for HwmonConfig {
fn default() -> Self {
HwmonConfig {
enabled: false,
interval: 60,
interval: std::time::Duration::from_secs(60),
measurement: "hwmon".into(),
sensors: map! {},
}
}
}
#[serde_as]
#[derive(Serialize, Deserialize, Clone, Debug)]
pub struct GpsdConfig {
pub enabled: bool,
pub interval: u64,
#[serde_as(as = "DurationSeconds<u64>")]
pub interval: std::time::Duration,
pub host: String,
}
@@ -118,19 +127,23 @@ impl Default for GpsdConfig {
fn default() -> Self {
GpsdConfig {
enabled: false,
interval: 60,
interval: std::time::Duration::from_secs(60),
host: "localhost:2947".into(),
}
}
}
#[serde_as]
#[derive(Serialize, Deserialize, Clone, Debug)]
pub struct Prs10Config {
pub enabled: bool,
pub port: String,
pub baud: u32,
#[serde_as(as = "DurationSeconds<u64>")]
pub timeout: std::time::Duration,
#[serde_as(as = "DurationSeconds<u64>")]
pub status_interval: std::time::Duration,
#[serde_as(as = "DurationSeconds<u64>")]
pub stats_interval: std::time::Duration,
}
@@ -217,12 +230,15 @@ pub struct SourceReport {
pub details: Arc<dyn SourceReportDetails>,
}
#[serde_as]
#[derive(Serialize, Deserialize, Clone)]
pub struct UCCMConfig {
pub enabled: bool,
pub port: String,
pub baud: u32,
#[serde_as(as = "DurationSeconds<u64>")]
pub status_interval: std::time::Duration,
#[serde_as(as = "DurationSeconds<u64>")]
pub timeout: std::time::Duration,
pub measurement: String,
}

View File

@@ -162,7 +162,7 @@ impl ChronyClient {
.expect("Unable to parse host:port:");
let client_options = ClientOptions {
n_tries: 3,
timeout: Duration::from_secs(config.sources.chrony.timeout),
timeout: config.sources.chrony.timeout,
};
ChronyClient {
server,
@@ -298,12 +298,8 @@ impl ChimemonSource for ChronyClient {
async fn run(self, chan: ChimemonSourceChannel) {
info!("Chrony task started");
let mut t_interval = tokio::time::interval(Duration::from_secs(
self.config.sources.chrony.tracking_interval,
));
let mut s_interval = tokio::time::interval(Duration::from_secs(
self.config.sources.chrony.sources_interval,
));
let mut t_interval = tokio::time::interval(self.config.sources.chrony.tracking_interval);
let mut s_interval = tokio::time::interval(self.config.sources.chrony.sources_interval);
let t_future = async {
let lchan = chan.clone();

View File

@@ -166,7 +166,7 @@ impl ChimemonSource for GpsdSource {
async fn run(mut self, mut chan: ChimemonSourceChannel) {
info!("gpsd task started");
self.conn.conn().await.unwrap();
let mut ticker = interval(Duration::from_secs(self.config.sources.gpsd.interval));
let mut ticker = interval(self.config.sources.gpsd.interval);
let mut params = WatchParams::default();
params.json = Some(true);

View File

@@ -113,8 +113,7 @@ impl HwmonSource {
impl ChimemonSource for HwmonSource {
async fn run(self, chan: ChimemonSourceChannel) {
info!("hwmon task started");
let mut interval =
tokio::time::interval(Duration::from_secs(self.config.sources.hwmon.interval));
let mut interval = tokio::time::interval(self.config.sources.hwmon.interval);
loop {
interval.tick().await;
let mut values = Vec::new();