harness/payload/dogstatsd.rs
1//! `DogStatsD` payload generation.
2
3// Here's the basic idea.
4//
5// Dogstatsd is three message types:
6//
7// * metric
8// * event
9// * service check
10//
11// # Metrics
12//
13// <NAME>:<VALUE>|<TYPE>|@<SAMPLE_RATE>|#<TAG>,<TAG>...|c:<CONTAINER>|T<TS>|e:<EXT>|card:<CARD>
14//
15// Required: <NAME>:<VALUE>|<TYPE>.
16//
17// * <NAME> := [^:|\n]+
18// * <VALUE> := <NUMBER>(:<NUMBER>)* ':'-packed multi-value, non-set
19// | [^|\n]+ raw string, set type
20// * <NUMBER> := [+-]?(\d+\.?\d*|\.\d+)([eE][+-]?\d+)? | [+-]?(inf|infinity|nan)
21// * <TYPE> := c|g|ms|h|s|d count gauge timer histogram set distribution
22// * <SAMPLE_RATE> := @<NUMBER>
23// * <TAG> := [^,|\n]+ conventionally <KEY>:<VALUE>, the ':' is not required
24// * <CONTAINER> := c:[^|\n]+ e.g. ci-<id>, in-<inode>
25// * <TS> := T\d+ unix seconds
26// * <EXT> := e:[^|\n]+ e.g. it-,cn-,pu-
27// * <CARD> := card:[^|\n]+ recognized: none|low|orchestrator|high
28//
29// # Events
30//
31// _e{<TITLE_LEN>,<TEXT_LEN>}:<TITLE>|<TEXT>|d:<TS>|h:<HOST>|k:<AGGKEY>|p:<PRIO>|s:<SRC>|t:<ALERT>|#<TAGS>
32//
33// Required: _e{<TITLE_LEN>,<TEXT_LEN>}:<TITLE>|<TEXT>. c: / e: / card: are valid here too.
34//
35// * <TITLE_LEN>,
36// <TEXT_LEN> := \d+ byte length of TITLE / TEXT
37// * <TITLE>,
38// <TEXT> := [^\n]{LEN} length-delimited, so '|' and ':' are allowed; '\\n' -> newline
39// * <TS> := d:\d+ unix seconds
40// * <HOST> := h:[^|\n]+
41// * <AGGKEY> := k:[^|\n]+
42// * <PRIO> := p:[^|\n]+ recognized: normal|low (else default)
43// * <SRC> := s:[^|\n]+
44// * <ALERT> := t:[^|\n]+ recognized: error|warning|info|success (else default)
45// * <TAGS> := #<TAG>(,<TAG>)*
46//
47// # Service checks
48//
49// _sc|<NAME>|<STATUS>|d:<TS>|h:<HOST>|#<TAG>,<TAG>...|m:<MESSAGE>
50//
51// Required: _sc|<NAME>|<STATUS>. c: / e: / card: are valid here too.
52//
53// * <NAME> := [^|\n]+
54// * <STATUS> := [0-3] OK warning critical unknown
55// * <TS> := d:\d+ unix seconds
56// * <HOST> := h:[^|\n]+
57// * <TAGS> := #<TAG>(,<TAG>)*
58// * <MESSAGE> := m:[^|\n]+
59
60use antithesis_sdk::random::random_choice;
61use rand::Rng;
62
63mod common;
64mod events;
65mod metrics;
66mod service_checks;
67
68pub use common::{sample_vibe, Vibe};
69
70/// The three `DogStatsD` message types.
71#[derive(Clone, Copy)]
72enum Message {
73 Metric,
74 Event,
75 ServiceCheck,
76}
77
78/// Write one `DogStatsD` message of a random type to `buf` at the given vibe.
79pub fn send<R: Rng + ?Sized>(rng: &mut R, buf: &mut Vec<u8>, vibe: Vibe) {
80 buf.clear();
81 match random_choice(&[Message::Metric, Message::Event, Message::ServiceCheck]) {
82 Some(Message::Event) => events::write(rng, buf, vibe),
83 Some(Message::ServiceCheck) => service_checks::write(rng, buf, vibe),
84 _ => metrics::write(rng, buf, vibe),
85 }
86}