|
22 | 22 | from instana.options import StandardOptions |
23 | 23 | from instana.util import to_json |
24 | 24 | from instana.util.runtime import get_py_source, log_runtime_env_info |
25 | | -from instana.util.span_utils import get_operation_specifiers |
| 25 | +from instana.util.span_utils import matches_rule |
26 | 26 | from instana.version import VERSION |
27 | 27 |
|
28 | 28 | if TYPE_CHECKING: |
@@ -357,51 +357,61 @@ def report_spans(self, payload: Dict[str, Any]) -> Optional[Response]: |
357 | 357 |
|
358 | 358 | def filter_spans(self, spans: List[Dict[str, Any]]) -> List[Dict[str, Any]]: |
359 | 359 | """ |
360 | | - Filters given span list using ignore-endpoint variable and returns the list of filtered spans. |
| 360 | + Filters span list using new hierarchical filtering rules. |
361 | 361 | """ |
362 | 362 | filtered_spans = [] |
363 | | - endpoint = "" |
| 363 | + |
364 | 364 | for span in spans: |
365 | | - if (hasattr(span, "n") or hasattr(span, "name")) and hasattr(span, "data"): |
366 | | - service = span.n |
367 | | - operation_specifier_key, service_specifier_key = ( |
368 | | - get_operation_specifiers(service) |
369 | | - ) |
370 | | - if service == "kafka": |
371 | | - endpoint = span.data[service][service_specifier_key] |
372 | | - method = span.data[service][operation_specifier_key] |
373 | | - if isinstance(method, str) and self.__is_endpoint_ignored( |
374 | | - service, method, endpoint |
375 | | - ): |
376 | | - continue |
377 | | - else: |
378 | | - filtered_spans.append(span) |
379 | | - else: |
| 365 | + if not (hasattr(span, "n") or hasattr(span, "name")) or not hasattr( |
| 366 | + span, "data" |
| 367 | + ): |
380 | 368 | filtered_spans.append(span) |
| 369 | + continue |
| 370 | + |
| 371 | + # Set the service name |
| 372 | + service_name = getattr(span, "n", getattr(span, "name", "")) |
| 373 | + |
| 374 | + # Set span attributes for filtering |
| 375 | + attributes_to_check = { |
| 376 | + "type": service_name, |
| 377 | + "kind": "entry" |
| 378 | + if span.k == 1 |
| 379 | + else "exit" |
| 380 | + if span.k == 2 |
| 381 | + else "intermediate", |
| 382 | + } |
| 383 | + |
| 384 | + # Add operation specifiers to the attributes |
| 385 | + if service_name in span.data: |
| 386 | + service_data = span.data[service_name] |
| 387 | + for key, value in service_data.items(): |
| 388 | + attributes_to_check[f"{service_name}.{key}"] = value |
| 389 | + attributes_to_check[key] = value |
| 390 | + |
| 391 | + # Check if the span need to be ignored |
| 392 | + if self.__is_endpoint_ignored(attributes_to_check): |
| 393 | + continue |
| 394 | + |
| 395 | + filtered_spans.append(span) |
| 396 | + |
381 | 397 | return filtered_spans |
382 | 398 |
|
383 | | - def __is_endpoint_ignored( |
384 | | - self, |
385 | | - service: str, |
386 | | - method: str = "", |
387 | | - endpoint: str = "", |
388 | | - ) -> bool: |
389 | | - """Check if the given service and endpoint combination should be ignored.""" |
390 | | - service = service.lower() |
391 | | - method = method.lower() |
392 | | - endpoint = endpoint.lower() |
393 | | - filter_rules = [ |
394 | | - f"{service}.{method}", # service.method |
395 | | - f"{service}.*", # service.* |
396 | | - ] |
397 | | - |
398 | | - if service == "kafka" and endpoint: |
399 | | - filter_rules += [ |
400 | | - f"{service}.{method}.{endpoint}", # service.method.endpoint |
401 | | - f"{service}.*.{endpoint}", # service.*.endpoint |
402 | | - f"{service}.{method}.*", # service.method.* |
403 | | - ] |
404 | | - return any(rule in self.options.ignore_endpoints for rule in filter_rules) |
| 399 | + def __is_endpoint_ignored(self, span_attributes: dict) -> bool: |
| 400 | + filters = self.options.ignore_endpoints |
| 401 | + if not filters: |
| 402 | + return False |
| 403 | + |
| 404 | + # Check include rules |
| 405 | + for rule in filters.get("include", []): |
| 406 | + if matches_rule(rule.get("attributes", []), span_attributes): |
| 407 | + return False |
| 408 | + |
| 409 | + # Check exclude rules |
| 410 | + for rule in filters.get("exclude", []): |
| 411 | + if matches_rule(rule.get("attributes", []), span_attributes): |
| 412 | + return True |
| 413 | + |
| 414 | + return False |
405 | 415 |
|
406 | 416 | def handle_agent_tasks(self, task: Dict[str, Any]) -> None: |
407 | 417 | """ |
|
0 commit comments