Skip to content

Commit

Permalink
Allow the user to configure the range of DogStatsD metrics
Browse files Browse the repository at this point in the history
This commit introduces a configuration option to allow the user to define the
range of values that appear in DogStatsD metrics. This range applies to all
metric kinds. The distribution is changed from Standard -- "numerically uniform"
-- to actually Uniform. We do not allow users to configure the distribution.

REF SMP-694

Signed-off-by: Brian L. Troutwine <[email protected]>
  • Loading branch information
blt committed Sep 11, 2023
1 parent 9d604db commit b00ec3c
Show file tree
Hide file tree
Showing 4 changed files with 69 additions and 11 deletions.
6 changes: 6 additions & 0 deletions lading/src/block.rs
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,8 @@ impl Cache {
multivalue_count_maximum,
kind_weights,
metric_weights,
value_minimum,
value_maximum,
}) => {
let context_range = *contexts_minimum..*contexts_maximum;
let tags_per_msg_range = *tags_per_msg_minimum..*tags_per_msg_maximum;
Expand All @@ -173,6 +175,7 @@ impl Cache {
*multivalue_pack_probability,
*kind_weights,
*metric_weights,
*value_minimum..*value_maximum,
&mut rng,
);

Expand Down Expand Up @@ -286,6 +289,8 @@ fn stream_inner(
multivalue_count_maximum,
kind_weights,
metric_weights,
value_minimum,
value_maximum,
}) => {
let context_range = *contexts_minimum..*contexts_maximum;
let tags_per_msg_range = *tags_per_msg_minimum..*tags_per_msg_maximum;
Expand All @@ -304,6 +309,7 @@ fn stream_inner(
*multivalue_pack_probability,
*kind_weights,
*metric_weights,
*value_minimum..*value_maximum,
&mut rng,
);

Expand Down
22 changes: 22 additions & 0 deletions lading_payload/src/dogstatsd.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,14 @@ fn contexts_maximum() -> u16 {
10_000
}

fn value_minimum() -> f64 {
f64::MIN
}

fn value_maximum() -> f64 {
f64::MAX
}

// https://docs.datadoghq.com/developers/guide/what-best-practices-are-recommended-for-naming-metrics-and-tags/#rules-and-best-practices-for-naming-metrics
fn name_length_minimum() -> u16 {
1
Expand Down Expand Up @@ -184,9 +192,18 @@ pub struct Config {
/// payload.
#[serde(default)]
pub kind_weights: KindWeights,

/// Defines the relative probability of each kind of DogStatsD metric.
#[serde(default)]
pub metric_weights: MetricWeights,

/// The minimum value to appear in metrics.
#[serde(default = "value_minimum")]
pub value_minimum: f64,

/// The maximum value to appear in metrics.
#[serde(default = "value_maximum")]
pub value_maximum: f64,
}

fn choose_or_not_ref<'a, R, T>(mut rng: &mut R, pool: &'a [T]) -> Option<&'a T>
Expand Down Expand Up @@ -272,6 +289,7 @@ impl MemberGenerator {
multivalue_pack_probability: f32,
kind_weights: KindWeights,
metric_weights: MetricWeights,
num_value_range: Range<f64>,
mut rng: &mut R,
) -> Self
where
Expand Down Expand Up @@ -343,6 +361,7 @@ impl MemberGenerator {
small_strings,
tagsets.clone(),
pool.as_ref(),
num_value_range,
&mut rng,
);

Expand Down Expand Up @@ -425,6 +444,7 @@ impl DogStatsD {
multivalue_pack_probability(),
KindWeights::default(),
MetricWeights::default(),
value_minimum()..value_maximum(),
rng,
)
}
Expand Down Expand Up @@ -454,6 +474,7 @@ impl DogStatsD {
multivalue_pack_probability: f32,
kind_weights: KindWeights,
metric_weights: MetricWeights,
num_value_range: Range<f64>,
rng: &mut R,
) -> Self
where
Expand All @@ -469,6 +490,7 @@ impl DogStatsD {
multivalue_pack_probability,
kind_weights,
metric_weights,
num_value_range,
rng,
);

