use chrono::{DateTime, FixedOffset};
use serde::{Deserialize, Serialize};
use serde_json::{json, Value as JsonValue};
mod boolean;
mod counter;
mod custom_distribution;
mod datetime;
mod event;
mod experiment;
mod labeled;
mod memory_distribution;
mod memory_unit;
mod ping;
mod quantity;
mod string;
mod string_list;
mod time_unit;
mod timespan;
mod timing_distribution;
mod uuid;
use crate::histogram::{Functional, Histogram, PrecomputedExponential, PrecomputedLinear};
use crate::util::get_iso_time_string;
use crate::CommonMetricData;
use crate::Glean;
pub use self::boolean::BooleanMetric;
pub use self::counter::CounterMetric;
pub use self::datetime::DatetimeMetric;
pub use self::event::EventMetric;
pub(crate) use self::experiment::ExperimentMetric;
pub use crate::histogram::HistogramType;
pub use self::custom_distribution::CustomDistributionMetric;
#[cfg(test)]
pub(crate) use self::experiment::RecordedExperimentData;
pub use self::labeled::{
combine_base_identifier_and_label, dynamic_label, strip_label, LabeledMetric,
};
pub use self::memory_distribution::MemoryDistributionMetric;
pub use self::memory_unit::MemoryUnit;
pub use self::ping::PingType;
pub use self::quantity::QuantityMetric;
pub use self::string::StringMetric;
pub use self::string_list::StringListMetric;
pub use self::time_unit::TimeUnit;
pub use self::timespan::TimespanMetric;
pub use self::timing_distribution::TimerId;
pub use self::timing_distribution::TimingDistributionMetric;
pub use self::uuid::UuidMetric;
#[derive(Serialize, Deserialize, Clone, Debug)]
pub enum Metric {
Boolean(bool),
Counter(i32),
CustomDistributionExponential(Histogram<PrecomputedExponential>),
CustomDistributionLinear(Histogram<PrecomputedLinear>),
Datetime(DateTime<FixedOffset>, TimeUnit),
Experiment(experiment::RecordedExperimentData),
Quantity(i64),
String(String),
StringList(Vec<String>),
Uuid(String),
Timespan(std::time::Duration, TimeUnit),
TimingDistribution(Histogram<Functional>),
MemoryDistribution(Histogram<Functional>),
}
pub trait MetricType {
fn meta(&self) -> &CommonMetricData;
fn meta_mut(&mut self) -> &mut CommonMetricData;
fn should_record(&self, glean: &Glean) -> bool {
glean.is_upload_enabled() && self.meta().should_record()
}
}
impl Metric {
pub fn ping_section(&self) -> &'static str {
match self {
Metric::Boolean(_) => "boolean",
Metric::Counter(_) => "counter",
Metric::CustomDistributionExponential(_) => "custom_distribution",
Metric::CustomDistributionLinear(_) => "custom_distribution",
Metric::Datetime(_, _) => "datetime",
Metric::Experiment(_) => panic!("Experiments should not be serialized through this"),
Metric::Quantity(_) => "quantity",
Metric::String(_) => "string",
Metric::StringList(_) => "string_list",
Metric::Timespan(..) => "timespan",
Metric::TimingDistribution(_) => "timing_distribution",
Metric::Uuid(_) => "uuid",
Metric::MemoryDistribution(_) => "memory_distribution",
}
}
pub fn as_json(&self) -> JsonValue {
match self {
Metric::Boolean(b) => json!(b),
Metric::Counter(c) => json!(c),
Metric::CustomDistributionExponential(hist) => {
json!(custom_distribution::snapshot(hist))
}
Metric::CustomDistributionLinear(hist) => json!(custom_distribution::snapshot(hist)),
Metric::Datetime(d, time_unit) => json!(get_iso_time_string(*d, *time_unit)),
Metric::Experiment(e) => json!(e),
Metric::Quantity(q) => json!(q),
Metric::String(s) => json!(s),
Metric::StringList(v) => json!(v),
Metric::Timespan(time, time_unit) => {
json!({"value": time_unit.duration_convert(*time), "time_unit": time_unit})
}
Metric::TimingDistribution(hist) => json!(timing_distribution::snapshot(hist)),
Metric::Uuid(s) => json!(s),
Metric::MemoryDistribution(hist) => json!(memory_distribution::snapshot(hist)),
}
}
}