Skip to main content

relay_filter/
common.rs

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