4242}
4343
4444
45- def parse_service_pair (pair : str ) -> List [str ]:
45+ def parse_filter_rules_string (
46+ params : str ,
47+ intermediate : Dict [str , Any ],
48+ policy : str ,
49+ name : str ,
50+ ) -> Dict [str , List [str ]]:
51+ """
52+ Parses a string to prepare filtered endpoint rules.
53+
54+ @param params: String format with rules separated by '|':
55+ - "key;values;match_type|key;values;match_type"
56+ - Example: "http.target;/health;strict|kafka.service;topic1,topic2;strict"
57+ - match_type is optional and defaults to "strict"
58+ @param intermediate: Dictionary to store parsed rules
59+ @param policy: Policy type ("exclude" or "include")
60+ @param name: Name of the filter rule
61+ @return: Updated intermediate dictionary with parsed attribute rules
4662 """
47- Parses a pair string to prepare a list of ignored endpoints.
48-
49- @param pair: String format:
50- - "service1:method1,method2" or "service1:method1" or "service1"
51- @return: List of strings in format ["service1.method1", "service1.method2", "service2.*"]
52- """
53- pair_list = []
54- if ":" in pair :
55- service , methods = pair .split (":" , 1 )
56- service = service .strip ()
57- method_list = [ep .strip () for ep in methods .split ("," ) if ep .strip ()]
63+ try :
64+ # Rule format: key;values;match_type|key;values;match_type
65+ rules = params .split ("|" )
66+ for rule in rules :
67+ rule_parts = rule .split (";" )
68+ if len (rule_parts ) < 2 :
69+ continue
5870
59- for method in method_list :
60- pair_list . append ( f" { service } . { method } " )
61- else :
62- pair_list . append ( f" { pair } .*" )
63- return pair_list
71+ key = rule_parts [ 0 ]. strip ()
72+ values_str = rule_parts [ 1 ]
73+ match_type = (
74+ rule_parts [ 2 ]. strip (). lower () if len ( rule_parts ) > 2 else "strict"
75+ )
6476
77+ # Split values by comma (simple split, assuming no commas in values or user handles escaping if needed?)
78+ # Spec says "values": Mandatory - List of Strings.
79+ # Env var examples: "http.target;/health" -> values=["/health"]
80+ # "kafka.service;topic1,topic2;strict" -> values=["topic1", "topic2"]
81+ values = [v .strip () for v in values_str .split ("," ) if v .strip ()]
6582
66- def parse_filtered_endpoints_string (params : Union [str , os .PathLike ]) -> List [str ]:
67- """
68- Parses a string to prepare a list of ignored endpoints.
83+ attr_data = {"key" : key , "values" : values , "match_type" : match_type }
84+ intermediate [policy ][name ]["attributes" ].append (attr_data )
6985
70- @param params: String format:
71- - "service1:method1,method2;service2:method3" or "service1;service2"
72- @return: List of strings in format ["service1.method1", "service1.method2", "service2.*"]
73- """
74- span_filters = []
75- if params :
76- service_pairs = params .lower ().split (";" )
77-
78- for pair in service_pairs :
79- if pair .strip ():
80- span_filters += parse_service_pair (pair )
81- return span_filters
86+ return intermediate
87+ except Exception as e :
88+ logger .error (f"Failed to parse filter params: { e } " )
89+ return {}
8290
8391
84- def parse_filtered_endpoints_dict (filter_dict : Dict [str , Any ]) -> Dict [str , List [Any ]]:
92+ def parse_filter_rules_dict (filter_dict : Dict [str , Any ]) -> Dict [str , List [Any ]]:
8593 """
8694 Parses 'exclude' and 'include' blocks from the filter dict.
8795
@@ -132,37 +140,36 @@ def parse_filtered_endpoints_dict(filter_dict: Dict[str, Any]) -> Dict[str, List
132140 return {"exclude" : [], "include" : []}
133141
134142
135- def parse_filtered_endpoints (
136- params : Union [ Dict [str , Any ], str ],
137- ) -> Union [ List [ str ], Dict [str , List [Any ] ]]:
143+ def parse_filter_rules (
144+ params : Dict [str , Any ],
145+ ) -> Dict [str , List [Any ]]:
138146 """
139- Parses input to prepare a list for ignored endpoints.
147+ Parses input to prepare filtered endpoints.
140148
141- @param params: Can be either:
142- - String: "service1:method1,method2;service2:method3" or "service1;service2"
143- - Dict: {"exclude": [{"name": "foo", "attributes": ...}], "include": []}
144- @return: List of strings in format ["service1.method1", "service1.method2", "service2.*"]
149+ @param params: Dict with structure:
150+ {"exclude": [{"name": "foo", "attributes": ...}], "include": [{"name": "foo", "attributes": ...}]}
151+ @return: Dict with structure {"exclude": [...], "include": [...]}
145152 """
146153 try :
147- if isinstance (params , str ):
148- return parse_filtered_endpoints_string (params )
149- elif isinstance (params , dict ):
150- return parse_filtered_endpoints_dict (params )
151- else :
152- return []
154+ return parse_filter_rules_dict (params )
153155 except Exception as e :
154- logger .debug ("Error parsing ignored endpoints: %s" , str (e ))
155- return []
156+ logger .debug ("Error parsing filtered endpoints: %s" , str (e ))
157+ return {}
156158
157159
158- def parse_filtered_endpoints_from_yaml (
160+ def parse_filter_rules_yaml (
159161 file_path : str ,
160- ) -> Union [ List [ str ], Dict [str , List [Any ] ]]:
162+ ) -> Dict [str , List [Any ]]:
161163 """
162- Parses configuration yaml file and prepares a list of ignored endpoints .
164+ Parses configuration YAML file and prepares filtered endpoint rules .
163165
164- @param file_path: Path of the file as a string
165- @return: List of strings in format ["service1.method1", "service1.method2", "service2.*", "kafka.method.topic", "kafka.*.topic", "kafka.method.*"]
166+ @param file_path: Path to the YAML configuration file
167+ @return: Dictionary containing parsed filter rules with structure:
168+ {
169+ "exclude": [{"name": str, "suppression": bool, "attributes": [{"key": str, "values": list, "match_type": str}]}],
170+ "include": [{"name": str, "suppression": None, "attributes": [{"key": str, "values": list, "match_type": str}]}]
171+ }
172+ Returns empty dict {} if no filter configuration is found or on error.
166173 """
167174 config_reader = ConfigReader (file_path )
168175 span_filters_dict = None
@@ -172,13 +179,13 @@ def parse_filtered_endpoints_from_yaml(
172179 logger .warning (DEPRECATED_CONFIG_KEY_WARNING )
173180 span_filters_dict = config_reader .data ["com.instana.tracing" ].get ("filter" )
174181 if span_filters_dict :
175- span_filters = parse_filtered_endpoints (span_filters_dict )
182+ span_filters = parse_filter_rules (span_filters_dict )
176183 return span_filters
177184 else :
178185 return {}
179186
180187
181- def parse_span_filter_env_vars () -> Dict [str , List [Any ]]:
188+ def parse_filter_rules_env_vars () -> Dict [str , List [Any ]]:
182189 """
183190 Parses INSTANA_TRACING_FILTER_<POLICY>_<NAME>_ATTRIBUTES environment variables.
184191
@@ -216,27 +223,12 @@ def parse_span_filter_env_vars() -> Dict[str, List[Any]]:
216223 }
217224
218225 if suffix == "ATTRIBUTES" :
219- # Rule format: key;values;match_type|key;values;match_type
220- rules = env_value .split ("|" )
221- for rule in rules :
222- rule_parts = rule .split (";" )
223- if len (rule_parts ) < 2 :
224- continue
225-
226- key = rule_parts [0 ].strip ()
227- values_str = rule_parts [1 ]
228- match_type = (
229- rule_parts [2 ].strip ().lower () if len (rule_parts ) > 2 else "strict"
230- )
231-
232- # Split values by comma (simple split, assuming no commas in values or user handles escaping if needed?)
233- # Spec says "values": Mandatory - List of Strings.
234- # Env var examples: "http.target;/health" -> values=["/health"]
235- # "kafka.service;topic1,topic2;strict" -> values=["topic1", "topic2"]
236- values = [v .strip () for v in values_str .split ("," ) if v .strip ()]
237-
238- attr_data = {"key" : key , "values" : values , "match_type" : match_type }
239- intermediate [policy ][name ]["attributes" ].append (attr_data )
226+ intermediate = parse_filter_rules_string (
227+ env_value ,
228+ intermediate ,
229+ policy ,
230+ name ,
231+ )
240232
241233 elif suffix == "SUPPRESSION" and policy == "exclude" :
242234 intermediate [policy ][name ]["suppression" ] = is_truthy (env_value )
0 commit comments