Skip to main content

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}