Initial generalization of source workers

This commit is contained in:
2022-11-01 01:36:14 -07:00
parent 82906adca2
commit ed3cb89325
7 changed files with 452 additions and 164 deletions

View File

@@ -1,4 +1,4 @@
use chrony_candm::reply;
use async_trait::async_trait;
use figment::{
providers::{Format, Serialized, Toml},
util::map,
@@ -8,11 +8,8 @@ use figment::{
use gethostname::gethostname;
use influxdb2::models::DataPoint;
use serde_derive::{Deserialize, Serialize};
use std::time::{SystemTime, UNIX_EPOCH};
use std::{
net::{IpAddr, Ipv4Addr},
path::Path,
};
use std::path::Path;
use tokio::sync::broadcast::*;
#[derive(Serialize, Deserialize, Clone)]
pub struct InfluxConfig {
@@ -40,12 +37,12 @@ impl Default for InfluxConfig {
pub struct ChronyConfig {
pub enabled: bool,
pub timeout: u64,
pub poll_interval: u64,
pub tracking_interval: u64,
pub sources_interval: u64,
pub measurement_prefix: String,
pub tracking_measurement: String,
pub sources_measurement: String,
pub host: IpAddr,
pub port: u16,
pub host: String,
}
impl Default for ChronyConfig {
@@ -53,12 +50,37 @@ impl Default for ChronyConfig {
ChronyConfig {
enabled: false,
timeout: 5,
poll_interval: 60,
tracking_interval: 60,
sources_interval: 300,
measurement_prefix: "chrony.".into(),
tracking_measurement: "tracking".into(),
sources_measurement: "sources".into(),
host: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)),
port: 323,
host: "127.0.0.1:323".into(),
}
}
}
#[derive(Serialize, Deserialize, Clone)]
pub struct HwmonSensorConfig {
pub name: String,
pub sensor: String,
}
#[derive(Serialize, Deserialize, Clone)]
pub struct HwmonConfig {
pub enabled: bool,
pub interval: u64,
pub measurement_prefix: String,
pub sensors: Map<String, HwmonSensorConfig>,
}
impl Default for HwmonConfig {
fn default() -> Self {
HwmonConfig {
enabled: false,
interval: 60,
measurement_prefix: "hwmon.".into(),
sensors: map! {},
}
}
}
@@ -66,6 +88,7 @@ impl Default for ChronyConfig {
#[derive(Serialize, Deserialize, Clone, Default)]
pub struct SourcesConfig {
pub chrony: ChronyConfig,
pub hwmon: HwmonConfig,
}
#[derive(Serialize, Deserialize, Clone, Default)]
@@ -74,70 +97,19 @@ pub struct Config {
pub sources: SourcesConfig,
}
pub fn load_config(filename: &Path) -> Result<Config, Box<dyn std::error::Error>> {
let config = Figment::from(Serialized::defaults(Config::default()))
.merge(Toml::file(filename))
.extract()?;
Ok(config)
pub fn load_config(filename: &Path) -> Figment {
Figment::from(Serialized::defaults(Config::default())).merge(Toml::file(filename))
}
pub fn datapoint_from_tracking(
t: &reply::Tracking,
config: &Config,
) -> Result<DataPoint, Box<dyn std::error::Error>> {
let now = SystemTime::now().duration_since(UNIX_EPOCH)?;
let measurement = config.sources.chrony.measurement_prefix.to_owned()
+ &config.sources.chrony.tracking_measurement;
let mut builder =
DataPoint::builder(&measurement).timestamp(now.as_nanos().try_into().unwrap());
for (key, value) in &config.influxdb.tags {
builder = builder.tag(key, value);
}
pub type ChimemonSourceChannel = Sender<DataPoint>;
pub type ChimemonTargetChannel = Receiver<DataPoint>;
let point = builder
.field("ref_id", t.ref_id as i64)
.field("ref_ip_addr", t.ip_addr.to_string())
.field("stratum", t.stratum as i64)
.field("leap_status", t.leap_status as i64)
.field("current_correction", f64::from(t.current_correction))
.field("last_offset", f64::from(t.last_offset))
.field("rms_offset", f64::from(t.rms_offset))
.field("freq_ppm", f64::from(t.freq_ppm))
.field("resid_freq_ppm", f64::from(t.resid_freq_ppm))
.field("skew_ppm", f64::from(t.skew_ppm))
.field("root_delay", f64::from(t.root_delay))
.field("root_dispersion", f64::from(t.root_dispersion))
.field("last_update_interval", f64::from(t.last_update_interval))
.build()?;
Ok(point)
#[async_trait]
pub trait ChimemonSource {
async fn run(self, chan: ChimemonSourceChannel);
}
pub fn datapoint_from_sourcedata(
d: &reply::SourceData,
config: &Config,
) -> Result<DataPoint, Box<dyn std::error::Error>> {
let now = SystemTime::now().duration_since(UNIX_EPOCH)?;
let measurement = config.sources.chrony.measurement_prefix.to_owned()
+ &config.sources.chrony.sources_measurement;
let mut builder =
DataPoint::builder(&measurement).timestamp(now.as_nanos().try_into().unwrap());
for (key, value) in &config.influxdb.tags {
builder = builder.tag(key, value)
}
builder = builder
.tag("ref_id", d.ip_addr.to_string())
.tag("mode", (d.mode as i64).to_string())
.tag("state", (d.state as i64).to_string())
.field("poll", d.poll as i64)
.field("stratum", d.stratum as i64)
.field("flags", d.flags.bits() as i64)
.field("reachability", d.reachability as i64)
.field("since_sample", d.since_sample as i64)
.field("orig_latest_meas", f64::from(d.orig_latest_meas))
.field("latest_meas", f64::from(d.latest_meas))
.field("latest_meas_err", f64::from(d.latest_meas_err));
let point = builder.build()?;
Ok(point)
#[async_trait]
pub trait ChimemonTarget {
async fn run(self, chan: ChimemonTargetChannel);
}