6
6
from sentry_dynamic_sampling_lib .settings import (
7
7
DEFAULT_IGNORED_PATH ,
8
8
DEFAULT_IGNORED_TASK ,
9
+ DEFAULT_IGNORED_USER_AGENT ,
9
10
DEFAULT_SAMPLE_RATE ,
10
11
)
11
12
from sentry_dynamic_sampling_lib .utils import synchronized
@@ -18,6 +19,7 @@ def __init__(self) -> None:
18
19
self ._lock = RLock ()
19
20
self ._sample_rate = DEFAULT_SAMPLE_RATE
20
21
self ._ignored_paths = DEFAULT_IGNORED_PATH
22
+ self ._ignored_user_agents = tuple (DEFAULT_IGNORED_USER_AGENT )
21
23
self ._ignored_tasks = DEFAULT_IGNORED_TASK
22
24
23
25
@property
@@ -40,6 +42,16 @@ def ignored_paths(self):
40
42
def ignored_paths (self , new_ignored_paths ):
41
43
self ._ignored_paths = set (new_ignored_paths )
42
44
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
+
43
55
@property
44
56
@synchronized
45
57
def ignored_tasks (self ):
@@ -55,6 +67,7 @@ def update(self, data):
55
67
self ._sample_rate = data ["active_sample_rate" ]
56
68
self ._ignored_paths = set (data ["wsgi_ignore_path" ])
57
69
self ._ignored_tasks = set (data ["celery_ignore_task" ])
70
+ self ._ignored_user_agents = tuple (data .get ("wsgi_ignore_user_agent" , []))
58
71
59
72
60
73
class MetricType (Enum ):
@@ -66,8 +79,8 @@ class Metric:
66
79
def __init__ (self ) -> None :
67
80
self ._lock = RLock ()
68
81
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 ()} },
71
84
}
72
85
73
86
def set_mode (self , _type , mode ):
@@ -80,13 +93,19 @@ def get_mode(self, _type):
80
93
def count_path (self , path ):
81
94
metric = self ._metrics [MetricType .WSGI ]
82
95
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
84
103
85
104
@synchronized
86
105
def count_task (self , path ):
87
106
metric = self ._metrics [MetricType .CELERY ]
88
107
if metric ["activated" ]:
89
- metric ["data" ][path ] += 1
108
+ metric ["data" ]["task" ][ path ] += 1
90
109
91
110
def __iter__ (self ):
92
111
"""
@@ -101,12 +120,16 @@ def __iter__(self):
101
120
LOGGER .debug ("Metric %s disabled" , metric_type .value )
102
121
continue
103
122
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 :
107
132
continue
108
- data = metric ["data" ]
109
- metric ["data" ] = Counter ()
110
133
111
134
# yield outside of the lock to not block write while callee execute
112
135
yield metric_type , data
0 commit comments