11//! This module contains the trait for items that can be filtered by Inbound Filters, plus
22//! the implementation for [`Event`].
3+ use std:: sync:: LazyLock ;
4+
35use relay_conventions:: attributes:: {
46 BROWSER__NAME , BROWSER__VERSION , CLIENT__ADDRESS , SENTRY__RELEASE , SENTRY__SEGMENT__NAME ,
57 URL__FULL , USER_AGENT__ORIGINAL ,
68} ;
9+ use relay_conventions:: interpolate:: http__request__header__key;
710use url:: Url ;
811
912use relay_event_schema:: protocol:: {
@@ -196,26 +199,6 @@ impl Filterable for Span {
196199 }
197200}
198201
199- impl Filterable for SpanV2 {
200- fn release ( & self ) -> Option < & str > {
201- self . attributes
202- . value ( ) ?
203- . get_value ( SENTRY__RELEASE ) ?
204- . as_str ( )
205- }
206-
207- fn transaction ( & self ) -> Option < & str > {
208- self . attributes
209- . value ( ) ?
210- . get_value ( SENTRY__SEGMENT__NAME ) ?
211- . as_str ( )
212- }
213-
214- fn user_agent ( & self ) -> UserAgent < ' _ > {
215- user_agent_from_attributes ( & self . attributes )
216- }
217- }
218-
219202impl Filterable for SessionUpdate {
220203 fn ip_addr ( & self ) -> Option < & str > {
221204 self . attributes
@@ -256,32 +239,51 @@ impl Filterable for SessionAggregates {
256239 }
257240}
258241
259- impl Filterable for OurLog {
260- fn release ( & self ) -> Option < & str > {
261- self . attributes
262- . value ( ) ?
263- . get_value ( SENTRY__RELEASE ) ?
264- . as_str ( )
265- }
242+ macro_rules! impl_for_attributes {
243+ ( $ty: ty) => {
244+ impl Filterable for $ty {
245+ fn ip_addr( & self ) -> Option <& str > {
246+ self . attributes
247+ . value( ) ?
248+ . get_value( CLIENT__ADDRESS ) ?
249+ . as_str( )
250+ }
266251
267- fn user_agent ( & self ) -> UserAgent < ' _ > {
268- user_agent_from_attributes ( & self . attributes )
269- }
270- }
252+ fn release( & self ) -> Option <& str > {
253+ self . attributes
254+ . value( ) ?
255+ . get_value( SENTRY__RELEASE ) ?
256+ . as_str( )
257+ }
271258
272- impl Filterable for TraceMetric {
273- fn release ( & self ) -> Option < & str > {
274- self . attributes
275- . value ( ) ?
276- . get_value ( SENTRY__RELEASE ) ?
277- . as_str ( )
278- }
259+ fn transaction( & self ) -> Option <& str > {
260+ self . attributes
261+ . value( ) ?
262+ . get_value( SENTRY__SEGMENT__NAME ) ?
263+ . as_str( )
264+ }
279265
280- fn user_agent ( & self ) -> UserAgent < ' _ > {
281- user_agent_from_attributes ( & self . attributes )
282- }
266+ fn url( & self ) -> Option <Url > {
267+ let url = self . attributes. value( ) ?. get_value( URL__FULL ) ?. as_str( ) ?;
268+ Url :: parse( url) . ok( )
269+ }
270+
271+ fn user_agent( & self ) -> UserAgent <' _> {
272+ user_agent_from_attributes( & self . attributes)
273+ }
274+
275+ fn header( & self , header_name: & str ) -> Option <& str > {
276+ let key = http__request__header__key( header_name) ;
277+ self . attributes. value( ) ?. get_value( & key) ?. as_str( )
278+ }
279+ }
280+ } ;
283281}
284282
283+ impl_for_attributes ! ( SpanV2 ) ;
284+ impl_for_attributes ! ( OurLog ) ;
285+ impl_for_attributes ! ( TraceMetric ) ;
286+
285287fn user_agent_from_attributes ( attributes : & relay_protocol:: Annotated < Attributes > ) -> UserAgent < ' _ > {
286288 let parsed = ( || {
287289 let attributes = attributes. value ( ) ?;
@@ -298,10 +300,20 @@ fn user_agent_from_attributes(attributes: &relay_protocol::Annotated<Attributes>
298300 } )
299301 } ) ( ) ;
300302
301- let raw = attributes
303+ static HTTP_USER_AGENT : LazyLock < String > =
304+ LazyLock :: new ( || http__request__header__key ( "user-agent" ) ) ;
305+
306+ let ua_original = attributes
302307 . value ( )
303308 . and_then ( |attr| attr. get_value ( USER_AGENT__ORIGINAL ) )
304309 . and_then ( |ua| ua. as_str ( ) ) ;
305310
311+ let ua_header = attributes
312+ . value ( )
313+ . and_then ( |attr| attr. get_value ( & * HTTP_USER_AGENT ) )
314+ . and_then ( |ua| ua. as_str ( ) ) ;
315+
316+ let raw = ua_original. or ( ua_header) ;
317+
306318 UserAgent { raw, parsed }
307319}
0 commit comments