use std::collections::HashMap;
use serde::Serialize;
#[derive(Debug, Clone, Serialize)]
#[non_exhaustive]
pub struct Event {
pub name: String,
pub tool: String,
pub tool_version: String,
pub machine_id: String,
pub timestamp_utc: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub args: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub err_msg: Option<String>,
pub attrs: HashMap<String, String>,
}
impl Event {
#[must_use]
pub fn with_timestamp(
name: impl Into<String>,
tool: impl Into<String>,
tool_version: impl Into<String>,
machine_id: impl Into<String>,
timestamp_utc: impl Into<String>,
) -> Self {
Self {
name: name.into(),
tool: tool.into(),
tool_version: tool_version.into(),
machine_id: machine_id.into(),
timestamp_utc: timestamp_utc.into(),
args: None,
err_msg: None,
attrs: HashMap::new(),
}
}
#[must_use]
pub fn now(
name: impl Into<String>,
tool: impl Into<String>,
tool_version: impl Into<String>,
machine_id: impl Into<String>,
) -> Self {
let ts = time::OffsetDateTime::now_utc()
.format(&time::format_description::well_known::Rfc3339)
.unwrap_or_else(|_| "1970-01-01T00:00:00Z".to_string());
Self::with_timestamp(name, tool, tool_version, machine_id, ts)
}
#[must_use]
pub fn with_attr(mut self, key: impl Into<String>, value: impl Into<String>) -> Self {
self.attrs.insert(key.into(), value.into());
self
}
#[must_use]
pub fn with_args(mut self, args: impl Into<String>) -> Self {
self.args = Some(args.into());
self
}
#[must_use]
pub fn with_err_msg(mut self, msg: impl Into<String>) -> Self {
self.err_msg = Some(msg.into());
self
}
#[must_use]
pub fn redacted(&self) -> Self {
let mut clone = self.clone();
if let Some(raw) = &clone.args {
clone.args = Some(rtb_redact::string(raw).into_owned());
}
if let Some(raw) = &clone.err_msg {
clone.err_msg = Some(rtb_redact::string(raw).into_owned());
}
clone
}
}
#[must_use]
pub const fn severity_of(event: &Event) -> &'static str {
if event.err_msg.is_some() {
"ERROR"
} else {
"INFO"
}
}