Skip to content

Commit

Permalink
more wip: handle late elided metric versions, improve CLI
Browse files Browse the repository at this point in the history
  • Loading branch information
bnaecker committed Jun 6, 2024
1 parent c11f1f6 commit da37ed3
Show file tree
Hide file tree
Showing 3 changed files with 122 additions and 19 deletions.
58 changes: 42 additions & 16 deletions oximeter/impl/src/bin/oximeter-schema.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,17 +29,31 @@ enum Cmd {

/// Print the derived timeseries schema.
Schema {
/// Show the schema for a specified timeseries by name.
///
/// If not provided, all timeseries are printed.
#[arg(short, long)]
timeseries: Option<String>,

/// Show the schema for a specified version.
///
/// If not provided, all versions are shown.
#[arg(short, long)]
version: Option<NonZeroU8>,
},

/// Print the Rust code that would be emitted in the macro format.
Emit {
/// Show the schema for a specified timeseries by name.
///
/// If not provided, all timeseries are printed.
#[arg(short, long)]
timeseries: Option<String>,

/// Show the emitted code for a specified version.
///
/// If not provided, all versions are shown.
#[arg(short, long)]
version: Option<NonZeroU8>,
},
}
Expand All @@ -54,26 +68,38 @@ fn main() -> anyhow::Result<()> {
let def: TimeseriesDefinition = toml::from_str(&contents)?;
println!("{def:#?}");
}
Cmd::Schema { version } => {
Cmd::Schema { timeseries, version } => {
let schema = oximeter_impl::schema::ir::load_schema(&contents)?;
if let Some(ver) = version {
let Some(s) = schema.get(usize::from(ver.get() - 1)) else {
anyhow::bail!(
"Schema file {} does not contain version {}",
args.path.display(),
ver,
);
};
println!("{s:#?}");
} else {
for (version, schema) in schema.into_iter().enumerate() {
println!("Version {}", version + 1);
println!("----------");
println!("{:#?}", schema);
match (timeseries, version) {
(None, None) => {
for each in schema.into_iter() {
println!("{each:#?}");
}
}
(None, Some(version)) => {
for each in
schema.into_iter().filter(|s| s.version == version)
{
println!("{each:#?}");
}
}
(Some(name), None) => {
for each in
schema.into_iter().filter(|s| s.timeseries_name == name)
{
println!("{each:#?}");
}
}
(Some(name), Some(version)) => {
for each in schema.into_iter().filter(|s| {
s.timeseries_name == name && s.version == version
}) {
println!("{each:#?}");
}
}
}
}
Cmd::Emit { version } => todo!(),
Cmd::Emit { .. } => todo!(),
}
Ok(())
}
59 changes: 58 additions & 1 deletion oximeter/impl/src/schema/ir.rs
Original file line number Diff line number Diff line change
Expand Up @@ -234,9 +234,9 @@ pub fn load_schema(
timeseries_name,
field_schema,
datum_type: metric.datum_type,
version: NonZeroU8::new(last_target_version).unwrap(),
/* TODO(ben): Add these fields.
units: metric.units,
version: last_target_version,
authz_scope,
*/
created: Utc::now(),
Expand All @@ -245,6 +245,63 @@ pub fn load_schema(
last_target_version.checked_add(1).expect("version < 256");
}
}

// We also allow omitting later versions of metrics if they are
// unchanged. A target has to specify every version, even if it's the
// same, but the metrics need only specify differents.
//
// Here, look for any target version strictly later than the last metric
// version, and create a corresponding target / metric pair for it.
if let Some(last_metric_fields) = metric.versions.last() {
match last_metric_fields {
MetricFields::Removed { .. } => {}
MetricFields::Added {
added_in: last_metric_version,
fields,
}
| MetricFields::Versioned(VersionedFields {
version: last_metric_version,
fields,
}) => {
let metric_field_names: BTreeSet<_> =
fields.iter().collect();
let next_version = last_metric_version
.get()
.checked_add(1)
.expect("version < 256");
for (version, target_fields) in
target_fields_by_version.range(next_version..)
{
let field_schema = construct_field_schema(
&def.fields,
target_name,
target_fields,
metric_name,
&metric_field_names,
)?;
let _authz_scope = extract_authz_scope(
metric_name,
def.target.authz_scope,
&field_schema,
)?;
let timeseries_name = TimeseriesName::try_from(
format!("{}:{}", target_name, metric_name),
)?;
out.push(TimeseriesSchema {
timeseries_name,
field_schema,
datum_type: metric.datum_type,
version: NonZeroU8::new(*version).unwrap(),
/* TODO(ben): Add these fields.
units: metric.units,
authz_scope,
*/
created: Utc::now(),
});
}
}
}
}
}

Ok(out)
Expand Down
24 changes: 22 additions & 2 deletions oximeter/impl/src/schema/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ use std::collections::btree_map::Entry;
use std::collections::BTreeMap;
use std::collections::BTreeSet;
use std::fmt::Write;
use std::num::NonZeroU8;
use std::path::Path;

/// The name and type information for a field of a timeseries schema.
Expand Down Expand Up @@ -166,9 +167,15 @@ pub struct TimeseriesSchema {
pub timeseries_name: TimeseriesName,
pub field_schema: BTreeSet<FieldSchema>,
pub datum_type: DatumType,
#[serde(default = "default_version")]
pub version: NonZeroU8,
pub created: DateTime<Utc>,
}

pub const fn default_version() -> NonZeroU8 {
unsafe { NonZeroU8::new_unchecked(1) }
}

impl From<&Sample> for TimeseriesSchema {
fn from(sample: &Sample) -> Self {
let timeseries_name = sample.timeseries_name.parse().unwrap();
Expand All @@ -190,7 +197,13 @@ impl From<&Sample> for TimeseriesSchema {
field_schema.insert(schema);
}
let datum_type = sample.measurement.datum_type();
Self { timeseries_name, field_schema, datum_type, created: Utc::now() }
Self {
timeseries_name,
field_schema,
datum_type,
version: default_version(),
created: Utc::now(),
}
}
}

Expand Down Expand Up @@ -222,7 +235,13 @@ impl TimeseriesSchema {
field_schema.insert(schema);
}
let datum_type = metric.datum_type();
Self { timeseries_name, field_schema, datum_type, created: Utc::now() }
Self {
timeseries_name,
field_schema,
datum_type,
version: default_version(),
created: Utc::now(),
}
}

/// Construct a timeseries schema from a sample
Expand Down Expand Up @@ -643,6 +662,7 @@ mod tests {
timeseries_name,
field_schema,
datum_type,
version: default_version(),
created: Utc::now(),
};

Expand Down

0 comments on commit da37ed3

Please sign in to comment.