refactor metric tags & sources config
This commit is contained in:
@@ -2,10 +2,6 @@ use std::any::type_name;
|
||||
use std::str::FromStr;
|
||||
use std::sync::Arc;
|
||||
|
||||
use crate::{
|
||||
ChimemonMessage, ChimemonSource, ChimemonSourceChannel, Prs10Config, SourceMetric,
|
||||
SourceReport, SourceReportDetails, SourceStatus,
|
||||
};
|
||||
use async_trait::async_trait;
|
||||
use bitflags::bitflags;
|
||||
use itertools::Itertools;
|
||||
@@ -13,10 +9,14 @@ use tokio::io::{AsyncBufReadExt, AsyncWriteExt, BufReader, ReadHalf, WriteHalf};
|
||||
use tokio::select;
|
||||
use tokio::sync::OnceCell;
|
||||
use tokio::time::{interval, timeout};
|
||||
use tokio_serial;
|
||||
use tokio_serial::{SerialPort, SerialStream};
|
||||
use tracing::{debug, debug_span, error, info, instrument, warn};
|
||||
|
||||
use crate::{
|
||||
ChimemonMessage, ChimemonSource, ChimemonSourceChannel, MetricTags, Prs10Config, SourceMetric,
|
||||
SourceReport, SourceReportDetails, SourceStatus,
|
||||
};
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Prs10Info {
|
||||
pub model: String,
|
||||
@@ -54,7 +54,7 @@ bitflags! {
|
||||
}
|
||||
|
||||
impl Prs10PowerLampFlags {
|
||||
pub fn get_metrics(&self, no_tags: Arc<Vec<(String, String)>>) -> Vec<SourceMetric> {
|
||||
pub fn get_metrics(&self, tags: Arc<MetricTags>) -> Vec<SourceMetric> {
|
||||
// Define the mapping statically
|
||||
const FLAG_LABELS: [(&Prs10PowerLampFlags, &str); 8] = [
|
||||
(&Prs10PowerLampFlags::ELEC_VOLTAGE_LOW, "elec_voltage_low"),
|
||||
@@ -72,7 +72,7 @@ impl Prs10PowerLampFlags {
|
||||
.iter()
|
||||
.map(|(flag, label)| {
|
||||
// We track whether each flag is set (true) or not (false)
|
||||
SourceMetric::new_bool(*label, self.contains(**flag), no_tags.clone())
|
||||
SourceMetric::new_bool(*label, self.contains(**flag), tags.clone())
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
@@ -180,17 +180,17 @@ impl SourceReportDetails for Prs10Status {
|
||||
}
|
||||
|
||||
fn to_metrics(&self) -> Vec<SourceMetric> {
|
||||
let no_tags = Arc::new(vec![]);
|
||||
let tags = Arc::new(vec![]);
|
||||
vec![
|
||||
SourceMetric::new_int(
|
||||
"volt_lamp_flags",
|
||||
self.volt_lamp_flags.bits() as i64,
|
||||
no_tags.clone(),
|
||||
tags.clone(),
|
||||
),
|
||||
SourceMetric::new_int("rf_flags", self.rf_flags.bits() as i64, no_tags.clone()),
|
||||
SourceMetric::new_int("temp_flags", self.temp_flags.bits() as i64, no_tags.clone()),
|
||||
SourceMetric::new_int("fll_flags", self.fll_flags.bits() as i64, no_tags.clone()),
|
||||
SourceMetric::new_int("pps_flags", self.pps_flags.bits() as i64, no_tags.clone()),
|
||||
SourceMetric::new_int("rf_flags", self.rf_flags.bits() as i64, tags.clone()),
|
||||
SourceMetric::new_int("temp_flags", self.temp_flags.bits() as i64, tags.clone()),
|
||||
SourceMetric::new_int("fll_flags", self.fll_flags.bits() as i64, tags.clone()),
|
||||
SourceMetric::new_int("pps_flags", self.pps_flags.bits() as i64, tags.clone()),
|
||||
// system flags are kind of useless because we can't guarantee they get upstreamed and will only appear once since they are 'event flags'
|
||||
]
|
||||
}
|
||||
@@ -254,104 +254,69 @@ impl SourceReportDetails for Prs10Stats {
|
||||
true
|
||||
}
|
||||
fn to_metrics(&self) -> Vec<SourceMetric> {
|
||||
let no_tags = Arc::new(vec![]);
|
||||
let tags = Arc::new(vec![]);
|
||||
vec![
|
||||
// Integer Metrics
|
||||
SourceMetric::new_int("ocxo_efc", self.ocxo_efc as i64, no_tags.clone()),
|
||||
SourceMetric::new_int("ocxo_efc", self.ocxo_efc as i64, tags.clone()),
|
||||
// Float Metrics
|
||||
SourceMetric::new_float(
|
||||
"error_signal_volts",
|
||||
self.error_signal_volts,
|
||||
no_tags.clone(),
|
||||
),
|
||||
SourceMetric::new_float("error_signal_volts", self.error_signal_volts, tags.clone()),
|
||||
SourceMetric::new_float(
|
||||
"detect_signal_volts",
|
||||
self.detect_signal_volts,
|
||||
no_tags.clone(),
|
||||
tags.clone(),
|
||||
),
|
||||
SourceMetric::new_float("heat_volts", self.heat_volts, no_tags.clone()),
|
||||
SourceMetric::new_float("elec_volts", self.elec_volts, no_tags.clone()),
|
||||
SourceMetric::new_float("heat_volts", self.heat_volts, tags.clone()),
|
||||
SourceMetric::new_float("elec_volts", self.elec_volts, tags.clone()),
|
||||
SourceMetric::new_float(
|
||||
"lamp_fet_drain_volts",
|
||||
self.lamp_fet_drain_volts,
|
||||
no_tags.clone(),
|
||||
tags.clone(),
|
||||
),
|
||||
SourceMetric::new_float(
|
||||
"lamp_fet_gate_volts",
|
||||
self.lamp_fet_gate_volts,
|
||||
no_tags.clone(),
|
||||
tags.clone(),
|
||||
),
|
||||
SourceMetric::new_float("ocxo_heat_volts", self.ocxo_heat_volts, no_tags.clone()),
|
||||
SourceMetric::new_float("cell_heat_volts", self.cell_heat_volts, no_tags.clone()),
|
||||
SourceMetric::new_float("lamp_heat_volts", self.lamp_heat_volts, no_tags.clone()),
|
||||
SourceMetric::new_float("rb_photo", self.rb_photo, no_tags.clone()),
|
||||
SourceMetric::new_float("rb_photo_iv", self.rb_photo_iv, no_tags.clone()),
|
||||
SourceMetric::new_float("case_temp", self.case_temp, no_tags.clone()),
|
||||
SourceMetric::new_float("ocxo_therm", self.ocxo_therm, no_tags.clone()),
|
||||
SourceMetric::new_float("cell_therm", self.cell_therm, no_tags.clone()),
|
||||
SourceMetric::new_float("lamp_therm", self.lamp_therm, no_tags.clone()),
|
||||
SourceMetric::new_float("ext_cal_volts", self.ext_cal_volts, no_tags.clone()),
|
||||
SourceMetric::new_float("analog_gnd_volts", self.analog_gnd_volts, no_tags.clone()),
|
||||
SourceMetric::new_float("ocxo_heat_volts", self.ocxo_heat_volts, tags.clone()),
|
||||
SourceMetric::new_float("cell_heat_volts", self.cell_heat_volts, tags.clone()),
|
||||
SourceMetric::new_float("lamp_heat_volts", self.lamp_heat_volts, tags.clone()),
|
||||
SourceMetric::new_float("rb_photo", self.rb_photo, tags.clone()),
|
||||
SourceMetric::new_float("rb_photo_iv", self.rb_photo_iv, tags.clone()),
|
||||
SourceMetric::new_float("case_temp", self.case_temp, tags.clone()),
|
||||
SourceMetric::new_float("ocxo_therm", self.ocxo_therm, tags.clone()),
|
||||
SourceMetric::new_float("cell_therm", self.cell_therm, tags.clone()),
|
||||
SourceMetric::new_float("lamp_therm", self.lamp_therm, tags.clone()),
|
||||
SourceMetric::new_float("ext_cal_volts", self.ext_cal_volts, tags.clone()),
|
||||
SourceMetric::new_float("analog_gnd_volts", self.analog_gnd_volts, tags.clone()),
|
||||
SourceMetric::new_float(
|
||||
"if_vco_varactor_volts",
|
||||
self.if_vco_varactor_volts,
|
||||
no_tags.clone(),
|
||||
tags.clone(),
|
||||
),
|
||||
SourceMetric::new_float(
|
||||
"op_vco_varactor_volts",
|
||||
self.op_vco_varactor_volts,
|
||||
no_tags.clone(),
|
||||
tags.clone(),
|
||||
),
|
||||
SourceMetric::new_float(
|
||||
"mul_amp_gain_volts",
|
||||
self.mul_amp_gain_volts,
|
||||
no_tags.clone(),
|
||||
),
|
||||
SourceMetric::new_float("rf_lock_volts", self.rf_lock_volts, no_tags.clone()),
|
||||
SourceMetric::new_float("mul_amp_gain_volts", self.mul_amp_gain_volts, tags.clone()),
|
||||
SourceMetric::new_float("rf_lock_volts", self.rf_lock_volts, tags.clone()),
|
||||
// U16 Metrics (optional, but can be treated as integers)
|
||||
SourceMetric::new_int(
|
||||
"freq_offset_ppt",
|
||||
self.freq_offset_ppt as i64,
|
||||
no_tags.clone(),
|
||||
),
|
||||
SourceMetric::new_int("mag_efc", self.mag_efc as i64, no_tags.clone()),
|
||||
SourceMetric::new_int("freq_offset_ppt", self.freq_offset_ppt as i64, tags.clone()),
|
||||
SourceMetric::new_int("mag_efc", self.mag_efc as i64, tags.clone()),
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Prs10Monitor {
|
||||
name: String,
|
||||
config: Prs10Config,
|
||||
rx: ReadHalf<SerialStream>,
|
||||
tx: WriteHalf<SerialStream>,
|
||||
info: OnceCell<Prs10Info>,
|
||||
config: Prs10Config,
|
||||
}
|
||||
|
||||
impl Prs10Monitor {
|
||||
pub fn new(config: Prs10Config) -> Self {
|
||||
let builder = tokio_serial::new(&config.port, config.baud)
|
||||
.timeout(config.timeout)
|
||||
.data_bits(tokio_serial::DataBits::Eight)
|
||||
.parity(tokio_serial::Parity::None)
|
||||
.stop_bits(tokio_serial::StopBits::One)
|
||||
.flow_control(tokio_serial::FlowControl::None);
|
||||
let mut port = SerialStream::open(&builder).expect("Must be able to open serial port");
|
||||
port.set_exclusive(true).expect("Can't lock serial port");
|
||||
info!(
|
||||
"Opened serial port {}@{}",
|
||||
port.name().unwrap(),
|
||||
port.baud_rate().unwrap()
|
||||
);
|
||||
let (rx, tx) = tokio::io::split(port);
|
||||
|
||||
Self {
|
||||
rx,
|
||||
tx,
|
||||
config,
|
||||
info: OnceCell::new(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn info(&self) -> &Prs10Info {
|
||||
self.info.get().expect("info() used before run()")
|
||||
}
|
||||
@@ -450,7 +415,7 @@ impl Prs10Monitor {
|
||||
async fn status_poll(&mut self) -> Result<ChimemonMessage, Box<dyn std::error::Error>> {
|
||||
let status = self.get_status().await?;
|
||||
Ok(ChimemonMessage::SourceReport(SourceReport {
|
||||
name: "prs10".into(),
|
||||
name: self.name.clone(),
|
||||
status: if status.is_healthy() {
|
||||
SourceStatus::Healthy
|
||||
} else {
|
||||
@@ -480,7 +445,7 @@ impl Prs10Monitor {
|
||||
drop(stats_guard);
|
||||
|
||||
Ok(ChimemonMessage::SourceReport(SourceReport {
|
||||
name: "prs10".into(),
|
||||
name: self.name.clone(),
|
||||
status: SourceStatus::Unknown,
|
||||
details: Arc::new(Prs10Stats {
|
||||
ocxo_efc,
|
||||
@@ -514,10 +479,35 @@ impl Prs10Monitor {
|
||||
|
||||
#[async_trait]
|
||||
impl ChimemonSource for Prs10Monitor {
|
||||
type Config = Prs10Config;
|
||||
fn new(name: &str, config: Self::Config) -> Self {
|
||||
let builder = tokio_serial::new(&config.port, config.baud)
|
||||
.timeout(config.timeout)
|
||||
.data_bits(tokio_serial::DataBits::Eight)
|
||||
.parity(tokio_serial::Parity::None)
|
||||
.stop_bits(tokio_serial::StopBits::One)
|
||||
.flow_control(tokio_serial::FlowControl::None);
|
||||
let mut port = SerialStream::open(&builder).expect("Must be able to open serial port");
|
||||
port.set_exclusive(true).expect("Can't lock serial port");
|
||||
info!(
|
||||
"Opened serial port {}@{}",
|
||||
port.name().unwrap(),
|
||||
port.baud_rate().unwrap()
|
||||
);
|
||||
let (rx, tx) = tokio::io::split(port);
|
||||
|
||||
Self {
|
||||
name: name.to_owned(),
|
||||
config,
|
||||
rx,
|
||||
tx,
|
||||
info: OnceCell::new(),
|
||||
}
|
||||
}
|
||||
async fn run(mut self, chan: ChimemonSourceChannel) {
|
||||
info!("PRS10 task starting");
|
||||
if let Err(e) = self.set_info().await {
|
||||
warn!("Error starting PRS10: {e:?}");
|
||||
error!("Error starting PRS10: {e:?}");
|
||||
return;
|
||||
}
|
||||
info!(
|
||||
|
||||
Reference in New Issue
Block a user