1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106
use std::borrow::Cow;
use std::fmt;
use serde::Serialize;
/// Identifies which filter dropped an event for which reason.
///
/// Ported from Sentry's same-named "enum". The enum variants are fed into outcomes in kebap-case
/// (e.g. "browser-extensions")
#[derive(Debug, Clone, Eq, PartialEq, Serialize, Hash)]
pub enum FilterStatKey {
/// Filtered by ip address.
IpAddress,
/// Filtered by release name (version).
ReleaseVersion,
/// Filtered by error message.
ErrorMessage,
/// Filtered by browser extension.
BrowserExtensions,
/// Filtered by legacy browser version.
LegacyBrowsers,
/// Filtered due to localhost restriction.
Localhost,
/// Filtered as known web crawler.
WebCrawlers,
/// Filtered due to invalid CSP policy.
InvalidCsp,
/// Filtered due to the fact that it was a call to a filtered transaction
FilteredTransactions,
/// Filtered due to name being denied.
DeniedName,
/// Filtered due to the namespace being disabled.
DisabledNamespace,
/// Filtered due to a generic filter.
GenericFilter(String),
}
// An event grouped to a removed group.
//
// Not returned by any filters implemented in Rust.
// DiscardedHash,
// Invalid CORS header.
//
// NOTE: Although cors is in the Sentry's FilterStatKey enum it is used for
// Invalid outcomes and therefore should logically belong to OutcomeInvalidReason
// that is why it was commented here and moved to OutcomeInvalidReason enum
// Cors,
impl FilterStatKey {
/// Returns the string identifier of the filter stat key.
pub fn name(self) -> Cow<'static, str> {
Cow::Borrowed(match self {
FilterStatKey::IpAddress => "ip-address",
FilterStatKey::ReleaseVersion => "release-version",
FilterStatKey::ErrorMessage => "error-message",
FilterStatKey::BrowserExtensions => "browser-extensions",
FilterStatKey::LegacyBrowsers => "legacy-browsers",
FilterStatKey::Localhost => "localhost",
FilterStatKey::WebCrawlers => "web-crawlers",
FilterStatKey::InvalidCsp => "invalid-csp",
FilterStatKey::FilteredTransactions => "filtered-transaction",
FilterStatKey::DeniedName => "denied-name",
FilterStatKey::DisabledNamespace => "disabled-namespace",
FilterStatKey::GenericFilter(filter_identifier) => {
return Cow::Owned(filter_identifier);
}
})
}
}
impl fmt::Display for FilterStatKey {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}", self.clone().name())
}
}
impl<'a> TryFrom<&'a str> for FilterStatKey {
type Error = &'a str;
fn try_from(value: &'a str) -> Result<Self, Self::Error> {
Ok(match value {
"ip-address" => FilterStatKey::IpAddress,
"release-version" => FilterStatKey::ReleaseVersion,
"error-message" => FilterStatKey::ErrorMessage,
"browser-extensions" => FilterStatKey::BrowserExtensions,
"legacy-browsers" => FilterStatKey::LegacyBrowsers,
"localhost" => FilterStatKey::Localhost,
"web-crawlers" => FilterStatKey::WebCrawlers,
"invalid-csp" => FilterStatKey::InvalidCsp,
"filtered-transaction" => FilterStatKey::FilteredTransactions,
other => FilterStatKey::GenericFilter(other.to_string()),
})
}
}