Introduce the `InvalidOverflow` error

This is used by the timing distribution metric type
whenever a passed sample is bigger than 10 minutes.
This commit is contained in:
Alessio Placitelli 2019-12-12 19:09:24 +01:00
Родитель 6712a8b92b
Коммит f7ffbdd651
3 изменённых файлов: 60 добавлений и 8 удалений

Просмотреть файл

@ -31,6 +31,8 @@ pub enum ErrorType {
InvalidLabel,
/// For when the metric caught an invalid state while recording
InvalidState,
/// For when the value to be recorded overflows the metric-specific upper range
InvalidOverflow,
}
impl ErrorType {
@ -40,6 +42,7 @@ impl ErrorType {
ErrorType::InvalidValue => "invalid_value",
ErrorType::InvalidLabel => "invalid_label",
ErrorType::InvalidState => "invalid_state",
ErrorType::InvalidOverflow => "invalid_overflow",
}
}
}
@ -52,6 +55,7 @@ impl TryFrom<i32> for ErrorType {
0 => Ok(ErrorType::InvalidValue),
1 => Ok(ErrorType::InvalidLabel),
2 => Ok(ErrorType::InvalidState),
4 => Ok(ErrorType::InvalidOverflow),
e => Err(ErrorKind::Lifetime(e).into()),
}
}

Просмотреть файл

@ -171,7 +171,7 @@ impl TimingDistributionMetric {
if duration > MAX_SAMPLE_TIME {
let msg = "Sample is longer than 10 minutes";
record_error(glean, &self.meta, ErrorType::InvalidValue, msg, None);
record_error(glean, &self.meta, ErrorType::InvalidOverflow, msg, None);
duration = MAX_SAMPLE_TIME;
}
@ -226,10 +226,11 @@ impl TimingDistributionMetric {
/// ## Notes
///
/// Discards any negative value in `samples` and report an `ErrorType::InvalidValue`
/// for each of them.
/// for each of them. Reports an `ErrorType::InvalidOverflow` error for samples that
/// are longer than `MAX_SAMPLE_TIME`.
pub fn accumulate_samples_signed(&mut self, glean: &Glean, samples: Vec<i64>) {
let mut num_negative_samples = 0;
let mut num_too_log_samples = 0;
let mut num_too_long_samples = 0;
glean.storage().record_with(glean, &self.meta, |old_value| {
let mut hist = match old_value {
@ -244,7 +245,7 @@ impl TimingDistributionMetric {
let sample = sample as u64;
let mut sample = self.time_unit.as_nanos(sample);
if sample > MAX_SAMPLE_TIME {
num_too_log_samples += 1;
num_too_long_samples += 1;
sample = MAX_SAMPLE_TIME;
}
@ -265,17 +266,17 @@ impl TimingDistributionMetric {
);
}
if num_too_log_samples > 0 {
if num_too_long_samples > 0 {
let msg = format!(
"Accumulated {} samples longer than 10 minutes",
num_too_log_samples
num_too_long_samples
);
record_error(
glean,
&self.meta,
ErrorType::InvalidValue,
ErrorType::InvalidOverflow,
msg,
num_too_log_samples,
num_too_long_samples,
);
}
}

Просмотреть файл

@ -238,6 +238,53 @@ fn the_accumulate_samples_api_correctly_handles_negative_values() {
);
}
#[test]
fn the_accumulate_samples_api_correctly_handles_overflowing_values() {
let (glean, _t) = new_glean();
let mut metric = TimingDistributionMetric::new(
CommonMetricData {
name: "distribution".into(),
category: "telemetry".into(),
send_in_pings: vec!["store1".into()],
disabled: false,
lifetime: Lifetime::Ping,
..Default::default()
},
TimeUnit::Nanosecond,
);
// The MAX_SAMPLE_TIME is the same from `metrics/timing_distribution.rs`.
const MAX_SAMPLE_TIME: u64 = 1000 * 1000 * 1000 * 60 * 10;
let overflowing_val = MAX_SAMPLE_TIME as i64 + 1;
// Accumulate the samples.
metric.accumulate_samples_signed(&glean, [overflowing_val, 1, 2, 3].to_vec());
let val = metric
.test_get_value(&glean, "store1")
.expect("Value should be stored");
// Overflowing values are truncated to MAX_SAMPLE_TIME and recorded.
assert_eq!(val.sum(), MAX_SAMPLE_TIME + 6);
assert_eq!(val.count(), 4);
// We should get a sample in each of the first 3 buckets.
assert_eq!(1, val.values()[&1]);
assert_eq!(1, val.values()[&2]);
assert_eq!(1, val.values()[&3]);
// 1 error should be reported.
assert_eq!(
Ok(1),
test_get_num_recorded_errors(
&glean,
metric.meta(),
ErrorType::InvalidOverflow,
Some("store1")
)
);
}
#[test]
fn large_nanoseconds_values() {
let (glean, _t) = new_glean(None);