66from sentry_dynamic_sampling_lib .settings import (
77 DEFAULT_IGNORED_PATH ,
88 DEFAULT_IGNORED_TASK ,
9+ DEFAULT_IGNORED_USER_AGENT ,
910 DEFAULT_SAMPLE_RATE ,
1011)
1112from sentry_dynamic_sampling_lib .utils import synchronized
@@ -18,6 +19,7 @@ def __init__(self) -> None:
1819 self ._lock = RLock ()
1920 self ._sample_rate = DEFAULT_SAMPLE_RATE
2021 self ._ignored_paths = DEFAULT_IGNORED_PATH
22+ self ._ignored_user_agents = tuple (DEFAULT_IGNORED_USER_AGENT )
2123 self ._ignored_tasks = DEFAULT_IGNORED_TASK
2224
2325 @property
@@ -40,6 +42,16 @@ def ignored_paths(self):
4042 def ignored_paths (self , new_ignored_paths ):
4143 self ._ignored_paths = set (new_ignored_paths )
4244
45+ @property
46+ @synchronized
47+ def ignored_user_agents (self ):
48+ return self ._ignored_user_agents
49+
50+ @ignored_user_agents .setter
51+ @synchronized
52+ def ignored_user_agents (self , new_ignored_user_agents ):
53+ self ._ignored_user_agents = set (new_ignored_user_agents )
54+
4355 @property
4456 @synchronized
4557 def ignored_tasks (self ):
@@ -55,6 +67,7 @@ def update(self, data):
5567 self ._sample_rate = data ["active_sample_rate" ]
5668 self ._ignored_paths = set (data ["wsgi_ignore_path" ])
5769 self ._ignored_tasks = set (data ["celery_ignore_task" ])
70+ self ._ignored_user_agents = tuple (data .get ("wsgi_ignore_user_agent" , []))
5871
5972
6073class MetricType (Enum ):
@@ -66,8 +79,8 @@ class Metric:
6679 def __init__ (self ) -> None :
6780 self ._lock = RLock ()
6881 self ._metrics = {
69- MetricType .WSGI : {"activated" : False , "data" : Counter ()},
70- MetricType .CELERY : {"activated" : False , "data" : Counter ()},
82+ MetricType .WSGI : {"activated" : False , "data" : { "path" : Counter (), "user_agent" : Counter ()} },
83+ MetricType .CELERY : {"activated" : False , "data" : { "task" : Counter ()} },
7184 }
7285
7386 def set_mode (self , _type , mode ):
@@ -80,13 +93,19 @@ def get_mode(self, _type):
8093 def count_path (self , path ):
8194 metric = self ._metrics [MetricType .WSGI ]
8295 if metric ["activated" ]:
83- metric ["data" ][path ] += 1
96+ metric ["data" ]["path" ][path ] += 1
97+
98+ @synchronized
99+ def count_user_agent (self , user_agent ):
100+ metric = self ._metrics [MetricType .WSGI ]
101+ if metric ["activated" ]:
102+ metric ["data" ]["user_agent" ][user_agent ] += 1
84103
85104 @synchronized
86105 def count_task (self , path ):
87106 metric = self ._metrics [MetricType .CELERY ]
88107 if metric ["activated" ]:
89- metric ["data" ][path ] += 1
108+ metric ["data" ]["task" ][ path ] += 1
90109
91110 def __iter__ (self ):
92111 """
@@ -101,12 +120,16 @@ def __iter__(self):
101120 LOGGER .debug ("Metric %s disabled" , metric_type .value )
102121 continue
103122 with self ._lock :
104- # check im metric is empty
105- if len (metric ["data" ]) == 0 :
106- LOGGER .debug ("Metric %s is empty" , metric_type .value )
123+ data = {}
124+ for name , counter in metric ["data" ].items ():
125+ # check if metric is empty
126+ if len (counter ) == 0 :
127+ LOGGER .debug ("Metric %s:%s is empty" , metric_type .value , name )
128+ continue
129+ data [name ] = dict (counter .most_common (10 ))
130+ metric ["data" ][name ] = Counter ()
131+ if not data :
107132 continue
108- data = metric ["data" ]
109- metric ["data" ] = Counter ()
110133
111134 # yield outside of the lock to not block write while callee execute
112135 yield metric_type , data
0 commit comments