Expand Down
38 changes: 31 additions & 7 deletions lading_payload/src/dogstatsd/common.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
use std::fmt;
use std::{fmt, ops::Range};

use rand::{distributions::Standard, prelude::Distribution, Rng};
use rand::{
distributions::{Standard, Uniform},
prelude::Distribution,
Rng,
};

use crate::Generator;

pub(crate) mod tags;

Expand All @@ -10,14 +16,32 @@ pub(crate) enum NumValue {
Int(i64),
}

impl Distribution<NumValue> for Standard {
fn sample<R>(&self, rng: &mut R) -> NumValue
#[derive(Clone, Debug)]
pub(crate) struct NumValueGenerator {
float_distr: Uniform<f64>,
int_distr: Uniform<i64>,
}

impl NumValueGenerator {
#[allow(clippy::cast_possible_truncation)]
pub(crate) fn new(range: Range<f64>) -> Self {
Self {
float_distr: Uniform::new(range.start, range.end),
int_distr: Uniform::new(range.start as i64, range.end as i64),
}
}
}

impl<'a> Generator<'a> for NumValueGenerator {
type Output = NumValue;

fn generate<R>(&'a self, rng: &mut R) -> Self::Output
where
R: Rng + ?Sized,
R: rand::Rng + ?Sized,
{
match rng.gen_range(0..=1) {
0 => NumValue::Float(rng.gen()),
1 => NumValue::Int(rng.gen()),
0 => NumValue::Float(self.float_distr.sample(rng)),
1 => NumValue::Int(self.int_distr.sample(rng)),
_ => unreachable!(),
}
}
Expand Down
14 changes: 10 additions & 4 deletions lading_payload/src/dogstatsd/metric.rs
Original file line number Diff line number Diff line change
@@ -1,15 +1,18 @@
use std::{fmt, ops::Range};

use rand::{
distributions::{OpenClosed01, Standard, WeightedIndex},
distributions::{OpenClosed01, WeightedIndex},
prelude::{Distribution, SliceRandom},
Rng,
};

use crate::{common::strings, dogstatsd::metric::template::Template, Generator};
use tracing::debug;

use super::{choose_or_not_ref, common};
use super::{
choose_or_not_ref,
common::{self, NumValueGenerator},
};

mod template;

Expand All @@ -19,6 +22,7 @@ pub(crate) struct MetricGenerator {
pub(crate) templates: Vec<template::Template>,
pub(crate) multivalue_count_range: Range<u16>,
pub(crate) multivalue_pack_probability: f32,
pub(crate) num_value_generator: NumValueGenerator,
}

impl MetricGenerator {
Expand All @@ -32,6 +36,7 @@ impl MetricGenerator {
container_ids: Vec<String>,
tagsets: common::tags::Tagsets,
str_pool: &strings::Pool,
num_value_range: Range<f64>,
mut rng: &mut R,
) -> Self
where
Expand Down Expand Up @@ -65,6 +70,7 @@ impl MetricGenerator {
templates,
multivalue_count_range,
multivalue_pack_probability,
num_value_generator: NumValueGenerator::new(num_value_range),
}
}
}
Expand All @@ -88,14 +94,14 @@ impl<'a> Generator<'a> for MetricGenerator {
let sample_rate = rng.gen();

let mut values = Vec::with_capacity(self.multivalue_count_range.end as usize);
let value: common::NumValue = Standard.sample(&mut rng);
let value: common::NumValue = self.num_value_generator.generate(&mut rng);
values.push(value);

let prob: f32 = OpenClosed01.sample(&mut rng);
if prob < self.multivalue_pack_probability {
let num_desired_values = rng.gen_range(self.multivalue_count_range.clone());
for _ in 1..num_desired_values {
values.push(Standard.sample(&mut rng));
values.push(self.num_value_generator.generate(&mut rng));
}
}

Expand Down

0 comments on commit b00ec3c

Please sign in to comment.