saluki_core/data_model/event/eventd/
mod.rs

1//! Events.
2
3use std::{fmt, num::NonZeroU64};
4
5use saluki_context::tags::SharedTagSet;
6use serde::{Serialize, Serializer};
7use stringtheory::MetaString;
8
9/// Value supplied used to specify a low priority event
10pub const PRIORITY_LOW: &str = "low";
11
12/// Value used to specify an error alert.
13pub const ALERT_TYPE_ERROR: &str = "error";
14
15/// Value used to specify a warning alert.
16pub const ALERT_TYPE_WARNING: &str = "warning";
17
18/// Value used to specify a success alert.
19pub const ALERT_TYPE_SUCCESS: &str = "success";
20
21/// Alert type.
22#[derive(Clone, Copy, Debug, PartialEq, Eq)]
23pub enum AlertType {
24    /// Indicates an informational event.
25    Info,
26
27    /// Indicates an error event.
28    Error,
29
30    /// Indicates a warning event.
31    Warning,
32
33    /// Indicates a successful event.
34    Success,
35}
36
37impl fmt::Display for AlertType {
38    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
39        f.write_str(self.as_str())
40    }
41}
42
43impl Serialize for AlertType {
44    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
45    where
46        S: Serializer,
47    {
48        serializer.serialize_str(self.as_str())
49    }
50}
51
52impl AlertType {
53    /// Creates an AlertType from a string.
54    ///
55    /// Defaults to an informational alert.
56    pub fn try_from_string(alert_type: &str) -> Option<Self> {
57        match alert_type {
58            ALERT_TYPE_ERROR => Some(AlertType::Error),
59            ALERT_TYPE_WARNING => Some(AlertType::Warning),
60            ALERT_TYPE_SUCCESS => Some(AlertType::Success),
61            _ => Some(AlertType::Info),
62        }
63    }
64
65    /// Returns the string representation of the alert type.
66    pub const fn as_str(self) -> &'static str {
67        match self {
68            AlertType::Info => "info",
69            AlertType::Error => "error",
70            AlertType::Warning => "warning",
71            AlertType::Success => "success",
72        }
73    }
74}
75
76/// Event priority.
77#[derive(Clone, Copy, Debug, PartialEq, Eq)]
78pub enum Priority {
79    /// The event has normal priority.
80    Normal,
81
82    /// The event has low priority.
83    Low,
84}
85
86impl fmt::Display for Priority {
87    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
88        f.write_str(self.as_str())
89    }
90}
91
92impl Serialize for Priority {
93    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
94    where
95        S: Serializer,
96    {
97        serializer.serialize_str(self.as_str())
98    }
99}
100
101impl Priority {
102    /// Creates an event Priority from a string.
103    ///
104    /// Defaults to  normal priority.
105    pub fn try_from_string(priority: &str) -> Option<Self> {
106        match priority {
107            PRIORITY_LOW => Some(Priority::Low),
108            _ => Some(Priority::Normal),
109        }
110    }
111
112    /// Returns the string representation of the priority.
113    pub const fn as_str(self) -> &'static str {
114        match self {
115            Priority::Normal => "normal",
116            Priority::Low => "low",
117        }
118    }
119}
120
121/// EventD is an object that can be posted to the DataDog event stream.
122#[derive(Clone, Debug, PartialEq, Serialize)]
123pub struct EventD {
124    title: MetaString,
125    text: MetaString,
126    timestamp: Option<NonZeroU64>,
127    #[serde(skip_serializing_if = "MetaString::is_empty")]
128    hostname: MetaString,
129    #[serde(skip_serializing_if = "MetaString::is_empty")]
130    aggregation_key: MetaString,
131    priority: Option<Priority>,
132    #[serde(skip_serializing_if = "MetaString::is_empty")]
133    source_type_name: MetaString,
134    alert_type: Option<AlertType>,
135    tags: SharedTagSet,
136    origin_tags: SharedTagSet,
137}
138
139impl EventD {
140    /// Returns the title of the event.
141    pub fn title(&self) -> &str {
142        &self.title
143    }
144
145    /// Returns the text of the event.
146    pub fn text(&self) -> &str {
147        &self.text
148    }
149
150    /// Returns the host where the event originated from.
151    pub fn hostname(&self) -> Option<&str> {
152        if self.hostname.is_empty() {
153            None
154        } else {
155            Some(&self.hostname)
156        }
157    }
158
159    /// Returns the aggregation key of the event.
160    pub fn aggregation_key(&self) -> Option<&str> {
161        if self.aggregation_key.is_empty() {
162            None
163        } else {
164            Some(&self.aggregation_key)
165        }
166    }
167
168    /// Returns the priority of the event.
169    pub fn priority(&self) -> Option<Priority> {
170        self.priority
171    }
172
173    /// Returns the source type name of the event.
174    pub fn source_type_name(&self) -> Option<&str> {
175        if self.source_type_name.is_empty() {
176            None
177        } else {
178            Some(&self.source_type_name)
179        }
180    }
181
182    /// Returns the alert type of the event.
183    pub fn alert_type(&self) -> Option<AlertType> {
184        self.alert_type
185    }
186
187    /// Returns the timestamp of the event.
188    ///
189    /// This is a Unix timestamp, or the number of seconds since the Unix epoch.
190    pub fn timestamp(&self) -> Option<u64> {
191        self.timestamp.map(|ts| ts.get())
192    }
193
194    /// Returns the tags associated with the event.
195    pub fn tags(&self) -> &SharedTagSet {
196        &self.tags
197    }
198
199    /// Returns the origin tags associated with the event.
200    pub fn origin_tags(&self) -> &SharedTagSet {
201        &self.origin_tags
202    }
203
204    /// Set the timestamp.
205    ///
206    /// Represented as a Unix timestamp, or the number of seconds since the Unix epoch.
207    ///
208    /// This variant is specifically for use in builder-style APIs.
209    pub fn with_timestamp(mut self, timestamp: impl Into<Option<u64>>) -> Self {
210        self.timestamp = timestamp.into().and_then(NonZeroU64::new);
211        self
212    }
213
214    /// Set the timestamp.
215    ///
216    /// Represented as a Unix timestamp, or the number of seconds since the Unix epoch.
217    pub fn set_timestamp(&mut self, timestamp: impl Into<Option<u64>>) {
218        self.timestamp = timestamp.into().and_then(NonZeroU64::new);
219    }
220
221    /// Set the hostname where the event originated from.
222    ///
223    /// This variant is specifically for use in builder-style APIs.
224    pub fn with_hostname(mut self, hostname: impl Into<Option<MetaString>>) -> Self {
225        self.hostname = match hostname.into() {
226            Some(s) => s,
227            None => MetaString::empty(),
228        };
229        self
230    }
231
232    /// Set the hostname where the event originated from.
233    pub fn set_hostname(&mut self, hostname: impl Into<Option<MetaString>>) {
234        self.hostname = match hostname.into() {
235            Some(s) => s,
236            None => MetaString::empty(),
237        };
238    }
239
240    /// Set the aggregation key of the event.
241    ///
242    /// Aggregation key is use to group events together in the event stream.
243    ///
244    /// This variant is specifically for use in builder-style APIs.
245    pub fn with_aggregation_key(mut self, aggregation_key: impl Into<Option<MetaString>>) -> Self {
246        self.aggregation_key = match aggregation_key.into() {
247            Some(s) => s,
248            None => MetaString::empty(),
249        };
250        self
251    }
252
253    /// Set the hostname where the event originated from.
254    ///
255    /// Aggregation key is use to group events together in the event stream.
256    pub fn set_aggregation_key(&mut self, aggregation_key: impl Into<Option<MetaString>>) {
257        self.aggregation_key = match aggregation_key.into() {
258            Some(s) => s,
259            None => MetaString::empty(),
260        };
261    }
262
263    /// Set the priority of the event.
264    ///
265    /// This variant is specifically for use in builder-style APIs.
266    pub fn with_priority(mut self, priority: impl Into<Option<Priority>>) -> Self {
267        self.priority = priority.into();
268        self
269    }
270
271    /// Set the priority of the event.
272    pub fn set_priority(&mut self, priority: impl Into<Option<Priority>>) {
273        self.priority = priority.into();
274    }
275
276    /// Set the source type name of the event.
277    ///
278    /// This variant is specifically for use in builder-style APIs.
279    pub fn with_source_type_name(mut self, source_type_name: impl Into<Option<MetaString>>) -> Self {
280        self.source_type_name = match source_type_name.into() {
281            Some(s) => s,
282            None => MetaString::empty(),
283        };
284        self
285    }
286
287    /// Set the source type name of the event.
288    pub fn set_source_type_name(&mut self, source_type_name: impl Into<Option<MetaString>>) {
289        self.source_type_name = match source_type_name.into() {
290            Some(s) => s,
291            None => MetaString::empty(),
292        };
293    }
294
295    /// Set the alert type of the event.
296    ///
297    /// This variant is specifically for use in builder-style APIs.
298    pub fn with_alert_type(mut self, alert_type: impl Into<Option<AlertType>>) -> Self {
299        self.alert_type = alert_type.into();
300        self
301    }
302
303    /// Set the alert type name of the event.
304    pub fn set_alert_type(&mut self, alert_type: impl Into<Option<AlertType>>) {
305        self.alert_type = alert_type.into();
306    }
307
308    /// Set the tags of the event.
309    ///
310    /// This variant is specifically for use in builder-style APIs.
311    pub fn with_tags(mut self, tags: impl Into<SharedTagSet>) -> Self {
312        self.tags = tags.into();
313        self
314    }
315
316    /// Set the tags of the event.
317    pub fn set_tags(&mut self, tags: impl Into<Option<SharedTagSet>>) {
318        self.tags = tags.into().unwrap_or_default();
319    }
320
321    /// Set the origin tags of the event.
322    ///
323    /// This variant is specifically for use in builder-style APIs.
324    pub fn with_origin_tags(mut self, origin_tags: SharedTagSet) -> Self {
325        self.origin_tags = origin_tags;
326        self
327    }
328
329    /// Creates an `EventD` from the given title and text.
330    ///
331    /// Defaults to an informational alert with normal priority.
332    pub fn new(title: impl Into<MetaString>, text: impl Into<MetaString>) -> Self {
333        Self {
334            title: title.into(),
335            text: text.into(),
336            timestamp: None,
337            hostname: MetaString::empty(),
338            aggregation_key: MetaString::empty(),
339            priority: Some(Priority::Normal),
340            source_type_name: MetaString::empty(),
341            alert_type: Some(AlertType::Info),
342            tags: SharedTagSet::default(),
343            origin_tags: SharedTagSet::default(),
344        }
345    }
346}